diff options
Diffstat (limited to 'drivers/message')
-rw-r--r-- | drivers/message/fusion/mptbase.c | 291 | ||||
-rw-r--r-- | drivers/message/fusion/mptbase.h | 38 | ||||
-rw-r--r-- | drivers/message/fusion/mptctl.c | 38 | ||||
-rw-r--r-- | drivers/message/fusion/mptfc.c | 9 | ||||
-rw-r--r-- | drivers/message/fusion/mptlan.c | 4 | ||||
-rw-r--r-- | drivers/message/fusion/mptsas.c | 278 | ||||
-rw-r--r-- | drivers/message/fusion/mptsas.h | 1 | ||||
-rw-r--r-- | drivers/message/fusion/mptscsih.c | 54 | ||||
-rw-r--r-- | drivers/message/fusion/mptspi.c | 9 | ||||
-rw-r--r-- | drivers/message/i2o/exec-osm.c | 8 | ||||
-rw-r--r-- | drivers/message/i2o/i2o_block.c | 33 | ||||
-rw-r--r-- | drivers/message/i2o/i2o_config.c | 18 | ||||
-rw-r--r-- | drivers/message/i2o/i2o_scsi.c | 3 |
13 files changed, 539 insertions, 245 deletions
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index a6a57011ba6c..c54674c482c7 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #include <linux/module.h> | 50 | #include <linux/module.h> |
51 | #include <linux/errno.h> | 51 | #include <linux/errno.h> |
52 | #include <linux/init.h> | 52 | #include <linux/init.h> |
53 | #include <linux/seq_file.h> | ||
53 | #include <linux/slab.h> | 54 | #include <linux/slab.h> |
54 | #include <linux/types.h> | 55 | #include <linux/types.h> |
55 | #include <linux/pci.h> | 56 | #include <linux/pci.h> |
@@ -115,6 +116,7 @@ MODULE_PARM_DESC(mpt_fwfault_debug, "Enable detection of Firmware fault" | |||
115 | " and halt Firmware on fault - (default=0)"); | 116 | " and halt Firmware on fault - (default=0)"); |
116 | 117 | ||
117 | 118 | ||
119 | static char MptCallbacksName[MPT_MAX_PROTOCOL_DRIVERS][50]; | ||
118 | 120 | ||
119 | #ifdef MFCNT | 121 | #ifdef MFCNT |
120 | static int mfcounter = 0; | 122 | static int mfcounter = 0; |
@@ -199,12 +201,9 @@ static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_valu | |||
199 | static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init); | 201 | static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init); |
200 | 202 | ||
201 | #ifdef CONFIG_PROC_FS | 203 | #ifdef CONFIG_PROC_FS |
202 | static int procmpt_summary_read(char *buf, char **start, off_t offset, | 204 | static const struct file_operations mpt_summary_proc_fops; |
203 | int request, int *eof, void *data); | 205 | static const struct file_operations mpt_version_proc_fops; |
204 | static int procmpt_version_read(char *buf, char **start, off_t offset, | 206 | static const struct file_operations mpt_iocinfo_proc_fops; |
205 | int request, int *eof, void *data); | ||
206 | static int procmpt_iocinfo_read(char *buf, char **start, off_t offset, | ||
207 | int request, int *eof, void *data); | ||
208 | #endif | 207 | #endif |
209 | static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc); | 208 | static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc); |
210 | 209 | ||
@@ -213,7 +212,7 @@ static int ProcessEventNotification(MPT_ADAPTER *ioc, | |||
213 | static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf); | 212 | static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf); |
214 | static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info); | 213 | static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info); |
215 | static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info); | 214 | static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info); |
216 | static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info); | 215 | static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info , u8 cb_idx); |
217 | static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc); | 216 | static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc); |
218 | static void mpt_inactive_raid_list_free(MPT_ADAPTER *ioc); | 217 | static void mpt_inactive_raid_list_free(MPT_ADAPTER *ioc); |
219 | 218 | ||
@@ -490,7 +489,7 @@ mpt_reply(MPT_ADAPTER *ioc, u32 pa) | |||
490 | else if (ioc->bus_type == SPI) | 489 | else if (ioc->bus_type == SPI) |
491 | mpt_spi_log_info(ioc, log_info); | 490 | mpt_spi_log_info(ioc, log_info); |
492 | else if (ioc->bus_type == SAS) | 491 | else if (ioc->bus_type == SAS) |
493 | mpt_sas_log_info(ioc, log_info); | 492 | mpt_sas_log_info(ioc, log_info, cb_idx); |
494 | } | 493 | } |
495 | 494 | ||
496 | if (ioc_stat & MPI_IOCSTATUS_MASK) | 495 | if (ioc_stat & MPI_IOCSTATUS_MASK) |
@@ -644,7 +643,7 @@ mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply) | |||
644 | * considered an error by the caller. | 643 | * considered an error by the caller. |
645 | */ | 644 | */ |
646 | u8 | 645 | u8 |
647 | mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass) | 646 | mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass, char *func_name) |
648 | { | 647 | { |
649 | u8 cb_idx; | 648 | u8 cb_idx; |
650 | last_drv_idx = MPT_MAX_PROTOCOL_DRIVERS; | 649 | last_drv_idx = MPT_MAX_PROTOCOL_DRIVERS; |
@@ -659,6 +658,8 @@ mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass) | |||
659 | MptDriverClass[cb_idx] = dclass; | 658 | MptDriverClass[cb_idx] = dclass; |
660 | MptEvHandlers[cb_idx] = NULL; | 659 | MptEvHandlers[cb_idx] = NULL; |
661 | last_drv_idx = cb_idx; | 660 | last_drv_idx = cb_idx; |
661 | memcpy(MptCallbacksName[cb_idx], func_name, | ||
662 | strlen(func_name) > 50 ? 50 : strlen(func_name)); | ||
662 | break; | 663 | break; |
663 | } | 664 | } |
664 | } | 665 | } |
@@ -1632,6 +1633,7 @@ mpt_mapresources(MPT_ADAPTER *ioc) | |||
1632 | } else { | 1633 | } else { |
1633 | printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n", | 1634 | printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n", |
1634 | ioc->name, pci_name(pdev)); | 1635 | ioc->name, pci_name(pdev)); |
1636 | pci_release_selected_regions(pdev, ioc->bars); | ||
1635 | return r; | 1637 | return r; |
1636 | } | 1638 | } |
1637 | } else { | 1639 | } else { |
@@ -1645,6 +1647,7 @@ mpt_mapresources(MPT_ADAPTER *ioc) | |||
1645 | } else { | 1647 | } else { |
1646 | printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n", | 1648 | printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n", |
1647 | ioc->name, pci_name(pdev)); | 1649 | ioc->name, pci_name(pdev)); |
1650 | pci_release_selected_regions(pdev, ioc->bars); | ||
1648 | return r; | 1651 | return r; |
1649 | } | 1652 | } |
1650 | } | 1653 | } |
@@ -1675,6 +1678,7 @@ mpt_mapresources(MPT_ADAPTER *ioc) | |||
1675 | if (mem == NULL) { | 1678 | if (mem == NULL) { |
1676 | printk(MYIOC_s_ERR_FMT ": ERROR - Unable to map adapter" | 1679 | printk(MYIOC_s_ERR_FMT ": ERROR - Unable to map adapter" |
1677 | " memory!\n", ioc->name); | 1680 | " memory!\n", ioc->name); |
1681 | pci_release_selected_regions(pdev, ioc->bars); | ||
1678 | return -EINVAL; | 1682 | return -EINVAL; |
1679 | } | 1683 | } |
1680 | ioc->memmap = mem; | 1684 | ioc->memmap = mem; |
@@ -1719,7 +1723,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1719 | u8 pcixcmd; | 1723 | u8 pcixcmd; |
1720 | static int mpt_ids = 0; | 1724 | static int mpt_ids = 0; |
1721 | #ifdef CONFIG_PROC_FS | 1725 | #ifdef CONFIG_PROC_FS |
1722 | struct proc_dir_entry *dent, *ent; | 1726 | struct proc_dir_entry *dent; |
1723 | #endif | 1727 | #endif |
1724 | 1728 | ||
1725 | ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC); | 1729 | ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC); |
@@ -1770,7 +1774,6 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1770 | ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */ | 1774 | ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */ |
1771 | ioc->reply_sz = MPT_REPLY_FRAME_SIZE; | 1775 | ioc->reply_sz = MPT_REPLY_FRAME_SIZE; |
1772 | 1776 | ||
1773 | ioc->pcidev = pdev; | ||
1774 | 1777 | ||
1775 | spin_lock_init(&ioc->taskmgmt_lock); | 1778 | spin_lock_init(&ioc->taskmgmt_lock); |
1776 | mutex_init(&ioc->internal_cmds.mutex); | 1779 | mutex_init(&ioc->internal_cmds.mutex); |
@@ -1794,7 +1797,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1794 | ioc->sh = NULL; | 1797 | ioc->sh = NULL; |
1795 | ioc->cached_fw = NULL; | 1798 | ioc->cached_fw = NULL; |
1796 | 1799 | ||
1797 | /* Initilize SCSI Config Data structure | 1800 | /* Initialize SCSI Config Data structure |
1798 | */ | 1801 | */ |
1799 | memset(&ioc->spi_data, 0, sizeof(SpiCfgData)); | 1802 | memset(&ioc->spi_data, 0, sizeof(SpiCfgData)); |
1800 | 1803 | ||
@@ -1913,6 +1916,9 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1913 | ioc->msi_enable = 0; | 1916 | ioc->msi_enable = 0; |
1914 | break; | 1917 | break; |
1915 | } | 1918 | } |
1919 | |||
1920 | ioc->fw_events_off = 1; | ||
1921 | |||
1916 | if (ioc->errata_flag_1064) | 1922 | if (ioc->errata_flag_1064) |
1917 | pci_disable_io_access(pdev); | 1923 | pci_disable_io_access(pdev); |
1918 | 1924 | ||
@@ -1972,16 +1978,8 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1972 | */ | 1978 | */ |
1973 | dent = proc_mkdir(ioc->name, mpt_proc_root_dir); | 1979 | dent = proc_mkdir(ioc->name, mpt_proc_root_dir); |
1974 | if (dent) { | 1980 | if (dent) { |
1975 | ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent); | 1981 | proc_create_data("info", S_IRUGO, dent, &mpt_iocinfo_proc_fops, ioc); |
1976 | if (ent) { | 1982 | proc_create_data("summary", S_IRUGO, dent, &mpt_summary_proc_fops, ioc); |
1977 | ent->read_proc = procmpt_iocinfo_read; | ||
1978 | ent->data = ioc; | ||
1979 | } | ||
1980 | ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent); | ||
1981 | if (ent) { | ||
1982 | ent->read_proc = procmpt_summary_read; | ||
1983 | ent->data = ioc; | ||
1984 | } | ||
1985 | } | 1983 | } |
1986 | #endif | 1984 | #endif |
1987 | 1985 | ||
@@ -2051,7 +2049,6 @@ mpt_detach(struct pci_dev *pdev) | |||
2051 | 2049 | ||
2052 | mpt_adapter_dispose(ioc); | 2050 | mpt_adapter_dispose(ioc); |
2053 | 2051 | ||
2054 | pci_set_drvdata(pdev, NULL); | ||
2055 | } | 2052 | } |
2056 | 2053 | ||
2057 | /************************************************************************** | 2054 | /************************************************************************** |
@@ -2471,7 +2468,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) | |||
2471 | if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) { | 2468 | if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) { |
2472 | 2469 | ||
2473 | /* | 2470 | /* |
2474 | * Initalize link list for inactive raid volumes. | 2471 | * Initialize link list for inactive raid volumes. |
2475 | */ | 2472 | */ |
2476 | mutex_init(&ioc->raid_data.inactive_list_mutex); | 2473 | mutex_init(&ioc->raid_data.inactive_list_mutex); |
2477 | INIT_LIST_HEAD(&ioc->raid_data.inactive_list); | 2474 | INIT_LIST_HEAD(&ioc->raid_data.inactive_list); |
@@ -5062,8 +5059,9 @@ mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode) | |||
5062 | if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) | 5059 | if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) |
5063 | goto out; | 5060 | goto out; |
5064 | if (!timeleft) { | 5061 | if (!timeleft) { |
5065 | printk(KERN_DEBUG "%s: Issuing Reset from %s!!\n", | 5062 | printk(MYIOC_s_WARN_FMT |
5066 | ioc->name, __func__); | 5063 | "Issuing Reset from %s!!, doorbell=0x%08x\n", |
5064 | ioc->name, __func__, mpt_GetIocState(ioc, 0)); | ||
5067 | mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP); | 5065 | mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP); |
5068 | mpt_free_msg_frame(ioc, mf); | 5066 | mpt_free_msg_frame(ioc, mf); |
5069 | } | 5067 | } |
@@ -6454,8 +6452,9 @@ out: | |||
6454 | mutex_unlock(&ioc->mptbase_cmds.mutex); | 6452 | mutex_unlock(&ioc->mptbase_cmds.mutex); |
6455 | if (issue_hard_reset) { | 6453 | if (issue_hard_reset) { |
6456 | issue_hard_reset = 0; | 6454 | issue_hard_reset = 0; |
6457 | printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n", | 6455 | printk(MYIOC_s_WARN_FMT |
6458 | ioc->name, __func__); | 6456 | "Issuing Reset from %s!!, doorbell=0x%08x\n", |
6457 | ioc->name, __func__, mpt_GetIocState(ioc, 0)); | ||
6459 | if (retry_count == 0) { | 6458 | if (retry_count == 0) { |
6460 | if (mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP) != 0) | 6459 | if (mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP) != 0) |
6461 | retry_count++; | 6460 | retry_count++; |
@@ -6537,20 +6536,12 @@ mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) | |||
6537 | static int | 6536 | static int |
6538 | procmpt_create(void) | 6537 | procmpt_create(void) |
6539 | { | 6538 | { |
6540 | struct proc_dir_entry *ent; | ||
6541 | |||
6542 | mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL); | 6539 | mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL); |
6543 | if (mpt_proc_root_dir == NULL) | 6540 | if (mpt_proc_root_dir == NULL) |
6544 | return -ENOTDIR; | 6541 | return -ENOTDIR; |
6545 | 6542 | ||
6546 | ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir); | 6543 | proc_create("summary", S_IRUGO, mpt_proc_root_dir, &mpt_summary_proc_fops); |
6547 | if (ent) | 6544 | proc_create("version", S_IRUGO, mpt_proc_root_dir, &mpt_version_proc_fops); |
6548 | ent->read_proc = procmpt_summary_read; | ||
6549 | |||
6550 | ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir); | ||
6551 | if (ent) | ||
6552 | ent->read_proc = procmpt_version_read; | ||
6553 | |||
6554 | return 0; | 6545 | return 0; |
6555 | } | 6546 | } |
6556 | 6547 | ||
@@ -6570,70 +6561,46 @@ procmpt_destroy(void) | |||
6570 | 6561 | ||
6571 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 6562 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
6572 | /** | 6563 | /** |
6573 | * procmpt_summary_read - Handle read request of a summary file | ||
6574 | * @buf: Pointer to area to write information | ||
6575 | * @start: Pointer to start pointer | ||
6576 | * @offset: Offset to start writing | ||
6577 | * @request: Amount of read data requested | ||
6578 | * @eof: Pointer to EOF integer | ||
6579 | * @data: Pointer | ||
6580 | * | ||
6581 | * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary. | 6564 | * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary. |
6582 | * Returns number of characters written to process performing the read. | ||
6583 | */ | 6565 | */ |
6584 | static int | 6566 | static void seq_mpt_print_ioc_summary(MPT_ADAPTER *ioc, struct seq_file *m, int showlan); |
6585 | procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data) | ||
6586 | { | ||
6587 | MPT_ADAPTER *ioc; | ||
6588 | char *out = buf; | ||
6589 | int len; | ||
6590 | |||
6591 | if (data) { | ||
6592 | int more = 0; | ||
6593 | 6567 | ||
6594 | ioc = data; | 6568 | static int mpt_summary_proc_show(struct seq_file *m, void *v) |
6595 | mpt_print_ioc_summary(ioc, out, &more, 0, 1); | 6569 | { |
6570 | MPT_ADAPTER *ioc = m->private; | ||
6596 | 6571 | ||
6597 | out += more; | 6572 | if (ioc) { |
6573 | seq_mpt_print_ioc_summary(ioc, m, 1); | ||
6598 | } else { | 6574 | } else { |
6599 | list_for_each_entry(ioc, &ioc_list, list) { | 6575 | list_for_each_entry(ioc, &ioc_list, list) { |
6600 | int more = 0; | 6576 | seq_mpt_print_ioc_summary(ioc, m, 1); |
6601 | |||
6602 | mpt_print_ioc_summary(ioc, out, &more, 0, 1); | ||
6603 | |||
6604 | out += more; | ||
6605 | if ((out-buf) >= request) | ||
6606 | break; | ||
6607 | } | 6577 | } |
6608 | } | 6578 | } |
6609 | 6579 | ||
6610 | len = out - buf; | 6580 | return 0; |
6581 | } | ||
6611 | 6582 | ||
6612 | MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len); | 6583 | static int mpt_summary_proc_open(struct inode *inode, struct file *file) |
6584 | { | ||
6585 | return single_open(file, mpt_summary_proc_show, PDE(inode)->data); | ||
6613 | } | 6586 | } |
6614 | 6587 | ||
6615 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 6588 | static const struct file_operations mpt_summary_proc_fops = { |
6616 | /** | 6589 | .owner = THIS_MODULE, |
6617 | * procmpt_version_read - Handle read request from /proc/mpt/version. | 6590 | .open = mpt_summary_proc_open, |
6618 | * @buf: Pointer to area to write information | 6591 | .read = seq_read, |
6619 | * @start: Pointer to start pointer | 6592 | .llseek = seq_lseek, |
6620 | * @offset: Offset to start writing | 6593 | .release = single_release, |
6621 | * @request: Amount of read data requested | 6594 | }; |
6622 | * @eof: Pointer to EOF integer | 6595 | |
6623 | * @data: Pointer | 6596 | static int mpt_version_proc_show(struct seq_file *m, void *v) |
6624 | * | ||
6625 | * Returns number of characters written to process performing the read. | ||
6626 | */ | ||
6627 | static int | ||
6628 | procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data) | ||
6629 | { | 6597 | { |
6630 | u8 cb_idx; | 6598 | u8 cb_idx; |
6631 | int scsi, fc, sas, lan, ctl, targ, dmp; | 6599 | int scsi, fc, sas, lan, ctl, targ, dmp; |
6632 | char *drvname; | 6600 | char *drvname; |
6633 | int len; | ||
6634 | 6601 | ||
6635 | len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON); | 6602 | seq_printf(m, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON); |
6636 | len += sprintf(buf+len, " Fusion MPT base driver\n"); | 6603 | seq_printf(m, " Fusion MPT base driver\n"); |
6637 | 6604 | ||
6638 | scsi = fc = sas = lan = ctl = targ = dmp = 0; | 6605 | scsi = fc = sas = lan = ctl = targ = dmp = 0; |
6639 | for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { | 6606 | for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { |
@@ -6661,98 +6628,97 @@ procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eo | |||
6661 | } | 6628 | } |
6662 | 6629 | ||
6663 | if (drvname) | 6630 | if (drvname) |
6664 | len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname); | 6631 | seq_printf(m, " Fusion MPT %s driver\n", drvname); |
6665 | } | 6632 | } |
6666 | } | 6633 | } |
6667 | 6634 | ||
6668 | MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len); | 6635 | return 0; |
6669 | } | 6636 | } |
6670 | 6637 | ||
6671 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 6638 | static int mpt_version_proc_open(struct inode *inode, struct file *file) |
6672 | /** | ||
6673 | * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info. | ||
6674 | * @buf: Pointer to area to write information | ||
6675 | * @start: Pointer to start pointer | ||
6676 | * @offset: Offset to start writing | ||
6677 | * @request: Amount of read data requested | ||
6678 | * @eof: Pointer to EOF integer | ||
6679 | * @data: Pointer | ||
6680 | * | ||
6681 | * Returns number of characters written to process performing the read. | ||
6682 | */ | ||
6683 | static int | ||
6684 | procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data) | ||
6685 | { | 6639 | { |
6686 | MPT_ADAPTER *ioc = data; | 6640 | return single_open(file, mpt_version_proc_show, NULL); |
6687 | int len; | 6641 | } |
6642 | |||
6643 | static const struct file_operations mpt_version_proc_fops = { | ||
6644 | .owner = THIS_MODULE, | ||
6645 | .open = mpt_version_proc_open, | ||
6646 | .read = seq_read, | ||
6647 | .llseek = seq_lseek, | ||
6648 | .release = single_release, | ||
6649 | }; | ||
6650 | |||
6651 | static int mpt_iocinfo_proc_show(struct seq_file *m, void *v) | ||
6652 | { | ||
6653 | MPT_ADAPTER *ioc = m->private; | ||
6688 | char expVer[32]; | 6654 | char expVer[32]; |
6689 | int sz; | 6655 | int sz; |
6690 | int p; | 6656 | int p; |
6691 | 6657 | ||
6692 | mpt_get_fw_exp_ver(expVer, ioc); | 6658 | mpt_get_fw_exp_ver(expVer, ioc); |
6693 | 6659 | ||
6694 | len = sprintf(buf, "%s:", ioc->name); | 6660 | seq_printf(m, "%s:", ioc->name); |
6695 | if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT) | 6661 | if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT) |
6696 | len += sprintf(buf+len, " (f/w download boot flag set)"); | 6662 | seq_printf(m, " (f/w download boot flag set)"); |
6697 | // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL) | 6663 | // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL) |
6698 | // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!"); | 6664 | // seq_printf(m, " CONFIG_CHECKSUM_FAIL!"); |
6699 | 6665 | ||
6700 | len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n", | 6666 | seq_printf(m, "\n ProductID = 0x%04x (%s)\n", |
6701 | ioc->facts.ProductID, | 6667 | ioc->facts.ProductID, |
6702 | ioc->prod_name); | 6668 | ioc->prod_name); |
6703 | len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer); | 6669 | seq_printf(m, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer); |
6704 | if (ioc->facts.FWImageSize) | 6670 | if (ioc->facts.FWImageSize) |
6705 | len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize); | 6671 | seq_printf(m, " (fw_size=%d)", ioc->facts.FWImageSize); |
6706 | len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion); | 6672 | seq_printf(m, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion); |
6707 | len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit); | 6673 | seq_printf(m, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit); |
6708 | len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState); | 6674 | seq_printf(m, " EventState = 0x%02x\n", ioc->facts.EventState); |
6709 | 6675 | ||
6710 | len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n", | 6676 | seq_printf(m, " CurrentHostMfaHighAddr = 0x%08x\n", |
6711 | ioc->facts.CurrentHostMfaHighAddr); | 6677 | ioc->facts.CurrentHostMfaHighAddr); |
6712 | len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n", | 6678 | seq_printf(m, " CurrentSenseBufferHighAddr = 0x%08x\n", |
6713 | ioc->facts.CurrentSenseBufferHighAddr); | 6679 | ioc->facts.CurrentSenseBufferHighAddr); |
6714 | 6680 | ||
6715 | len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth); | 6681 | seq_printf(m, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth); |
6716 | len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize); | 6682 | seq_printf(m, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize); |
6717 | 6683 | ||
6718 | len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n", | 6684 | seq_printf(m, " RequestFrames @ 0x%p (Dma @ 0x%p)\n", |
6719 | (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma); | 6685 | (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma); |
6720 | /* | 6686 | /* |
6721 | * Rounding UP to nearest 4-kB boundary here... | 6687 | * Rounding UP to nearest 4-kB boundary here... |
6722 | */ | 6688 | */ |
6723 | sz = (ioc->req_sz * ioc->req_depth) + 128; | 6689 | sz = (ioc->req_sz * ioc->req_depth) + 128; |
6724 | sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000; | 6690 | sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000; |
6725 | len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n", | 6691 | seq_printf(m, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n", |
6726 | ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz); | 6692 | ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz); |
6727 | len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n", | 6693 | seq_printf(m, " {MaxReqSz=%d} {MaxReqDepth=%d}\n", |
6728 | 4*ioc->facts.RequestFrameSize, | 6694 | 4*ioc->facts.RequestFrameSize, |
6729 | ioc->facts.GlobalCredits); | 6695 | ioc->facts.GlobalCredits); |
6730 | 6696 | ||
6731 | len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n", | 6697 | seq_printf(m, " Frames @ 0x%p (Dma @ 0x%p)\n", |
6732 | (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma); | 6698 | (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma); |
6733 | sz = (ioc->reply_sz * ioc->reply_depth) + 128; | 6699 | sz = (ioc->reply_sz * ioc->reply_depth) + 128; |
6734 | len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n", | 6700 | seq_printf(m, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n", |
6735 | ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz); | 6701 | ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz); |
6736 | len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n", | 6702 | seq_printf(m, " {MaxRepSz=%d} {MaxRepDepth=%d}\n", |
6737 | ioc->facts.CurReplyFrameSize, | 6703 | ioc->facts.CurReplyFrameSize, |
6738 | ioc->facts.ReplyQueueDepth); | 6704 | ioc->facts.ReplyQueueDepth); |
6739 | 6705 | ||
6740 | len += sprintf(buf+len, " MaxDevices = %d\n", | 6706 | seq_printf(m, " MaxDevices = %d\n", |
6741 | (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices); | 6707 | (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices); |
6742 | len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses); | 6708 | seq_printf(m, " MaxBuses = %d\n", ioc->facts.MaxBuses); |
6743 | 6709 | ||
6744 | /* per-port info */ | 6710 | /* per-port info */ |
6745 | for (p=0; p < ioc->facts.NumberOfPorts; p++) { | 6711 | for (p=0; p < ioc->facts.NumberOfPorts; p++) { |
6746 | len += sprintf(buf+len, " PortNumber = %d (of %d)\n", | 6712 | seq_printf(m, " PortNumber = %d (of %d)\n", |
6747 | p+1, | 6713 | p+1, |
6748 | ioc->facts.NumberOfPorts); | 6714 | ioc->facts.NumberOfPorts); |
6749 | if (ioc->bus_type == FC) { | 6715 | if (ioc->bus_type == FC) { |
6750 | if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) { | 6716 | if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) { |
6751 | u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow; | 6717 | u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow; |
6752 | len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n", | 6718 | seq_printf(m, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n", |
6753 | a[5], a[4], a[3], a[2], a[1], a[0]); | 6719 | a[5], a[4], a[3], a[2], a[1], a[0]); |
6754 | } | 6720 | } |
6755 | len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n", | 6721 | seq_printf(m, " WWN = %08X%08X:%08X%08X\n", |
6756 | ioc->fc_port_page0[p].WWNN.High, | 6722 | ioc->fc_port_page0[p].WWNN.High, |
6757 | ioc->fc_port_page0[p].WWNN.Low, | 6723 | ioc->fc_port_page0[p].WWNN.Low, |
6758 | ioc->fc_port_page0[p].WWPN.High, | 6724 | ioc->fc_port_page0[p].WWPN.High, |
@@ -6760,9 +6726,21 @@ procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eo | |||
6760 | } | 6726 | } |
6761 | } | 6727 | } |
6762 | 6728 | ||
6763 | MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len); | 6729 | return 0; |
6730 | } | ||
6731 | |||
6732 | static int mpt_iocinfo_proc_open(struct inode *inode, struct file *file) | ||
6733 | { | ||
6734 | return single_open(file, mpt_iocinfo_proc_show, PDE(inode)->data); | ||
6764 | } | 6735 | } |
6765 | 6736 | ||
6737 | static const struct file_operations mpt_iocinfo_proc_fops = { | ||
6738 | .owner = THIS_MODULE, | ||
6739 | .open = mpt_iocinfo_proc_open, | ||
6740 | .read = seq_read, | ||
6741 | .llseek = seq_lseek, | ||
6742 | .release = single_release, | ||
6743 | }; | ||
6766 | #endif /* CONFIG_PROC_FS } */ | 6744 | #endif /* CONFIG_PROC_FS } */ |
6767 | 6745 | ||
6768 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 6746 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
@@ -6828,6 +6806,39 @@ mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int sh | |||
6828 | 6806 | ||
6829 | *size = y; | 6807 | *size = y; |
6830 | } | 6808 | } |
6809 | |||
6810 | static void seq_mpt_print_ioc_summary(MPT_ADAPTER *ioc, struct seq_file *m, int showlan) | ||
6811 | { | ||
6812 | char expVer[32]; | ||
6813 | |||
6814 | mpt_get_fw_exp_ver(expVer, ioc); | ||
6815 | |||
6816 | /* | ||
6817 | * Shorter summary of attached ioc's... | ||
6818 | */ | ||
6819 | seq_printf(m, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d", | ||
6820 | ioc->name, | ||
6821 | ioc->prod_name, | ||
6822 | MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */ | ||
6823 | ioc->facts.FWVersion.Word, | ||
6824 | expVer, | ||
6825 | ioc->facts.NumberOfPorts, | ||
6826 | ioc->req_depth); | ||
6827 | |||
6828 | if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) { | ||
6829 | u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow; | ||
6830 | seq_printf(m, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X", | ||
6831 | a[5], a[4], a[3], a[2], a[1], a[0]); | ||
6832 | } | ||
6833 | |||
6834 | seq_printf(m, ", IRQ=%d", ioc->pci_irq); | ||
6835 | |||
6836 | if (!ioc->active) | ||
6837 | seq_printf(m, " (disabled)"); | ||
6838 | |||
6839 | seq_putc(m, '\n'); | ||
6840 | } | ||
6841 | |||
6831 | /** | 6842 | /** |
6832 | * mpt_set_taskmgmt_in_progress_flag - set flags associated with task management | 6843 | * mpt_set_taskmgmt_in_progress_flag - set flags associated with task management |
6833 | * @ioc: Pointer to MPT_ADAPTER structure | 6844 | * @ioc: Pointer to MPT_ADAPTER structure |
@@ -6913,7 +6924,6 @@ EXPORT_SYMBOL(mpt_halt_firmware); | |||
6913 | * mpt_SoftResetHandler - Issues a less expensive reset | 6924 | * mpt_SoftResetHandler - Issues a less expensive reset |
6914 | * @ioc: Pointer to MPT_ADAPTER structure | 6925 | * @ioc: Pointer to MPT_ADAPTER structure |
6915 | * @sleepFlag: Indicates if sleep or schedule must be called. | 6926 | * @sleepFlag: Indicates if sleep or schedule must be called. |
6916 | |||
6917 | * | 6927 | * |
6918 | * Returns 0 for SUCCESS or -1 if FAILED. | 6928 | * Returns 0 for SUCCESS or -1 if FAILED. |
6919 | * | 6929 | * |
@@ -6971,6 +6981,7 @@ mpt_SoftResetHandler(MPT_ADAPTER *ioc, int sleepFlag) | |||
6971 | 6981 | ||
6972 | spin_lock_irqsave(&ioc->taskmgmt_lock, flags); | 6982 | spin_lock_irqsave(&ioc->taskmgmt_lock, flags); |
6973 | if (ioc->taskmgmt_in_progress) { | 6983 | if (ioc->taskmgmt_in_progress) { |
6984 | ioc->ioc_reset_in_progress = 0; | ||
6974 | spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); | 6985 | spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); |
6975 | return -1; | 6986 | return -1; |
6976 | } | 6987 | } |
@@ -7057,7 +7068,6 @@ mpt_SoftResetHandler(MPT_ADAPTER *ioc, int sleepFlag) | |||
7057 | * mpt_Soft_Hard_ResetHandler - Try less expensive reset | 7068 | * mpt_Soft_Hard_ResetHandler - Try less expensive reset |
7058 | * @ioc: Pointer to MPT_ADAPTER structure | 7069 | * @ioc: Pointer to MPT_ADAPTER structure |
7059 | * @sleepFlag: Indicates if sleep or schedule must be called. | 7070 | * @sleepFlag: Indicates if sleep or schedule must be called. |
7060 | |||
7061 | * | 7071 | * |
7062 | * Returns 0 for SUCCESS or -1 if FAILED. | 7072 | * Returns 0 for SUCCESS or -1 if FAILED. |
7063 | * Try for softreset first, only if it fails go for expensive | 7073 | * Try for softreset first, only if it fails go for expensive |
@@ -7144,7 +7154,8 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag) | |||
7144 | rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag); | 7154 | rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag); |
7145 | if (rc != 0) { | 7155 | if (rc != 0) { |
7146 | printk(KERN_WARNING MYNAM | 7156 | printk(KERN_WARNING MYNAM |
7147 | ": WARNING - (%d) Cannot recover %s\n", rc, ioc->name); | 7157 | ": WARNING - (%d) Cannot recover %s, doorbell=0x%08x\n", |
7158 | rc, ioc->name, mpt_GetIocState(ioc, 0)); | ||
7148 | } else { | 7159 | } else { |
7149 | if (ioc->hard_resets < -1) | 7160 | if (ioc->hard_resets < -1) |
7150 | ioc->hard_resets++; | 7161 | ioc->hard_resets++; |
@@ -7997,7 +8008,7 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info) | |||
7997 | * Refer to lsi/mpi_log_sas.h. | 8008 | * Refer to lsi/mpi_log_sas.h. |
7998 | **/ | 8009 | **/ |
7999 | static void | 8010 | static void |
8000 | mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info) | 8011 | mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info, u8 cb_idx) |
8001 | { | 8012 | { |
8002 | union loginfo_type { | 8013 | union loginfo_type { |
8003 | u32 loginfo; | 8014 | u32 loginfo; |
@@ -8051,21 +8062,22 @@ union loginfo_type { | |||
8051 | if (sub_code_desc != NULL) | 8062 | if (sub_code_desc != NULL) |
8052 | printk(MYIOC_s_INFO_FMT | 8063 | printk(MYIOC_s_INFO_FMT |
8053 | "LogInfo(0x%08x): Originator={%s}, Code={%s}," | 8064 | "LogInfo(0x%08x): Originator={%s}, Code={%s}," |
8054 | " SubCode={%s}\n", | 8065 | " SubCode={%s} cb_idx %s\n", |
8055 | ioc->name, log_info, originator_desc, code_desc, | 8066 | ioc->name, log_info, originator_desc, code_desc, |
8056 | sub_code_desc); | 8067 | sub_code_desc, MptCallbacksName[cb_idx]); |
8057 | else if (code_desc != NULL) | 8068 | else if (code_desc != NULL) |
8058 | printk(MYIOC_s_INFO_FMT | 8069 | printk(MYIOC_s_INFO_FMT |
8059 | "LogInfo(0x%08x): Originator={%s}, Code={%s}," | 8070 | "LogInfo(0x%08x): Originator={%s}, Code={%s}," |
8060 | " SubCode(0x%04x)\n", | 8071 | " SubCode(0x%04x) cb_idx %s\n", |
8061 | ioc->name, log_info, originator_desc, code_desc, | 8072 | ioc->name, log_info, originator_desc, code_desc, |
8062 | sas_loginfo.dw.subcode); | 8073 | sas_loginfo.dw.subcode, MptCallbacksName[cb_idx]); |
8063 | else | 8074 | else |
8064 | printk(MYIOC_s_INFO_FMT | 8075 | printk(MYIOC_s_INFO_FMT |
8065 | "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x)," | 8076 | "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x)," |
8066 | " SubCode(0x%04x)\n", | 8077 | " SubCode(0x%04x) cb_idx %s\n", |
8067 | ioc->name, log_info, originator_desc, | 8078 | ioc->name, log_info, originator_desc, |
8068 | sas_loginfo.dw.code, sas_loginfo.dw.subcode); | 8079 | sas_loginfo.dw.code, sas_loginfo.dw.subcode, |
8080 | MptCallbacksName[cb_idx]); | ||
8069 | } | 8081 | } |
8070 | 8082 | ||
8071 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 8083 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
@@ -8430,7 +8442,8 @@ fusion_init(void) | |||
8430 | /* Register ourselves (mptbase) in order to facilitate | 8442 | /* Register ourselves (mptbase) in order to facilitate |
8431 | * EventNotification handling. | 8443 | * EventNotification handling. |
8432 | */ | 8444 | */ |
8433 | mpt_base_index = mpt_register(mptbase_reply, MPTBASE_DRIVER); | 8445 | mpt_base_index = mpt_register(mptbase_reply, MPTBASE_DRIVER, |
8446 | "mptbase_reply"); | ||
8434 | 8447 | ||
8435 | /* Register for hard reset handling callbacks. | 8448 | /* Register for hard reset handling callbacks. |
8436 | */ | 8449 | */ |
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index b613eb3d4706..f71f22948477 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h | |||
@@ -76,8 +76,8 @@ | |||
76 | #define COPYRIGHT "Copyright (c) 1999-2008 " MODULEAUTHOR | 76 | #define COPYRIGHT "Copyright (c) 1999-2008 " MODULEAUTHOR |
77 | #endif | 77 | #endif |
78 | 78 | ||
79 | #define MPT_LINUX_VERSION_COMMON "3.04.15" | 79 | #define MPT_LINUX_VERSION_COMMON "3.04.17" |
80 | #define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.15" | 80 | #define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.17" |
81 | #define WHAT_MAGIC_STRING "@" "(" "#" ")" | 81 | #define WHAT_MAGIC_STRING "@" "(" "#" ")" |
82 | 82 | ||
83 | #define show_mptmod_ver(s,ver) \ | 83 | #define show_mptmod_ver(s,ver) \ |
@@ -396,6 +396,8 @@ typedef struct _VirtTarget { | |||
396 | u8 raidVolume; /* set, if RAID Volume */ | 396 | u8 raidVolume; /* set, if RAID Volume */ |
397 | u8 type; /* byte 0 of Inquiry data */ | 397 | u8 type; /* byte 0 of Inquiry data */ |
398 | u8 deleted; /* target in process of being removed */ | 398 | u8 deleted; /* target in process of being removed */ |
399 | u8 inDMD; /* currently in the device | ||
400 | removal delay timer */ | ||
399 | u32 num_luns; | 401 | u32 num_luns; |
400 | } VirtTarget; | 402 | } VirtTarget; |
401 | 403 | ||
@@ -418,31 +420,6 @@ typedef struct _VirtDevice { | |||
418 | #define MPT_TARGET_FLAGS_LED_ON 0x80 | 420 | #define MPT_TARGET_FLAGS_LED_ON 0x80 |
419 | 421 | ||
420 | /* | 422 | /* |
421 | * /proc/mpt interface | ||
422 | */ | ||
423 | typedef struct { | ||
424 | const char *name; | ||
425 | mode_t mode; | ||
426 | int pad; | ||
427 | read_proc_t *read_proc; | ||
428 | write_proc_t *write_proc; | ||
429 | } mpt_proc_entry_t; | ||
430 | |||
431 | #define MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len) \ | ||
432 | do { \ | ||
433 | len -= offset; \ | ||
434 | if (len < request) { \ | ||
435 | *eof = 1; \ | ||
436 | if (len <= 0) \ | ||
437 | return 0; \ | ||
438 | } else \ | ||
439 | len = request; \ | ||
440 | *start = buf + offset; \ | ||
441 | return len; \ | ||
442 | } while (0) | ||
443 | |||
444 | |||
445 | /* | ||
446 | * IOCTL structure and associated defines | 423 | * IOCTL structure and associated defines |
447 | */ | 424 | */ |
448 | 425 | ||
@@ -580,6 +557,7 @@ struct mptfc_rport_info | |||
580 | typedef void (*MPT_ADD_SGE)(void *pAddr, u32 flagslength, dma_addr_t dma_addr); | 557 | typedef void (*MPT_ADD_SGE)(void *pAddr, u32 flagslength, dma_addr_t dma_addr); |
581 | typedef void (*MPT_ADD_CHAIN)(void *pAddr, u8 next, u16 length, | 558 | typedef void (*MPT_ADD_CHAIN)(void *pAddr, u8 next, u16 length, |
582 | dma_addr_t dma_addr); | 559 | dma_addr_t dma_addr); |
560 | typedef void (*MPT_SCHEDULE_TARGET_RESET)(void *ioc); | ||
583 | 561 | ||
584 | /* | 562 | /* |
585 | * Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS | 563 | * Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS |
@@ -601,7 +579,7 @@ typedef struct _MPT_ADAPTER | |||
601 | u16 nvdata_version_default; | 579 | u16 nvdata_version_default; |
602 | int debug_level; | 580 | int debug_level; |
603 | u8 io_missing_delay; | 581 | u8 io_missing_delay; |
604 | u8 device_missing_delay; | 582 | u16 device_missing_delay; |
605 | SYSIF_REGS __iomem *chip; /* == c8817000 (mmap) */ | 583 | SYSIF_REGS __iomem *chip; /* == c8817000 (mmap) */ |
606 | SYSIF_REGS __iomem *pio_chip; /* Programmed IO (downloadboot) */ | 584 | SYSIF_REGS __iomem *pio_chip; /* Programmed IO (downloadboot) */ |
607 | u8 bus_type; | 585 | u8 bus_type; |
@@ -738,6 +716,7 @@ typedef struct _MPT_ADAPTER | |||
738 | int taskmgmt_in_progress; | 716 | int taskmgmt_in_progress; |
739 | u8 taskmgmt_quiesce_io; | 717 | u8 taskmgmt_quiesce_io; |
740 | u8 ioc_reset_in_progress; | 718 | u8 ioc_reset_in_progress; |
719 | MPT_SCHEDULE_TARGET_RESET schedule_target_reset; | ||
741 | struct work_struct sas_persist_task; | 720 | struct work_struct sas_persist_task; |
742 | 721 | ||
743 | struct work_struct fc_setup_reset_work; | 722 | struct work_struct fc_setup_reset_work; |
@@ -922,7 +901,8 @@ extern void mpt_detach(struct pci_dev *pdev); | |||
922 | extern int mpt_suspend(struct pci_dev *pdev, pm_message_t state); | 901 | extern int mpt_suspend(struct pci_dev *pdev, pm_message_t state); |
923 | extern int mpt_resume(struct pci_dev *pdev); | 902 | extern int mpt_resume(struct pci_dev *pdev); |
924 | #endif | 903 | #endif |
925 | extern u8 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass); | 904 | extern u8 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass, |
905 | char *func_name); | ||
926 | extern void mpt_deregister(u8 cb_idx); | 906 | extern void mpt_deregister(u8 cb_idx); |
927 | extern int mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc); | 907 | extern int mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc); |
928 | extern void mpt_event_deregister(u8 cb_idx); | 908 | extern void mpt_event_deregister(u8 cb_idx); |
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index f06b29193b4e..d8ddfdf8be14 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c | |||
@@ -261,10 +261,16 @@ mptctl_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply) | |||
261 | /* We are done, issue wake up | 261 | /* We are done, issue wake up |
262 | */ | 262 | */ |
263 | if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_PENDING) { | 263 | if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_PENDING) { |
264 | if (req->u.hdr.Function == MPI_FUNCTION_SCSI_TASK_MGMT) | 264 | if (req->u.hdr.Function == MPI_FUNCTION_SCSI_TASK_MGMT) { |
265 | mpt_clear_taskmgmt_in_progress_flag(ioc); | 265 | mpt_clear_taskmgmt_in_progress_flag(ioc); |
266 | ioc->ioctl_cmds.status &= ~MPT_MGMT_STATUS_PENDING; | 266 | ioc->ioctl_cmds.status &= ~MPT_MGMT_STATUS_PENDING; |
267 | complete(&ioc->ioctl_cmds.done); | 267 | complete(&ioc->ioctl_cmds.done); |
268 | if (ioc->bus_type == SAS) | ||
269 | ioc->schedule_target_reset(ioc); | ||
270 | } else { | ||
271 | ioc->ioctl_cmds.status &= ~MPT_MGMT_STATUS_PENDING; | ||
272 | complete(&ioc->ioctl_cmds.done); | ||
273 | } | ||
268 | } | 274 | } |
269 | 275 | ||
270 | out_continuation: | 276 | out_continuation: |
@@ -298,6 +304,8 @@ mptctl_taskmgmt_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
298 | mpt_clear_taskmgmt_in_progress_flag(ioc); | 304 | mpt_clear_taskmgmt_in_progress_flag(ioc); |
299 | ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING; | 305 | ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING; |
300 | complete(&ioc->taskmgmt_cmds.done); | 306 | complete(&ioc->taskmgmt_cmds.done); |
307 | if (ioc->bus_type == SAS) | ||
308 | ioc->schedule_target_reset(ioc); | ||
301 | return 1; | 309 | return 1; |
302 | } | 310 | } |
303 | return 0; | 311 | return 0; |
@@ -946,9 +954,12 @@ retry_wait: | |||
946 | mpt_free_msg_frame(iocp, mf); | 954 | mpt_free_msg_frame(iocp, mf); |
947 | goto fwdl_out; | 955 | goto fwdl_out; |
948 | } | 956 | } |
949 | if (!timeleft) | 957 | if (!timeleft) { |
958 | printk(MYIOC_s_WARN_FMT | ||
959 | "FW download timeout, doorbell=0x%08x\n", | ||
960 | iocp->name, mpt_GetIocState(iocp, 0)); | ||
950 | mptctl_timeout_expired(iocp, mf); | 961 | mptctl_timeout_expired(iocp, mf); |
951 | else | 962 | } else |
952 | goto retry_wait; | 963 | goto retry_wait; |
953 | goto fwdl_out; | 964 | goto fwdl_out; |
954 | } | 965 | } |
@@ -2293,6 +2304,10 @@ retry_wait: | |||
2293 | goto done_free_mem; | 2304 | goto done_free_mem; |
2294 | } | 2305 | } |
2295 | if (!timeleft) { | 2306 | if (!timeleft) { |
2307 | printk(MYIOC_s_WARN_FMT | ||
2308 | "mpt cmd timeout, doorbell=0x%08x" | ||
2309 | " function=0x%x\n", | ||
2310 | ioc->name, mpt_GetIocState(ioc, 0), function); | ||
2296 | if (function == MPI_FUNCTION_SCSI_TASK_MGMT) | 2311 | if (function == MPI_FUNCTION_SCSI_TASK_MGMT) |
2297 | mutex_unlock(&ioc->taskmgmt_cmds.mutex); | 2312 | mutex_unlock(&ioc->taskmgmt_cmds.mutex); |
2298 | mptctl_timeout_expired(ioc, mf); | 2313 | mptctl_timeout_expired(ioc, mf); |
@@ -2600,9 +2615,12 @@ retry_wait: | |||
2600 | mpt_free_msg_frame(ioc, mf); | 2615 | mpt_free_msg_frame(ioc, mf); |
2601 | goto out; | 2616 | goto out; |
2602 | } | 2617 | } |
2603 | if (!timeleft) | 2618 | if (!timeleft) { |
2619 | printk(MYIOC_s_WARN_FMT | ||
2620 | "HOST INFO command timeout, doorbell=0x%08x\n", | ||
2621 | ioc->name, mpt_GetIocState(ioc, 0)); | ||
2604 | mptctl_timeout_expired(ioc, mf); | 2622 | mptctl_timeout_expired(ioc, mf); |
2605 | else | 2623 | } else |
2606 | goto retry_wait; | 2624 | goto retry_wait; |
2607 | goto out; | 2625 | goto out; |
2608 | } | 2626 | } |
@@ -3000,7 +3018,8 @@ static int __init mptctl_init(void) | |||
3000 | * Install our handler | 3018 | * Install our handler |
3001 | */ | 3019 | */ |
3002 | ++where; | 3020 | ++where; |
3003 | mptctl_id = mpt_register(mptctl_reply, MPTCTL_DRIVER); | 3021 | mptctl_id = mpt_register(mptctl_reply, MPTCTL_DRIVER, |
3022 | "mptctl_reply"); | ||
3004 | if (!mptctl_id || mptctl_id >= MPT_MAX_PROTOCOL_DRIVERS) { | 3023 | if (!mptctl_id || mptctl_id >= MPT_MAX_PROTOCOL_DRIVERS) { |
3005 | printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n"); | 3024 | printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n"); |
3006 | misc_deregister(&mptctl_miscdev); | 3025 | misc_deregister(&mptctl_miscdev); |
@@ -3008,7 +3027,8 @@ static int __init mptctl_init(void) | |||
3008 | goto out_fail; | 3027 | goto out_fail; |
3009 | } | 3028 | } |
3010 | 3029 | ||
3011 | mptctl_taskmgmt_id = mpt_register(mptctl_taskmgmt_reply, MPTCTL_DRIVER); | 3030 | mptctl_taskmgmt_id = mpt_register(mptctl_taskmgmt_reply, MPTCTL_DRIVER, |
3031 | "mptctl_taskmgmt_reply"); | ||
3012 | if (!mptctl_taskmgmt_id || mptctl_taskmgmt_id >= MPT_MAX_PROTOCOL_DRIVERS) { | 3032 | if (!mptctl_taskmgmt_id || mptctl_taskmgmt_id >= MPT_MAX_PROTOCOL_DRIVERS) { |
3013 | printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n"); | 3033 | printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n"); |
3014 | mpt_deregister(mptctl_id); | 3034 | mpt_deregister(mptctl_id); |
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index b5f03ad81568..e15220ff52fc 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c | |||
@@ -1472,9 +1472,12 @@ mptfc_init(void) | |||
1472 | if (!mptfc_transport_template) | 1472 | if (!mptfc_transport_template) |
1473 | return -ENODEV; | 1473 | return -ENODEV; |
1474 | 1474 | ||
1475 | mptfcDoneCtx = mpt_register(mptscsih_io_done, MPTFC_DRIVER); | 1475 | mptfcDoneCtx = mpt_register(mptscsih_io_done, MPTFC_DRIVER, |
1476 | mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER); | 1476 | "mptscsih_scandv_complete"); |
1477 | mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER); | 1477 | mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER, |
1478 | "mptscsih_scandv_complete"); | ||
1479 | mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER, | ||
1480 | "mptscsih_scandv_complete"); | ||
1478 | 1481 | ||
1479 | mpt_event_register(mptfcDoneCtx, mptfc_event_process); | 1482 | mpt_event_register(mptfcDoneCtx, mptfc_event_process); |
1480 | mpt_reset_register(mptfcDoneCtx, mptfc_ioc_reset); | 1483 | mpt_reset_register(mptfcDoneCtx, mptfc_ioc_reset); |
diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c index 4fa9665cbe93..cbe96072a6cc 100644 --- a/drivers/message/fusion/mptlan.c +++ b/drivers/message/fusion/mptlan.c | |||
@@ -1452,7 +1452,9 @@ static int __init mpt_lan_init (void) | |||
1452 | { | 1452 | { |
1453 | show_mptmod_ver(LANAME, LANVER); | 1453 | show_mptmod_ver(LANAME, LANVER); |
1454 | 1454 | ||
1455 | if ((LanCtx = mpt_register(lan_reply, MPTLAN_DRIVER)) <= 0) { | 1455 | LanCtx = mpt_register(lan_reply, MPTLAN_DRIVER, |
1456 | "lan_reply"); | ||
1457 | if (LanCtx <= 0) { | ||
1456 | printk (KERN_ERR MYNAM ": Failed to register with MPT base driver\n"); | 1458 | printk (KERN_ERR MYNAM ": Failed to register with MPT base driver\n"); |
1457 | return -EBUSY; | 1459 | return -EBUSY; |
1458 | } | 1460 | } |
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index ac000e83db0e..83a5115f0251 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c | |||
@@ -57,6 +57,7 @@ | |||
57 | #include <scsi/scsi_device.h> | 57 | #include <scsi/scsi_device.h> |
58 | #include <scsi/scsi_host.h> | 58 | #include <scsi/scsi_host.h> |
59 | #include <scsi/scsi_transport_sas.h> | 59 | #include <scsi/scsi_transport_sas.h> |
60 | #include <scsi/scsi_transport.h> | ||
60 | #include <scsi/scsi_dbg.h> | 61 | #include <scsi/scsi_dbg.h> |
61 | 62 | ||
62 | #include "mptbase.h" | 63 | #include "mptbase.h" |
@@ -126,6 +127,7 @@ static void mptsas_scan_sas_topology(MPT_ADAPTER *ioc); | |||
126 | static void mptsas_broadcast_primative_work(struct fw_event_work *fw_event); | 127 | static void mptsas_broadcast_primative_work(struct fw_event_work *fw_event); |
127 | static void mptsas_handle_queue_full_event(struct fw_event_work *fw_event); | 128 | static void mptsas_handle_queue_full_event(struct fw_event_work *fw_event); |
128 | static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id); | 129 | static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id); |
130 | void mptsas_schedule_target_reset(void *ioc); | ||
129 | 131 | ||
130 | static void mptsas_print_phy_data(MPT_ADAPTER *ioc, | 132 | static void mptsas_print_phy_data(MPT_ADAPTER *ioc, |
131 | MPI_SAS_IO_UNIT0_PHY_DATA *phy_data) | 133 | MPI_SAS_IO_UNIT0_PHY_DATA *phy_data) |
@@ -1139,6 +1141,44 @@ mptsas_target_reset_queue(MPT_ADAPTER *ioc, | |||
1139 | } | 1141 | } |
1140 | 1142 | ||
1141 | /** | 1143 | /** |
1144 | * mptsas_schedule_target_reset- send pending target reset | ||
1145 | * @iocp: per adapter object | ||
1146 | * | ||
1147 | * This function will delete scheduled target reset from the list and | ||
1148 | * try to send next target reset. This will be called from completion | ||
1149 | * context of any Task managment command. | ||
1150 | */ | ||
1151 | |||
1152 | void | ||
1153 | mptsas_schedule_target_reset(void *iocp) | ||
1154 | { | ||
1155 | MPT_ADAPTER *ioc = (MPT_ADAPTER *)(iocp); | ||
1156 | MPT_SCSI_HOST *hd = shost_priv(ioc->sh); | ||
1157 | struct list_head *head = &hd->target_reset_list; | ||
1158 | struct mptsas_target_reset_event *target_reset_list; | ||
1159 | u8 id, channel; | ||
1160 | /* | ||
1161 | * issue target reset to next device in the queue | ||
1162 | */ | ||
1163 | |||
1164 | head = &hd->target_reset_list; | ||
1165 | if (list_empty(head)) | ||
1166 | return; | ||
1167 | |||
1168 | target_reset_list = list_entry(head->next, | ||
1169 | struct mptsas_target_reset_event, list); | ||
1170 | |||
1171 | id = target_reset_list->sas_event_data.TargetID; | ||
1172 | channel = target_reset_list->sas_event_data.Bus; | ||
1173 | target_reset_list->time_count = jiffies; | ||
1174 | |||
1175 | if (mptsas_target_reset(ioc, channel, id)) | ||
1176 | target_reset_list->target_reset_issued = 1; | ||
1177 | return; | ||
1178 | } | ||
1179 | |||
1180 | |||
1181 | /** | ||
1142 | * mptsas_taskmgmt_complete - complete SAS task management function | 1182 | * mptsas_taskmgmt_complete - complete SAS task management function |
1143 | * @ioc: Pointer to MPT_ADAPTER structure | 1183 | * @ioc: Pointer to MPT_ADAPTER structure |
1144 | * | 1184 | * |
@@ -1222,28 +1262,12 @@ mptsas_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
1222 | * enable work queue to remove device from upper layers | 1262 | * enable work queue to remove device from upper layers |
1223 | */ | 1263 | */ |
1224 | list_del(&target_reset_list->list); | 1264 | list_del(&target_reset_list->list); |
1225 | if ((mptsas_find_vtarget(ioc, channel, id)) && !ioc->fw_events_off) | 1265 | if (!ioc->fw_events_off) |
1226 | mptsas_queue_device_delete(ioc, | 1266 | mptsas_queue_device_delete(ioc, |
1227 | &target_reset_list->sas_event_data); | 1267 | &target_reset_list->sas_event_data); |
1228 | 1268 | ||
1229 | 1269 | ||
1230 | /* | 1270 | ioc->schedule_target_reset(ioc); |
1231 | * issue target reset to next device in the queue | ||
1232 | */ | ||
1233 | |||
1234 | head = &hd->target_reset_list; | ||
1235 | if (list_empty(head)) | ||
1236 | return 1; | ||
1237 | |||
1238 | target_reset_list = list_entry(head->next, struct mptsas_target_reset_event, | ||
1239 | list); | ||
1240 | |||
1241 | id = target_reset_list->sas_event_data.TargetID; | ||
1242 | channel = target_reset_list->sas_event_data.Bus; | ||
1243 | target_reset_list->time_count = jiffies; | ||
1244 | |||
1245 | if (mptsas_target_reset(ioc, channel, id)) | ||
1246 | target_reset_list->target_reset_issued = 1; | ||
1247 | 1271 | ||
1248 | return 1; | 1272 | return 1; |
1249 | } | 1273 | } |
@@ -1889,6 +1913,48 @@ mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) | |||
1889 | return mptscsih_qcmd(SCpnt,done); | 1913 | return mptscsih_qcmd(SCpnt,done); |
1890 | } | 1914 | } |
1891 | 1915 | ||
1916 | /** | ||
1917 | * mptsas_mptsas_eh_timed_out - resets the scsi_cmnd timeout | ||
1918 | * if the device under question is currently in the | ||
1919 | * device removal delay. | ||
1920 | * @sc: scsi command that the midlayer is about to time out | ||
1921 | * | ||
1922 | **/ | ||
1923 | static enum blk_eh_timer_return mptsas_eh_timed_out(struct scsi_cmnd *sc) | ||
1924 | { | ||
1925 | MPT_SCSI_HOST *hd; | ||
1926 | MPT_ADAPTER *ioc; | ||
1927 | VirtDevice *vdevice; | ||
1928 | enum blk_eh_timer_return rc = BLK_EH_NOT_HANDLED; | ||
1929 | |||
1930 | hd = shost_priv(sc->device->host); | ||
1931 | if (hd == NULL) { | ||
1932 | printk(KERN_ERR MYNAM ": %s: Can't locate host! (sc=%p)\n", | ||
1933 | __func__, sc); | ||
1934 | goto done; | ||
1935 | } | ||
1936 | |||
1937 | ioc = hd->ioc; | ||
1938 | if (ioc->bus_type != SAS) { | ||
1939 | printk(KERN_ERR MYNAM ": %s: Wrong bus type (sc=%p)\n", | ||
1940 | __func__, sc); | ||
1941 | goto done; | ||
1942 | } | ||
1943 | |||
1944 | vdevice = sc->device->hostdata; | ||
1945 | if (vdevice && vdevice->vtarget && (vdevice->vtarget->inDMD | ||
1946 | || vdevice->vtarget->deleted)) { | ||
1947 | dtmprintk(ioc, printk(MYIOC_s_WARN_FMT ": %s: target removed " | ||
1948 | "or in device removal delay (sc=%p)\n", | ||
1949 | ioc->name, __func__, sc)); | ||
1950 | rc = BLK_EH_RESET_TIMER; | ||
1951 | goto done; | ||
1952 | } | ||
1953 | |||
1954 | done: | ||
1955 | return rc; | ||
1956 | } | ||
1957 | |||
1892 | 1958 | ||
1893 | static struct scsi_host_template mptsas_driver_template = { | 1959 | static struct scsi_host_template mptsas_driver_template = { |
1894 | .module = THIS_MODULE, | 1960 | .module = THIS_MODULE, |
@@ -2364,7 +2430,7 @@ mptsas_sas_io_unit_pg1(MPT_ADAPTER *ioc) | |||
2364 | SasIOUnitPage1_t *buffer; | 2430 | SasIOUnitPage1_t *buffer; |
2365 | dma_addr_t dma_handle; | 2431 | dma_addr_t dma_handle; |
2366 | int error; | 2432 | int error; |
2367 | u16 device_missing_delay; | 2433 | u8 device_missing_delay; |
2368 | 2434 | ||
2369 | memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t)); | 2435 | memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t)); |
2370 | memset(&cfg, 0, sizeof(CONFIGPARMS)); | 2436 | memset(&cfg, 0, sizeof(CONFIGPARMS)); |
@@ -2401,7 +2467,7 @@ mptsas_sas_io_unit_pg1(MPT_ADAPTER *ioc) | |||
2401 | 2467 | ||
2402 | ioc->io_missing_delay = | 2468 | ioc->io_missing_delay = |
2403 | le16_to_cpu(buffer->IODeviceMissingDelay); | 2469 | le16_to_cpu(buffer->IODeviceMissingDelay); |
2404 | device_missing_delay = le16_to_cpu(buffer->ReportDeviceMissingDelay); | 2470 | device_missing_delay = buffer->ReportDeviceMissingDelay; |
2405 | ioc->device_missing_delay = (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_UNIT_16) ? | 2471 | ioc->device_missing_delay = (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_UNIT_16) ? |
2406 | (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16 : | 2472 | (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16 : |
2407 | device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK; | 2473 | device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK; |
@@ -2549,6 +2615,7 @@ mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info, | |||
2549 | device_info->sas_address = le64_to_cpu(sas_address); | 2615 | device_info->sas_address = le64_to_cpu(sas_address); |
2550 | device_info->device_info = | 2616 | device_info->device_info = |
2551 | le32_to_cpu(buffer->DeviceInfo); | 2617 | le32_to_cpu(buffer->DeviceInfo); |
2618 | device_info->flags = le16_to_cpu(buffer->Flags); | ||
2552 | 2619 | ||
2553 | out_free_consistent: | 2620 | out_free_consistent: |
2554 | pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4, | 2621 | pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4, |
@@ -2960,6 +3027,7 @@ static int mptsas_probe_one_phy(struct device *dev, | |||
2960 | struct sas_phy *phy; | 3027 | struct sas_phy *phy; |
2961 | struct sas_port *port; | 3028 | struct sas_port *port; |
2962 | int error = 0; | 3029 | int error = 0; |
3030 | VirtTarget *vtarget; | ||
2963 | 3031 | ||
2964 | if (!dev) { | 3032 | if (!dev) { |
2965 | error = -ENODEV; | 3033 | error = -ENODEV; |
@@ -3182,6 +3250,16 @@ static int mptsas_probe_one_phy(struct device *dev, | |||
3182 | rphy_to_expander_device(rphy)); | 3250 | rphy_to_expander_device(rphy)); |
3183 | } | 3251 | } |
3184 | 3252 | ||
3253 | /* If the device exists,verify it wasn't previously flagged | ||
3254 | as a missing device. If so, clear it */ | ||
3255 | vtarget = mptsas_find_vtarget(ioc, | ||
3256 | phy_info->attached.channel, | ||
3257 | phy_info->attached.id); | ||
3258 | if (vtarget && vtarget->inDMD) { | ||
3259 | printk(KERN_INFO "Device returned, unsetting inDMD\n"); | ||
3260 | vtarget->inDMD = 0; | ||
3261 | } | ||
3262 | |||
3185 | out: | 3263 | out: |
3186 | return error; | 3264 | return error; |
3187 | } | 3265 | } |
@@ -3635,9 +3713,42 @@ mptsas_send_link_status_event(struct fw_event_work *fw_event) | |||
3635 | MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION) | 3713 | MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION) |
3636 | phy_info->phy->negotiated_linkrate = | 3714 | phy_info->phy->negotiated_linkrate = |
3637 | SAS_LINK_RATE_FAILED; | 3715 | SAS_LINK_RATE_FAILED; |
3638 | else | 3716 | else { |
3639 | phy_info->phy->negotiated_linkrate = | 3717 | phy_info->phy->negotiated_linkrate = |
3640 | SAS_LINK_RATE_UNKNOWN; | 3718 | SAS_LINK_RATE_UNKNOWN; |
3719 | if (ioc->device_missing_delay && | ||
3720 | mptsas_is_end_device(&phy_info->attached)) { | ||
3721 | struct scsi_device *sdev; | ||
3722 | VirtDevice *vdevice; | ||
3723 | u8 channel, id; | ||
3724 | id = phy_info->attached.id; | ||
3725 | channel = phy_info->attached.channel; | ||
3726 | devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT | ||
3727 | "Link down for fw_id %d:fw_channel %d\n", | ||
3728 | ioc->name, phy_info->attached.id, | ||
3729 | phy_info->attached.channel)); | ||
3730 | |||
3731 | shost_for_each_device(sdev, ioc->sh) { | ||
3732 | vdevice = sdev->hostdata; | ||
3733 | if ((vdevice == NULL) || | ||
3734 | (vdevice->vtarget == NULL)) | ||
3735 | continue; | ||
3736 | if ((vdevice->vtarget->tflags & | ||
3737 | MPT_TARGET_FLAGS_RAID_COMPONENT || | ||
3738 | vdevice->vtarget->raidVolume)) | ||
3739 | continue; | ||
3740 | if (vdevice->vtarget->id == id && | ||
3741 | vdevice->vtarget->channel == | ||
3742 | channel) | ||
3743 | devtprintk(ioc, | ||
3744 | printk(MYIOC_s_DEBUG_FMT | ||
3745 | "SDEV OUTSTANDING CMDS" | ||
3746 | "%d\n", ioc->name, | ||
3747 | sdev->device_busy)); | ||
3748 | } | ||
3749 | |||
3750 | } | ||
3751 | } | ||
3641 | } | 3752 | } |
3642 | out: | 3753 | out: |
3643 | mptsas_free_fw_event(ioc, fw_event); | 3754 | mptsas_free_fw_event(ioc, fw_event); |
@@ -3840,6 +3951,13 @@ mptsas_probe_devices(MPT_ADAPTER *ioc) | |||
3840 | MPI_SAS_DEVICE_INFO_SATA_DEVICE)) == 0) | 3951 | MPI_SAS_DEVICE_INFO_SATA_DEVICE)) == 0) |
3841 | continue; | 3952 | continue; |
3842 | 3953 | ||
3954 | /* If there is no FW B_T mapping for this device then continue | ||
3955 | * */ | ||
3956 | if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT) | ||
3957 | || !(sas_device.flags & | ||
3958 | MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED)) | ||
3959 | continue; | ||
3960 | |||
3843 | phy_info = mptsas_refreshing_device_handles(ioc, &sas_device); | 3961 | phy_info = mptsas_refreshing_device_handles(ioc, &sas_device); |
3844 | if (!phy_info) | 3962 | if (!phy_info) |
3845 | continue; | 3963 | continue; |
@@ -4149,6 +4267,14 @@ mptsas_adding_inactive_raid_components(MPT_ADAPTER *ioc, u8 channel, u8 id) | |||
4149 | phys_disk.PhysDiskID)) | 4267 | phys_disk.PhysDiskID)) |
4150 | continue; | 4268 | continue; |
4151 | 4269 | ||
4270 | /* If there is no FW B_T mapping for this device then continue | ||
4271 | * */ | ||
4272 | if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT) | ||
4273 | || !(sas_device.flags & | ||
4274 | MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED)) | ||
4275 | continue; | ||
4276 | |||
4277 | |||
4152 | phy_info = mptsas_find_phyinfo_by_sas_address(ioc, | 4278 | phy_info = mptsas_find_phyinfo_by_sas_address(ioc, |
4153 | sas_device.sas_address); | 4279 | sas_device.sas_address); |
4154 | mptsas_add_end_device(ioc, phy_info); | 4280 | mptsas_add_end_device(ioc, phy_info); |
@@ -4171,6 +4297,7 @@ mptsas_hotplug_work(MPT_ADAPTER *ioc, struct fw_event_work *fw_event, | |||
4171 | struct mptsas_devinfo sas_device; | 4297 | struct mptsas_devinfo sas_device; |
4172 | VirtTarget *vtarget; | 4298 | VirtTarget *vtarget; |
4173 | int i; | 4299 | int i; |
4300 | struct mptsas_portinfo *port_info; | ||
4174 | 4301 | ||
4175 | switch (hot_plug_info->event_type) { | 4302 | switch (hot_plug_info->event_type) { |
4176 | 4303 | ||
@@ -4199,12 +4326,47 @@ mptsas_hotplug_work(MPT_ADAPTER *ioc, struct fw_event_work *fw_event, | |||
4199 | (hot_plug_info->channel << 8) + | 4326 | (hot_plug_info->channel << 8) + |
4200 | hot_plug_info->id); | 4327 | hot_plug_info->id); |
4201 | 4328 | ||
4329 | /* If there is no FW B_T mapping for this device then break | ||
4330 | * */ | ||
4331 | if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT) | ||
4332 | || !(sas_device.flags & | ||
4333 | MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED)) | ||
4334 | break; | ||
4335 | |||
4202 | if (!sas_device.handle) | 4336 | if (!sas_device.handle) |
4203 | return; | 4337 | return; |
4204 | 4338 | ||
4205 | phy_info = mptsas_refreshing_device_handles(ioc, &sas_device); | 4339 | phy_info = mptsas_refreshing_device_handles(ioc, &sas_device); |
4206 | if (!phy_info) | 4340 | /* Only For SATA Device ADD */ |
4341 | if (!phy_info && (sas_device.device_info & | ||
4342 | MPI_SAS_DEVICE_INFO_SATA_DEVICE)) { | ||
4343 | devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT | ||
4344 | "%s %d SATA HOT PLUG: " | ||
4345 | "parent handle of device %x\n", ioc->name, | ||
4346 | __func__, __LINE__, sas_device.handle_parent)); | ||
4347 | port_info = mptsas_find_portinfo_by_handle(ioc, | ||
4348 | sas_device.handle_parent); | ||
4349 | |||
4350 | if (port_info == ioc->hba_port_info) | ||
4351 | mptsas_probe_hba_phys(ioc); | ||
4352 | else if (port_info) | ||
4353 | mptsas_expander_refresh(ioc, port_info); | ||
4354 | else { | ||
4355 | dfailprintk(ioc, printk(MYIOC_s_ERR_FMT | ||
4356 | "%s %d port info is NULL\n", | ||
4357 | ioc->name, __func__, __LINE__)); | ||
4358 | break; | ||
4359 | } | ||
4360 | phy_info = mptsas_refreshing_device_handles | ||
4361 | (ioc, &sas_device); | ||
4362 | } | ||
4363 | |||
4364 | if (!phy_info) { | ||
4365 | dfailprintk(ioc, printk(MYIOC_s_ERR_FMT | ||
4366 | "%s %d phy info is NULL\n", | ||
4367 | ioc->name, __func__, __LINE__)); | ||
4207 | break; | 4368 | break; |
4369 | } | ||
4208 | 4370 | ||
4209 | if (mptsas_get_rphy(phy_info)) | 4371 | if (mptsas_get_rphy(phy_info)) |
4210 | break; | 4372 | break; |
@@ -4241,6 +4403,13 @@ mptsas_hotplug_work(MPT_ADAPTER *ioc, struct fw_event_work *fw_event, | |||
4241 | break; | 4403 | break; |
4242 | } | 4404 | } |
4243 | 4405 | ||
4406 | /* If there is no FW B_T mapping for this device then break | ||
4407 | * */ | ||
4408 | if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT) | ||
4409 | || !(sas_device.flags & | ||
4410 | MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED)) | ||
4411 | break; | ||
4412 | |||
4244 | phy_info = mptsas_find_phyinfo_by_sas_address( | 4413 | phy_info = mptsas_find_phyinfo_by_sas_address( |
4245 | ioc, sas_device.sas_address); | 4414 | ioc, sas_device.sas_address); |
4246 | 4415 | ||
@@ -4294,6 +4463,13 @@ mptsas_hotplug_work(MPT_ADAPTER *ioc, struct fw_event_work *fw_event, | |||
4294 | break; | 4463 | break; |
4295 | } | 4464 | } |
4296 | 4465 | ||
4466 | /* If there is no FW B_T mapping for this device then break | ||
4467 | * */ | ||
4468 | if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT) | ||
4469 | || !(sas_device.flags & | ||
4470 | MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED)) | ||
4471 | break; | ||
4472 | |||
4297 | phy_info = mptsas_find_phyinfo_by_sas_address(ioc, | 4473 | phy_info = mptsas_find_phyinfo_by_sas_address(ioc, |
4298 | sas_device.sas_address); | 4474 | sas_device.sas_address); |
4299 | if (!phy_info) { | 4475 | if (!phy_info) { |
@@ -4727,8 +4903,9 @@ mptsas_broadcast_primative_work(struct fw_event_work *fw_event) | |||
4727 | mutex_unlock(&ioc->taskmgmt_cmds.mutex); | 4903 | mutex_unlock(&ioc->taskmgmt_cmds.mutex); |
4728 | 4904 | ||
4729 | if (issue_reset) { | 4905 | if (issue_reset) { |
4730 | printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n", | 4906 | printk(MYIOC_s_WARN_FMT |
4731 | ioc->name, __func__); | 4907 | "Issuing Reset from %s!! doorbell=0x%08x\n", |
4908 | ioc->name, __func__, mpt_GetIocState(ioc, 0)); | ||
4732 | mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP); | 4909 | mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP); |
4733 | } | 4910 | } |
4734 | mptsas_free_fw_event(ioc, fw_event); | 4911 | mptsas_free_fw_event(ioc, fw_event); |
@@ -4816,12 +4993,47 @@ mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply) | |||
4816 | { | 4993 | { |
4817 | EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data = | 4994 | EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data = |
4818 | (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data; | 4995 | (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data; |
4996 | u16 ioc_stat; | ||
4997 | ioc_stat = le16_to_cpu(reply->IOCStatus); | ||
4819 | 4998 | ||
4820 | if (sas_event_data->ReasonCode == | 4999 | if (sas_event_data->ReasonCode == |
4821 | MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING) { | 5000 | MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING) { |
4822 | mptsas_target_reset_queue(ioc, sas_event_data); | 5001 | mptsas_target_reset_queue(ioc, sas_event_data); |
4823 | return 0; | 5002 | return 0; |
4824 | } | 5003 | } |
5004 | if (sas_event_data->ReasonCode == | ||
5005 | MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET && | ||
5006 | ioc->device_missing_delay && | ||
5007 | (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE)) { | ||
5008 | VirtTarget *vtarget = NULL; | ||
5009 | u8 id, channel; | ||
5010 | u32 log_info = le32_to_cpu(reply->IOCLogInfo); | ||
5011 | |||
5012 | id = sas_event_data->TargetID; | ||
5013 | channel = sas_event_data->Bus; | ||
5014 | |||
5015 | vtarget = mptsas_find_vtarget(ioc, channel, id); | ||
5016 | if (vtarget) { | ||
5017 | devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT | ||
5018 | "LogInfo (0x%x) available for " | ||
5019 | "INTERNAL_DEVICE_RESET" | ||
5020 | "fw_id %d fw_channel %d\n", ioc->name, | ||
5021 | log_info, id, channel)); | ||
5022 | if (vtarget->raidVolume) { | ||
5023 | devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT | ||
5024 | "Skipping Raid Volume for inDMD\n", | ||
5025 | ioc->name)); | ||
5026 | } else { | ||
5027 | devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT | ||
5028 | "Setting device flag inDMD\n", | ||
5029 | ioc->name)); | ||
5030 | vtarget->inDMD = 1; | ||
5031 | } | ||
5032 | |||
5033 | } | ||
5034 | |||
5035 | } | ||
5036 | |||
4825 | break; | 5037 | break; |
4826 | } | 5038 | } |
4827 | case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE: | 5039 | case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE: |
@@ -4924,7 +5136,7 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
4924 | ioc->DoneCtx = mptsasDoneCtx; | 5136 | ioc->DoneCtx = mptsasDoneCtx; |
4925 | ioc->TaskCtx = mptsasTaskCtx; | 5137 | ioc->TaskCtx = mptsasTaskCtx; |
4926 | ioc->InternalCtx = mptsasInternalCtx; | 5138 | ioc->InternalCtx = mptsasInternalCtx; |
4927 | 5139 | ioc->schedule_target_reset = &mptsas_schedule_target_reset; | |
4928 | /* Added sanity check on readiness of the MPT adapter. | 5140 | /* Added sanity check on readiness of the MPT adapter. |
4929 | */ | 5141 | */ |
4930 | if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) { | 5142 | if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) { |
@@ -5154,14 +5366,20 @@ mptsas_init(void) | |||
5154 | sas_attach_transport(&mptsas_transport_functions); | 5366 | sas_attach_transport(&mptsas_transport_functions); |
5155 | if (!mptsas_transport_template) | 5367 | if (!mptsas_transport_template) |
5156 | return -ENODEV; | 5368 | return -ENODEV; |
5369 | mptsas_transport_template->eh_timed_out = mptsas_eh_timed_out; | ||
5157 | 5370 | ||
5158 | mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER); | 5371 | mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER, |
5159 | mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER); | 5372 | "mptscsih_io_done"); |
5373 | mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER, | ||
5374 | "mptscsih_taskmgmt_complete"); | ||
5160 | mptsasInternalCtx = | 5375 | mptsasInternalCtx = |
5161 | mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER); | 5376 | mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER, |
5162 | mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER); | 5377 | "mptscsih_scandv_complete"); |
5378 | mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER, | ||
5379 | "mptsas_mgmt_done"); | ||
5163 | mptsasDeviceResetCtx = | 5380 | mptsasDeviceResetCtx = |
5164 | mpt_register(mptsas_taskmgmt_complete, MPTSAS_DRIVER); | 5381 | mpt_register(mptsas_taskmgmt_complete, MPTSAS_DRIVER, |
5382 | "mptsas_taskmgmt_complete"); | ||
5165 | 5383 | ||
5166 | mpt_event_register(mptsasDoneCtx, mptsas_event_process); | 5384 | mpt_event_register(mptsasDoneCtx, mptsas_event_process); |
5167 | mpt_reset_register(mptsasDoneCtx, mptsas_ioc_reset); | 5385 | mpt_reset_register(mptsasDoneCtx, mptsas_ioc_reset); |
diff --git a/drivers/message/fusion/mptsas.h b/drivers/message/fusion/mptsas.h index 7b249edbda78..57e86ab77661 100644 --- a/drivers/message/fusion/mptsas.h +++ b/drivers/message/fusion/mptsas.h | |||
@@ -140,6 +140,7 @@ struct mptsas_devinfo { | |||
140 | u64 sas_address; /* WWN of this device, | 140 | u64 sas_address; /* WWN of this device, |
141 | SATA is assigned by HBA,expander */ | 141 | SATA is assigned by HBA,expander */ |
142 | u32 device_info; /* bitfield detailed info about this device */ | 142 | u32 device_info; /* bitfield detailed info about this device */ |
143 | u16 flags; /* sas device pg0 flags */ | ||
143 | }; | 144 | }; |
144 | 145 | ||
145 | /* | 146 | /* |
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index 5c53624e0e87..59b8f53d1ece 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c | |||
@@ -664,6 +664,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
664 | u32 log_info; | 664 | u32 log_info; |
665 | 665 | ||
666 | status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK; | 666 | status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK; |
667 | |||
667 | scsi_state = pScsiReply->SCSIState; | 668 | scsi_state = pScsiReply->SCSIState; |
668 | scsi_status = pScsiReply->SCSIStatus; | 669 | scsi_status = pScsiReply->SCSIStatus; |
669 | xfer_cnt = le32_to_cpu(pScsiReply->TransferCount); | 670 | xfer_cnt = le32_to_cpu(pScsiReply->TransferCount); |
@@ -738,13 +739,36 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
738 | 739 | ||
739 | case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */ | 740 | case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */ |
740 | if ( ioc->bus_type == SAS ) { | 741 | if ( ioc->bus_type == SAS ) { |
741 | u16 ioc_status = le16_to_cpu(pScsiReply->IOCStatus); | 742 | u16 ioc_status = |
742 | if (ioc_status & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { | 743 | le16_to_cpu(pScsiReply->IOCStatus); |
743 | if ((log_info & SAS_LOGINFO_MASK) | 744 | if ((ioc_status & |
744 | == SAS_LOGINFO_NEXUS_LOSS) { | 745 | MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) |
745 | sc->result = (DID_BUS_BUSY << 16); | 746 | && |
746 | break; | 747 | ((log_info & SAS_LOGINFO_MASK) == |
747 | } | 748 | SAS_LOGINFO_NEXUS_LOSS)) { |
749 | VirtDevice *vdevice = | ||
750 | sc->device->hostdata; | ||
751 | |||
752 | /* flag the device as being in | ||
753 | * device removal delay so we can | ||
754 | * notify the midlayer to hold off | ||
755 | * on timeout eh */ | ||
756 | if (vdevice && vdevice-> | ||
757 | vtarget && | ||
758 | vdevice->vtarget-> | ||
759 | raidVolume) | ||
760 | printk(KERN_INFO | ||
761 | "Skipping Raid Volume" | ||
762 | "for inDMD\n"); | ||
763 | else if (vdevice && | ||
764 | vdevice->vtarget) | ||
765 | vdevice->vtarget-> | ||
766 | inDMD = 1; | ||
767 | |||
768 | sc->result = | ||
769 | (DID_TRANSPORT_DISRUPTED | ||
770 | << 16); | ||
771 | break; | ||
748 | } | 772 | } |
749 | } else if (ioc->bus_type == FC) { | 773 | } else if (ioc->bus_type == FC) { |
750 | /* | 774 | /* |
@@ -1704,8 +1728,9 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, | |||
1704 | 1728 | ||
1705 | CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status) | 1729 | CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status) |
1706 | if (issue_hard_reset) { | 1730 | if (issue_hard_reset) { |
1707 | printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n", | 1731 | printk(MYIOC_s_WARN_FMT |
1708 | ioc->name, __func__); | 1732 | "Issuing Reset from %s!! doorbell=0x%08x\n", |
1733 | ioc->name, __func__, mpt_GetIocState(ioc, 0)); | ||
1709 | retval = mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP); | 1734 | retval = mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP); |
1710 | mpt_free_msg_frame(ioc, mf); | 1735 | mpt_free_msg_frame(ioc, mf); |
1711 | } | 1736 | } |
@@ -2132,6 +2157,8 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, | |||
2132 | mpt_clear_taskmgmt_in_progress_flag(ioc); | 2157 | mpt_clear_taskmgmt_in_progress_flag(ioc); |
2133 | ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING; | 2158 | ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING; |
2134 | complete(&ioc->taskmgmt_cmds.done); | 2159 | complete(&ioc->taskmgmt_cmds.done); |
2160 | if (ioc->bus_type == SAS) | ||
2161 | ioc->schedule_target_reset(ioc); | ||
2135 | return 1; | 2162 | return 1; |
2136 | } | 2163 | } |
2137 | return 0; | 2164 | return 0; |
@@ -2459,6 +2486,8 @@ mptscsih_slave_configure(struct scsi_device *sdev) | |||
2459 | ioc->name,sdev->tagged_supported, sdev->simple_tags, | 2486 | ioc->name,sdev->tagged_supported, sdev->simple_tags, |
2460 | sdev->ordered_tags)); | 2487 | sdev->ordered_tags)); |
2461 | 2488 | ||
2489 | blk_queue_dma_alignment (sdev->request_queue, 512 - 1); | ||
2490 | |||
2462 | return 0; | 2491 | return 0; |
2463 | } | 2492 | } |
2464 | 2493 | ||
@@ -3045,8 +3074,11 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io) | |||
3045 | goto out; | 3074 | goto out; |
3046 | } | 3075 | } |
3047 | if (!timeleft) { | 3076 | if (!timeleft) { |
3048 | printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n", | 3077 | printk(MYIOC_s_WARN_FMT |
3049 | ioc->name, __func__); | 3078 | "Issuing Reset from %s!! doorbell=0x%08xh" |
3079 | " cmd=0x%02x\n", | ||
3080 | ioc->name, __func__, mpt_GetIocState(ioc, 0), | ||
3081 | cmd); | ||
3050 | mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP); | 3082 | mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP); |
3051 | mpt_free_msg_frame(ioc, mf); | 3083 | mpt_free_msg_frame(ioc, mf); |
3052 | } | 3084 | } |
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index 1abaa5d01ae3..0e2803155ae2 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c | |||
@@ -1551,9 +1551,12 @@ mptspi_init(void) | |||
1551 | if (!mptspi_transport_template) | 1551 | if (!mptspi_transport_template) |
1552 | return -ENODEV; | 1552 | return -ENODEV; |
1553 | 1553 | ||
1554 | mptspiDoneCtx = mpt_register(mptscsih_io_done, MPTSPI_DRIVER); | 1554 | mptspiDoneCtx = mpt_register(mptscsih_io_done, MPTSPI_DRIVER, |
1555 | mptspiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSPI_DRIVER); | 1555 | "mptscsih_io_done"); |
1556 | mptspiInternalCtx = mpt_register(mptscsih_scandv_complete, MPTSPI_DRIVER); | 1556 | mptspiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSPI_DRIVER, |
1557 | "mptscsih_taskmgmt_complete"); | ||
1558 | mptspiInternalCtx = mpt_register(mptscsih_scandv_complete, | ||
1559 | MPTSPI_DRIVER, "mptscsih_scandv_complete"); | ||
1557 | 1560 | ||
1558 | mpt_event_register(mptspiDoneCtx, mptspi_event_process); | 1561 | mpt_event_register(mptspiDoneCtx, mptspi_event_process); |
1559 | mpt_reset_register(mptspiDoneCtx, mptspi_ioc_reset); | 1562 | mpt_reset_register(mptspiDoneCtx, mptspi_ioc_reset); |
diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c index 06c655c55587..a3970e56ae53 100644 --- a/drivers/message/i2o/exec-osm.c +++ b/drivers/message/i2o/exec-osm.c | |||
@@ -389,12 +389,16 @@ static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind) | |||
389 | dev = &c->pdev->dev; | 389 | dev = &c->pdev->dev; |
390 | 390 | ||
391 | if (i2o_dma_realloc(dev, &c->dlct, | 391 | if (i2o_dma_realloc(dev, &c->dlct, |
392 | le32_to_cpu(sb->expected_lct_size))) | 392 | le32_to_cpu(sb->expected_lct_size))) { |
393 | mutex_unlock(&c->lct_lock); | ||
393 | return -ENOMEM; | 394 | return -ENOMEM; |
395 | } | ||
394 | 396 | ||
395 | msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); | 397 | msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); |
396 | if (IS_ERR(msg)) | 398 | if (IS_ERR(msg)) { |
399 | mutex_unlock(&c->lct_lock); | ||
397 | return PTR_ERR(msg); | 400 | return PTR_ERR(msg); |
401 | } | ||
398 | 402 | ||
399 | msg->u.head[0] = cpu_to_le32(EIGHT_WORD_MSG_SIZE | SGL_OFFSET_6); | 403 | msg->u.head[0] = cpu_to_le32(EIGHT_WORD_MSG_SIZE | SGL_OFFSET_6); |
400 | msg->u.head[1] = cpu_to_le32(I2O_CMD_LCT_NOTIFY << 24 | HOST_TID << 12 | | 404 | msg->u.head[1] = cpu_to_le32(I2O_CMD_LCT_NOTIFY << 24 | HOST_TID << 12 | |
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c index fc593fbab696..f0f1e667000f 100644 --- a/drivers/message/i2o/i2o_block.c +++ b/drivers/message/i2o/i2o_block.c | |||
@@ -53,6 +53,7 @@ | |||
53 | #include <linux/module.h> | 53 | #include <linux/module.h> |
54 | #include <linux/slab.h> | 54 | #include <linux/slab.h> |
55 | #include <linux/i2o.h> | 55 | #include <linux/i2o.h> |
56 | #include <linux/smp_lock.h> | ||
56 | 57 | ||
57 | #include <linux/mempool.h> | 58 | #include <linux/mempool.h> |
58 | 59 | ||
@@ -577,6 +578,7 @@ static int i2o_block_open(struct block_device *bdev, fmode_t mode) | |||
577 | if (!dev->i2o_dev) | 578 | if (!dev->i2o_dev) |
578 | return -ENODEV; | 579 | return -ENODEV; |
579 | 580 | ||
581 | lock_kernel(); | ||
580 | if (dev->power > 0x1f) | 582 | if (dev->power > 0x1f) |
581 | i2o_block_device_power(dev, 0x02); | 583 | i2o_block_device_power(dev, 0x02); |
582 | 584 | ||
@@ -585,6 +587,7 @@ static int i2o_block_open(struct block_device *bdev, fmode_t mode) | |||
585 | i2o_block_device_lock(dev->i2o_dev, -1); | 587 | i2o_block_device_lock(dev->i2o_dev, -1); |
586 | 588 | ||
587 | osm_debug("Ready.\n"); | 589 | osm_debug("Ready.\n"); |
590 | unlock_kernel(); | ||
588 | 591 | ||
589 | return 0; | 592 | return 0; |
590 | }; | 593 | }; |
@@ -615,6 +618,7 @@ static int i2o_block_release(struct gendisk *disk, fmode_t mode) | |||
615 | if (!dev->i2o_dev) | 618 | if (!dev->i2o_dev) |
616 | return 0; | 619 | return 0; |
617 | 620 | ||
621 | lock_kernel(); | ||
618 | i2o_block_device_flush(dev->i2o_dev); | 622 | i2o_block_device_flush(dev->i2o_dev); |
619 | 623 | ||
620 | i2o_block_device_unlock(dev->i2o_dev, -1); | 624 | i2o_block_device_unlock(dev->i2o_dev, -1); |
@@ -625,6 +629,7 @@ static int i2o_block_release(struct gendisk *disk, fmode_t mode) | |||
625 | operation = 0x24; | 629 | operation = 0x24; |
626 | 630 | ||
627 | i2o_block_device_power(dev, operation); | 631 | i2o_block_device_power(dev, operation); |
632 | unlock_kernel(); | ||
628 | 633 | ||
629 | return 0; | 634 | return 0; |
630 | } | 635 | } |
@@ -652,30 +657,40 @@ static int i2o_block_ioctl(struct block_device *bdev, fmode_t mode, | |||
652 | { | 657 | { |
653 | struct gendisk *disk = bdev->bd_disk; | 658 | struct gendisk *disk = bdev->bd_disk; |
654 | struct i2o_block_device *dev = disk->private_data; | 659 | struct i2o_block_device *dev = disk->private_data; |
660 | int ret = -ENOTTY; | ||
655 | 661 | ||
656 | /* Anyone capable of this syscall can do *real bad* things */ | 662 | /* Anyone capable of this syscall can do *real bad* things */ |
657 | 663 | ||
658 | if (!capable(CAP_SYS_ADMIN)) | 664 | if (!capable(CAP_SYS_ADMIN)) |
659 | return -EPERM; | 665 | return -EPERM; |
660 | 666 | ||
667 | lock_kernel(); | ||
661 | switch (cmd) { | 668 | switch (cmd) { |
662 | case BLKI2OGRSTRAT: | 669 | case BLKI2OGRSTRAT: |
663 | return put_user(dev->rcache, (int __user *)arg); | 670 | ret = put_user(dev->rcache, (int __user *)arg); |
671 | break; | ||
664 | case BLKI2OGWSTRAT: | 672 | case BLKI2OGWSTRAT: |
665 | return put_user(dev->wcache, (int __user *)arg); | 673 | ret = put_user(dev->wcache, (int __user *)arg); |
674 | break; | ||
666 | case BLKI2OSRSTRAT: | 675 | case BLKI2OSRSTRAT: |
676 | ret = -EINVAL; | ||
667 | if (arg < 0 || arg > CACHE_SMARTFETCH) | 677 | if (arg < 0 || arg > CACHE_SMARTFETCH) |
668 | return -EINVAL; | 678 | break; |
669 | dev->rcache = arg; | 679 | dev->rcache = arg; |
680 | ret = 0; | ||
670 | break; | 681 | break; |
671 | case BLKI2OSWSTRAT: | 682 | case BLKI2OSWSTRAT: |
683 | ret = -EINVAL; | ||
672 | if (arg != 0 | 684 | if (arg != 0 |
673 | && (arg < CACHE_WRITETHROUGH || arg > CACHE_SMARTBACK)) | 685 | && (arg < CACHE_WRITETHROUGH || arg > CACHE_SMARTBACK)) |
674 | return -EINVAL; | 686 | break; |
675 | dev->wcache = arg; | 687 | dev->wcache = arg; |
688 | ret = 0; | ||
676 | break; | 689 | break; |
677 | } | 690 | } |
678 | return -ENOTTY; | 691 | unlock_kernel(); |
692 | |||
693 | return ret; | ||
679 | }; | 694 | }; |
680 | 695 | ||
681 | /** | 696 | /** |
@@ -712,7 +727,7 @@ static int i2o_block_transfer(struct request *req) | |||
712 | { | 727 | { |
713 | struct i2o_block_device *dev = req->rq_disk->private_data; | 728 | struct i2o_block_device *dev = req->rq_disk->private_data; |
714 | struct i2o_controller *c; | 729 | struct i2o_controller *c; |
715 | u32 tid = dev->i2o_dev->lct_data.tid; | 730 | u32 tid; |
716 | struct i2o_message *msg; | 731 | struct i2o_message *msg; |
717 | u32 *mptr; | 732 | u32 *mptr; |
718 | struct i2o_block_request *ireq = req->special; | 733 | struct i2o_block_request *ireq = req->special; |
@@ -728,6 +743,7 @@ static int i2o_block_transfer(struct request *req) | |||
728 | goto exit; | 743 | goto exit; |
729 | } | 744 | } |
730 | 745 | ||
746 | tid = dev->i2o_dev->lct_data.tid; | ||
731 | c = dev->i2o_dev->iop; | 747 | c = dev->i2o_dev->iop; |
732 | 748 | ||
733 | msg = i2o_msg_get(c); | 749 | msg = i2o_msg_get(c); |
@@ -883,7 +899,7 @@ static void i2o_block_request_fn(struct request_queue *q) | |||
883 | if (!req) | 899 | if (!req) |
884 | break; | 900 | break; |
885 | 901 | ||
886 | if (blk_fs_request(req)) { | 902 | if (req->cmd_type == REQ_TYPE_FS) { |
887 | struct i2o_block_delayed_request *dreq; | 903 | struct i2o_block_delayed_request *dreq; |
888 | struct i2o_block_request *ireq = req->special; | 904 | struct i2o_block_request *ireq = req->special; |
889 | unsigned int queue_depth; | 905 | unsigned int queue_depth; |
@@ -930,7 +946,8 @@ static const struct block_device_operations i2o_block_fops = { | |||
930 | .owner = THIS_MODULE, | 946 | .owner = THIS_MODULE, |
931 | .open = i2o_block_open, | 947 | .open = i2o_block_open, |
932 | .release = i2o_block_release, | 948 | .release = i2o_block_release, |
933 | .locked_ioctl = i2o_block_ioctl, | 949 | .ioctl = i2o_block_ioctl, |
950 | .compat_ioctl = i2o_block_ioctl, | ||
934 | .getgeo = i2o_block_getgeo, | 951 | .getgeo = i2o_block_getgeo, |
935 | .media_changed = i2o_block_media_changed | 952 | .media_changed = i2o_block_media_changed |
936 | }; | 953 | }; |
diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c index c4b117f5fb70..068ba0785bb4 100644 --- a/drivers/message/i2o/i2o_config.c +++ b/drivers/message/i2o/i2o_config.c | |||
@@ -111,11 +111,11 @@ static int i2o_cfg_gethrt(unsigned long arg) | |||
111 | 111 | ||
112 | len = 8 + ((hrt->entry_len * hrt->num_entries) << 2); | 112 | len = 8 + ((hrt->entry_len * hrt->num_entries) << 2); |
113 | 113 | ||
114 | /* We did a get user...so assuming mem is ok...is this bad? */ | 114 | if (put_user(len, kcmd.reslen)) |
115 | put_user(len, kcmd.reslen); | 115 | ret = -EFAULT; |
116 | if (len > reslen) | 116 | else if (len > reslen) |
117 | ret = -ENOBUFS; | 117 | ret = -ENOBUFS; |
118 | if (copy_to_user(kcmd.resbuf, (void *)hrt, len)) | 118 | else if (copy_to_user(kcmd.resbuf, (void *)hrt, len)) |
119 | ret = -EFAULT; | 119 | ret = -EFAULT; |
120 | 120 | ||
121 | return ret; | 121 | return ret; |
@@ -147,8 +147,9 @@ static int i2o_cfg_getlct(unsigned long arg) | |||
147 | lct = (i2o_lct *) c->lct; | 147 | lct = (i2o_lct *) c->lct; |
148 | 148 | ||
149 | len = (unsigned int)lct->table_size << 2; | 149 | len = (unsigned int)lct->table_size << 2; |
150 | put_user(len, kcmd.reslen); | 150 | if (put_user(len, kcmd.reslen)) |
151 | if (len > reslen) | 151 | ret = -EFAULT; |
152 | else if (len > reslen) | ||
152 | ret = -ENOBUFS; | 153 | ret = -ENOBUFS; |
153 | else if (copy_to_user(kcmd.resbuf, lct, len)) | 154 | else if (copy_to_user(kcmd.resbuf, lct, len)) |
154 | ret = -EFAULT; | 155 | ret = -EFAULT; |
@@ -208,8 +209,9 @@ static int i2o_cfg_parms(unsigned long arg, unsigned int type) | |||
208 | return -EAGAIN; | 209 | return -EAGAIN; |
209 | } | 210 | } |
210 | 211 | ||
211 | put_user(len, kcmd.reslen); | 212 | if (put_user(len, kcmd.reslen)) |
212 | if (len > reslen) | 213 | ret = -EFAULT; |
214 | else if (len > reslen) | ||
213 | ret = -ENOBUFS; | 215 | ret = -ENOBUFS; |
214 | else if (copy_to_user(kcmd.resbuf, res, len)) | 216 | else if (copy_to_user(kcmd.resbuf, res, len)) |
215 | ret = -EFAULT; | 217 | ret = -EFAULT; |
diff --git a/drivers/message/i2o/i2o_scsi.c b/drivers/message/i2o/i2o_scsi.c index 3d45817e6dcd..ea6b2197da8a 100644 --- a/drivers/message/i2o/i2o_scsi.c +++ b/drivers/message/i2o/i2o_scsi.c | |||
@@ -528,7 +528,6 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt, | |||
528 | * Do the incoming paperwork | 528 | * Do the incoming paperwork |
529 | */ | 529 | */ |
530 | i2o_dev = SCpnt->device->hostdata; | 530 | i2o_dev = SCpnt->device->hostdata; |
531 | c = i2o_dev->iop; | ||
532 | 531 | ||
533 | SCpnt->scsi_done = done; | 532 | SCpnt->scsi_done = done; |
534 | 533 | ||
@@ -538,7 +537,7 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt, | |||
538 | done(SCpnt); | 537 | done(SCpnt); |
539 | goto exit; | 538 | goto exit; |
540 | } | 539 | } |
541 | 540 | c = i2o_dev->iop; | |
542 | tid = i2o_dev->lct_data.tid; | 541 | tid = i2o_dev->lct_data.tid; |
543 | 542 | ||
544 | osm_debug("qcmd: Tid = %03x\n", tid); | 543 | osm_debug("qcmd: Tid = %03x\n", tid); |