aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/message')
-rw-r--r--drivers/message/fusion/mptbase.c291
-rw-r--r--drivers/message/fusion/mptbase.h38
-rw-r--r--drivers/message/fusion/mptctl.c38
-rw-r--r--drivers/message/fusion/mptfc.c9
-rw-r--r--drivers/message/fusion/mptlan.c4
-rw-r--r--drivers/message/fusion/mptsas.c278
-rw-r--r--drivers/message/fusion/mptsas.h1
-rw-r--r--drivers/message/fusion/mptscsih.c54
-rw-r--r--drivers/message/fusion/mptspi.c9
-rw-r--r--drivers/message/i2o/exec-osm.c8
-rw-r--r--drivers/message/i2o/i2o_block.c33
-rw-r--r--drivers/message/i2o/i2o_config.c18
-rw-r--r--drivers/message/i2o/i2o_scsi.c3
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
119static char MptCallbacksName[MPT_MAX_PROTOCOL_DRIVERS][50];
118 120
119#ifdef MFCNT 121#ifdef MFCNT
120static int mfcounter = 0; 122static int mfcounter = 0;
@@ -199,12 +201,9 @@ static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_valu
199static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init); 201static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
200 202
201#ifdef CONFIG_PROC_FS 203#ifdef CONFIG_PROC_FS
202static int procmpt_summary_read(char *buf, char **start, off_t offset, 204static const struct file_operations mpt_summary_proc_fops;
203 int request, int *eof, void *data); 205static const struct file_operations mpt_version_proc_fops;
204static int procmpt_version_read(char *buf, char **start, off_t offset, 206static const struct file_operations mpt_iocinfo_proc_fops;
205 int request, int *eof, void *data);
206static int procmpt_iocinfo_read(char *buf, char **start, off_t offset,
207 int request, int *eof, void *data);
208#endif 207#endif
209static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc); 208static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
210 209
@@ -213,7 +212,7 @@ static int ProcessEventNotification(MPT_ADAPTER *ioc,
213static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf); 212static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
214static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info); 213static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
215static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info); 214static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
216static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info); 215static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info , u8 cb_idx);
217static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc); 216static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
218static void mpt_inactive_raid_list_free(MPT_ADAPTER *ioc); 217static 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 */
646u8 645u8
647mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass) 646mpt_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)
6537static int 6536static int
6538procmpt_create(void) 6537procmpt_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 */
6584static int 6566static void seq_mpt_print_ioc_summary(MPT_ADAPTER *ioc, struct seq_file *m, int showlan);
6585procmpt_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; 6568static 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); 6583static 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/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6588static 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 6596static int mpt_version_proc_show(struct seq_file *m, void *v)
6624 *
6625 * Returns number of characters written to process performing the read.
6626 */
6627static int
6628procmpt_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/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6638static 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 */
6683static int
6684procmpt_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
6643static 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
6651static 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
6732static 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
6737static 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
6810static 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 **/
7999static void 8010static void
8000mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info) 8011mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info, u8 cb_idx)
8001{ 8012{
8002union loginfo_type { 8013union 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 */
423typedef 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) \
432do { \
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
580typedef void (*MPT_ADD_SGE)(void *pAddr, u32 flagslength, dma_addr_t dma_addr); 557typedef void (*MPT_ADD_SGE)(void *pAddr, u32 flagslength, dma_addr_t dma_addr);
581typedef void (*MPT_ADD_CHAIN)(void *pAddr, u8 next, u16 length, 558typedef void (*MPT_ADD_CHAIN)(void *pAddr, u8 next, u16 length,
582 dma_addr_t dma_addr); 559 dma_addr_t dma_addr);
560typedef 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);
922extern int mpt_suspend(struct pci_dev *pdev, pm_message_t state); 901extern int mpt_suspend(struct pci_dev *pdev, pm_message_t state);
923extern int mpt_resume(struct pci_dev *pdev); 902extern int mpt_resume(struct pci_dev *pdev);
924#endif 903#endif
925extern u8 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass); 904extern u8 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass,
905 char *func_name);
926extern void mpt_deregister(u8 cb_idx); 906extern void mpt_deregister(u8 cb_idx);
927extern int mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc); 907extern int mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc);
928extern void mpt_event_deregister(u8 cb_idx); 908extern 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);
126static void mptsas_broadcast_primative_work(struct fw_event_work *fw_event); 127static void mptsas_broadcast_primative_work(struct fw_event_work *fw_event);
127static void mptsas_handle_queue_full_event(struct fw_event_work *fw_event); 128static void mptsas_handle_queue_full_event(struct fw_event_work *fw_event);
128static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id); 129static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id);
130void mptsas_schedule_target_reset(void *ioc);
129 131
130static void mptsas_print_phy_data(MPT_ADAPTER *ioc, 132static 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
1152void
1153mptsas_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 **/
1923static 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
1954done:
1955 return rc;
1956}
1957
1892 1958
1893static struct scsi_host_template mptsas_driver_template = { 1959static 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);