aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/fusion
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/message/fusion')
-rw-r--r--drivers/message/fusion/mptbase.c13
-rw-r--r--drivers/message/fusion/mptbase.h4
-rw-r--r--drivers/message/fusion/mptctl.c9
-rw-r--r--drivers/message/fusion/mptfc.c18
-rw-r--r--drivers/message/fusion/mptlan.c1
-rw-r--r--drivers/message/fusion/mptsas.c212
-rw-r--r--drivers/message/fusion/mptscsih.c107
-rw-r--r--drivers/message/fusion/mptscsih.h3
-rw-r--r--drivers/message/fusion/mptspi.c1
9 files changed, 333 insertions, 35 deletions
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 610e914abe6c..5382b5a44aff 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -126,8 +126,6 @@ static int mfcounter = 0;
126 * Public data... 126 * Public data...
127 */ 127 */
128 128
129static struct proc_dir_entry *mpt_proc_root_dir;
130
131#define WHOINIT_UNKNOWN 0xAA 129#define WHOINIT_UNKNOWN 0xAA
132 130
133/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 131/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -146,6 +144,9 @@ static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
146static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS]; 144static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
147static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS]; 145static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
148 146
147#ifdef CONFIG_PROC_FS
148static struct proc_dir_entry *mpt_proc_root_dir;
149#endif
149 150
150/* 151/*
151 * Driver Callback Index's 152 * Driver Callback Index's
@@ -1587,7 +1588,7 @@ mpt_mapresources(MPT_ADAPTER *ioc)
1587{ 1588{
1588 u8 __iomem *mem; 1589 u8 __iomem *mem;
1589 int ii; 1590 int ii;
1590 unsigned long mem_phys; 1591 resource_size_t mem_phys;
1591 unsigned long port; 1592 unsigned long port;
1592 u32 msize; 1593 u32 msize;
1593 u32 psize; 1594 u32 psize;
@@ -1677,8 +1678,8 @@ mpt_mapresources(MPT_ADAPTER *ioc)
1677 return -EINVAL; 1678 return -EINVAL;
1678 } 1679 }
1679 ioc->memmap = mem; 1680 ioc->memmap = mem;
1680 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %lx\n", 1681 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %llx\n",
1681 ioc->name, mem, mem_phys)); 1682 ioc->name, mem, (unsigned long long)mem_phys));
1682 1683
1683 ioc->mem_phys = mem_phys; 1684 ioc->mem_phys = mem_phys;
1684 ioc->chip = (SYSIF_REGS __iomem *)mem; 1685 ioc->chip = (SYSIF_REGS __iomem *)mem;
@@ -4330,6 +4331,8 @@ initChainBuffers(MPT_ADAPTER *ioc)
4330 4331
4331 if (ioc->bus_type == SPI) 4332 if (ioc->bus_type == SPI)
4332 num_chain *= MPT_SCSI_CAN_QUEUE; 4333 num_chain *= MPT_SCSI_CAN_QUEUE;
4334 else if (ioc->bus_type == SAS)
4335 num_chain *= MPT_SAS_CAN_QUEUE;
4333 else 4336 else
4334 num_chain *= MPT_FC_CAN_QUEUE; 4337 num_chain *= MPT_FC_CAN_QUEUE;
4335 4338
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index 8dd4d219e433..9718c8f2e959 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.12" 79#define MPT_LINUX_VERSION_COMMON "3.04.14"
80#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.12" 80#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.14"
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) \
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index 9b2e2198aee9..caa8f568a41c 100644
--- a/drivers/message/fusion/mptctl.c
+++ b/drivers/message/fusion/mptctl.c
@@ -360,8 +360,8 @@ static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function)
360 u16 iocstatus; 360 u16 iocstatus;
361 361
362 /* bus reset is only good for SCSI IO, RAID PASSTHRU */ 362 /* bus reset is only good for SCSI IO, RAID PASSTHRU */
363 if (!(function == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) || 363 if (!(function == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH ||
364 (function == MPI_FUNCTION_SCSI_IO_REQUEST)) { 364 function == MPI_FUNCTION_SCSI_IO_REQUEST)) {
365 dtmprintk(ioc, printk(MYIOC_s_WARN_FMT 365 dtmprintk(ioc, printk(MYIOC_s_WARN_FMT
366 "TaskMgmt, not SCSI_IO!!\n", ioc->name)); 366 "TaskMgmt, not SCSI_IO!!\n", ioc->name));
367 return -EPERM; 367 return -EPERM;
@@ -621,11 +621,8 @@ __mptctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
621 */ 621 */
622 iocnumX = khdr.iocnum & 0xFF; 622 iocnumX = khdr.iocnum & 0xFF;
623 if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) || 623 if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
624 (iocp == NULL)) { 624 (iocp == NULL))
625 printk(KERN_DEBUG MYNAM "%s::mptctl_ioctl() @%d - ioc%d not found!\n",
626 __FILE__, __LINE__, iocnumX);
627 return -ENODEV; 625 return -ENODEV;
628 }
629 626
630 if (!iocp->active) { 627 if (!iocp->active) {
631 printk(KERN_DEBUG MYNAM "%s::mptctl_ioctl() @%d - Controller disabled.\n", 628 printk(KERN_DEBUG MYNAM "%s::mptctl_ioctl() @%d - Controller disabled.\n",
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index ebf6ae024da4..33f7256055b1 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -54,6 +54,7 @@
54#include <linux/reboot.h> /* notifier code */ 54#include <linux/reboot.h> /* notifier code */
55#include <linux/workqueue.h> 55#include <linux/workqueue.h>
56#include <linux/sort.h> 56#include <linux/sort.h>
57#include <linux/slab.h>
57 58
58#include <scsi/scsi.h> 59#include <scsi/scsi.h>
59#include <scsi/scsi_cmnd.h> 60#include <scsi/scsi_cmnd.h>
@@ -195,29 +196,34 @@ mptfc_block_error_handler(struct scsi_cmnd *SCpnt,
195 unsigned long flags; 196 unsigned long flags;
196 int ready; 197 int ready;
197 MPT_ADAPTER *ioc; 198 MPT_ADAPTER *ioc;
199 int loops = 40; /* seconds */
198 200
199 hd = shost_priv(SCpnt->device->host); 201 hd = shost_priv(SCpnt->device->host);
200 ioc = hd->ioc; 202 ioc = hd->ioc;
201 spin_lock_irqsave(shost->host_lock, flags); 203 spin_lock_irqsave(shost->host_lock, flags);
202 while ((ready = fc_remote_port_chkready(rport) >> 16) == DID_IMM_RETRY) { 204 while ((ready = fc_remote_port_chkready(rport) >> 16) == DID_IMM_RETRY
205 || (loops > 0 && ioc->active == 0)) {
203 spin_unlock_irqrestore(shost->host_lock, flags); 206 spin_unlock_irqrestore(shost->host_lock, flags);
204 dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT 207 dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
205 "mptfc_block_error_handler.%d: %d:%d, port status is " 208 "mptfc_block_error_handler.%d: %d:%d, port status is "
206 "DID_IMM_RETRY, deferring %s recovery.\n", 209 "%x, active flag %d, deferring %s recovery.\n",
207 ioc->name, ioc->sh->host_no, 210 ioc->name, ioc->sh->host_no,
208 SCpnt->device->id, SCpnt->device->lun, caller)); 211 SCpnt->device->id, SCpnt->device->lun,
212 ready, ioc->active, caller));
209 msleep(1000); 213 msleep(1000);
210 spin_lock_irqsave(shost->host_lock, flags); 214 spin_lock_irqsave(shost->host_lock, flags);
215 loops --;
211 } 216 }
212 spin_unlock_irqrestore(shost->host_lock, flags); 217 spin_unlock_irqrestore(shost->host_lock, flags);
213 218
214 if (ready == DID_NO_CONNECT || !SCpnt->device->hostdata) { 219 if (ready == DID_NO_CONNECT || !SCpnt->device->hostdata
220 || ioc->active == 0) {
215 dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT 221 dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
216 "%s.%d: %d:%d, failing recovery, " 222 "%s.%d: %d:%d, failing recovery, "
217 "port state %d, vdevice %p.\n", caller, 223 "port state %x, active %d, vdevice %p.\n", caller,
218 ioc->name, ioc->sh->host_no, 224 ioc->name, ioc->sh->host_no,
219 SCpnt->device->id, SCpnt->device->lun, ready, 225 SCpnt->device->id, SCpnt->device->lun, ready,
220 SCpnt->device->hostdata)); 226 ioc->active, SCpnt->device->hostdata));
221 return FAILED; 227 return FAILED;
222 } 228 }
223 dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT 229 dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c
index 34f3f36f819b..4fa9665cbe93 100644
--- a/drivers/message/fusion/mptlan.c
+++ b/drivers/message/fusion/mptlan.c
@@ -57,6 +57,7 @@
57#include <linux/module.h> 57#include <linux/module.h>
58#include <linux/fs.h> 58#include <linux/fs.h>
59#include <linux/sched.h> 59#include <linux/sched.h>
60#include <linux/slab.h>
60 61
61#define my_VERSION MPT_LINUX_VERSION_COMMON 62#define my_VERSION MPT_LINUX_VERSION_COMMON
62#define MYNAM "mptlan" 63#define MYNAM "mptlan"
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index 83873e3d0ce7..76687126b573 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -45,6 +45,7 @@
45 45
46#include <linux/module.h> 46#include <linux/module.h>
47#include <linux/kernel.h> 47#include <linux/kernel.h>
48#include <linux/slab.h>
48#include <linux/init.h> 49#include <linux/init.h>
49#include <linux/errno.h> 50#include <linux/errno.h>
50#include <linux/jiffies.h> 51#include <linux/jiffies.h>
@@ -1075,6 +1076,19 @@ mptsas_target_reset(MPT_ADAPTER *ioc, u8 channel, u8 id)
1075 return 0; 1076 return 0;
1076} 1077}
1077 1078
1079static void
1080mptsas_block_io_sdev(struct scsi_device *sdev, void *data)
1081{
1082 scsi_device_set_state(sdev, SDEV_BLOCK);
1083}
1084
1085static void
1086mptsas_block_io_starget(struct scsi_target *starget)
1087{
1088 if (starget)
1089 starget_for_each_device(starget, NULL, mptsas_block_io_sdev);
1090}
1091
1078/** 1092/**
1079 * mptsas_target_reset_queue 1093 * mptsas_target_reset_queue
1080 * 1094 *
@@ -1098,10 +1112,11 @@ mptsas_target_reset_queue(MPT_ADAPTER *ioc,
1098 id = sas_event_data->TargetID; 1112 id = sas_event_data->TargetID;
1099 channel = sas_event_data->Bus; 1113 channel = sas_event_data->Bus;
1100 1114
1101 if (!(vtarget = mptsas_find_vtarget(ioc, channel, id))) 1115 vtarget = mptsas_find_vtarget(ioc, channel, id);
1102 return; 1116 if (vtarget) {
1103 1117 mptsas_block_io_starget(vtarget->starget);
1104 vtarget->deleted = 1; /* block IO */ 1118 vtarget->deleted = 1; /* block IO */
1119 }
1105 1120
1106 target_reset_list = kzalloc(sizeof(struct mptsas_target_reset_event), 1121 target_reset_list = kzalloc(sizeof(struct mptsas_target_reset_event),
1107 GFP_ATOMIC); 1122 GFP_ATOMIC);
@@ -1868,7 +1883,8 @@ mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1868 if (ioc->sas_discovery_quiesce_io) 1883 if (ioc->sas_discovery_quiesce_io)
1869 return SCSI_MLQUEUE_HOST_BUSY; 1884 return SCSI_MLQUEUE_HOST_BUSY;
1870 1885
1871// scsi_print_command(SCpnt); 1886 if (ioc->debug_level & MPT_DEBUG_SCSI)
1887 scsi_print_command(SCpnt);
1872 1888
1873 return mptscsih_qcmd(SCpnt,done); 1889 return mptscsih_qcmd(SCpnt,done);
1874} 1890}
@@ -2686,6 +2702,187 @@ mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
2686 return error; 2702 return error;
2687} 2703}
2688 2704
2705struct rep_manu_request{
2706 u8 smp_frame_type;
2707 u8 function;
2708 u8 reserved;
2709 u8 request_length;
2710};
2711
2712struct rep_manu_reply{
2713 u8 smp_frame_type; /* 0x41 */
2714 u8 function; /* 0x01 */
2715 u8 function_result;
2716 u8 response_length;
2717 u16 expander_change_count;
2718 u8 reserved0[2];
2719 u8 sas_format:1;
2720 u8 reserved1:7;
2721 u8 reserved2[3];
2722 u8 vendor_id[SAS_EXPANDER_VENDOR_ID_LEN];
2723 u8 product_id[SAS_EXPANDER_PRODUCT_ID_LEN];
2724 u8 product_rev[SAS_EXPANDER_PRODUCT_REV_LEN];
2725 u8 component_vendor_id[SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN];
2726 u16 component_id;
2727 u8 component_revision_id;
2728 u8 reserved3;
2729 u8 vendor_specific[8];
2730};
2731
2732/**
2733 * mptsas_exp_repmanufacture_info -
2734 * @ioc: per adapter object
2735 * @sas_address: expander sas address
2736 * @edev: the sas_expander_device object
2737 *
2738 * Fills in the sas_expander_device object when SMP port is created.
2739 *
2740 * Returns 0 for success, non-zero for failure.
2741 */
2742static int
2743mptsas_exp_repmanufacture_info(MPT_ADAPTER *ioc,
2744 u64 sas_address, struct sas_expander_device *edev)
2745{
2746 MPT_FRAME_HDR *mf;
2747 SmpPassthroughRequest_t *smpreq;
2748 SmpPassthroughReply_t *smprep;
2749 struct rep_manu_reply *manufacture_reply;
2750 struct rep_manu_request *manufacture_request;
2751 int ret;
2752 int flagsLength;
2753 unsigned long timeleft;
2754 char *psge;
2755 unsigned long flags;
2756 void *data_out = NULL;
2757 dma_addr_t data_out_dma = 0;
2758 u32 sz;
2759
2760 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2761 if (ioc->ioc_reset_in_progress) {
2762 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2763 printk(MYIOC_s_INFO_FMT "%s: host reset in progress!\n",
2764 __func__, ioc->name);
2765 return -EFAULT;
2766 }
2767 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2768
2769 ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex);
2770 if (ret)
2771 goto out;
2772
2773 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
2774 if (!mf) {
2775 ret = -ENOMEM;
2776 goto out_unlock;
2777 }
2778
2779 smpreq = (SmpPassthroughRequest_t *)mf;
2780 memset(smpreq, 0, sizeof(*smpreq));
2781
2782 sz = sizeof(struct rep_manu_request) + sizeof(struct rep_manu_reply);
2783
2784 data_out = pci_alloc_consistent(ioc->pcidev, sz, &data_out_dma);
2785 if (!data_out) {
2786 printk(KERN_ERR "Memory allocation failure at %s:%d/%s()!\n",
2787 __FILE__, __LINE__, __func__);
2788 ret = -ENOMEM;
2789 goto put_mf;
2790 }
2791
2792 manufacture_request = data_out;
2793 manufacture_request->smp_frame_type = 0x40;
2794 manufacture_request->function = 1;
2795 manufacture_request->reserved = 0;
2796 manufacture_request->request_length = 0;
2797
2798 smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
2799 smpreq->PhysicalPort = 0xFF;
2800 *((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address);
2801 smpreq->RequestDataLength = sizeof(struct rep_manu_request);
2802
2803 psge = (char *)
2804 (((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4));
2805
2806 flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2807 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
2808 MPI_SGE_FLAGS_HOST_TO_IOC |
2809 MPI_SGE_FLAGS_END_OF_BUFFER;
2810 flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
2811 flagsLength |= sizeof(struct rep_manu_request);
2812
2813 ioc->add_sge(psge, flagsLength, data_out_dma);
2814 psge += ioc->SGE_size;
2815
2816 flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2817 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
2818 MPI_SGE_FLAGS_IOC_TO_HOST |
2819 MPI_SGE_FLAGS_END_OF_BUFFER;
2820 flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
2821 flagsLength |= sizeof(struct rep_manu_reply);
2822 ioc->add_sge(psge, flagsLength, data_out_dma +
2823 sizeof(struct rep_manu_request));
2824
2825 INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
2826 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
2827
2828 timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
2829 if (!(ioc->sas_mgmt.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2830 ret = -ETIME;
2831 mpt_free_msg_frame(ioc, mf);
2832 mf = NULL;
2833 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET)
2834 goto out_free;
2835 if (!timeleft)
2836 mpt_HardResetHandler(ioc, CAN_SLEEP);
2837 goto out_free;
2838 }
2839
2840 mf = NULL;
2841
2842 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_RF_VALID) {
2843 u8 *tmp;
2844
2845 smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
2846 if (le16_to_cpu(smprep->ResponseDataLength) !=
2847 sizeof(struct rep_manu_reply))
2848 goto out_free;
2849
2850 manufacture_reply = data_out + sizeof(struct rep_manu_request);
2851 strncpy(edev->vendor_id, manufacture_reply->vendor_id,
2852 SAS_EXPANDER_VENDOR_ID_LEN);
2853 strncpy(edev->product_id, manufacture_reply->product_id,
2854 SAS_EXPANDER_PRODUCT_ID_LEN);
2855 strncpy(edev->product_rev, manufacture_reply->product_rev,
2856 SAS_EXPANDER_PRODUCT_REV_LEN);
2857 edev->level = manufacture_reply->sas_format;
2858 if (manufacture_reply->sas_format) {
2859 strncpy(edev->component_vendor_id,
2860 manufacture_reply->component_vendor_id,
2861 SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN);
2862 tmp = (u8 *)&manufacture_reply->component_id;
2863 edev->component_id = tmp[0] << 8 | tmp[1];
2864 edev->component_revision_id =
2865 manufacture_reply->component_revision_id;
2866 }
2867 } else {
2868 printk(MYIOC_s_ERR_FMT
2869 "%s: smp passthru reply failed to be returned\n",
2870 ioc->name, __func__);
2871 ret = -ENXIO;
2872 }
2873out_free:
2874 if (data_out_dma)
2875 pci_free_consistent(ioc->pcidev, sz, data_out, data_out_dma);
2876put_mf:
2877 if (mf)
2878 mpt_free_msg_frame(ioc, mf);
2879out_unlock:
2880 CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
2881 mutex_unlock(&ioc->sas_mgmt.mutex);
2882out:
2883 return ret;
2884 }
2885
2689static void 2886static void
2690mptsas_parse_device_info(struct sas_identify *identify, 2887mptsas_parse_device_info(struct sas_identify *identify,
2691 struct mptsas_devinfo *device_info) 2888 struct mptsas_devinfo *device_info)
@@ -2967,6 +3164,11 @@ static int mptsas_probe_one_phy(struct device *dev,
2967 goto out; 3164 goto out;
2968 } 3165 }
2969 mptsas_set_rphy(ioc, phy_info, rphy); 3166 mptsas_set_rphy(ioc, phy_info, rphy);
3167 if (identify.device_type == SAS_EDGE_EXPANDER_DEVICE ||
3168 identify.device_type == SAS_FANOUT_EXPANDER_DEVICE)
3169 mptsas_exp_repmanufacture_info(ioc,
3170 identify.sas_address,
3171 rphy_to_expander_device(rphy));
2970 } 3172 }
2971 3173
2972 out: 3174 out:
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index c29578614504..6796597dcee0 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -46,6 +46,7 @@
46 46
47#include <linux/module.h> 47#include <linux/module.h>
48#include <linux/kernel.h> 48#include <linux/kernel.h>
49#include <linux/slab.h>
49#include <linux/init.h> 50#include <linux/init.h>
50#include <linux/errno.h> 51#include <linux/errno.h>
51#include <linux/kdev_t.h> 52#include <linux/kdev_t.h>
@@ -792,11 +793,36 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
792 * precedence! 793 * precedence!
793 */ 794 */
794 sc->result = (DID_OK << 16) | scsi_status; 795 sc->result = (DID_OK << 16) | scsi_status;
795 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) { 796 if (!(scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)) {
796 /* Have already saved the status and sense data 797
798 /*
799 * For an Errata on LSI53C1030
800 * When the length of request data
801 * and transfer data are different
802 * with result of command (READ or VERIFY),
803 * DID_SOFT_ERROR is set.
797 */ 804 */
798 ; 805 if (ioc->bus_type == SPI) {
799 } else { 806 if (pScsiReq->CDB[0] == READ_6 ||
807 pScsiReq->CDB[0] == READ_10 ||
808 pScsiReq->CDB[0] == READ_12 ||
809 pScsiReq->CDB[0] == READ_16 ||
810 pScsiReq->CDB[0] == VERIFY ||
811 pScsiReq->CDB[0] == VERIFY_16) {
812 if (scsi_bufflen(sc) !=
813 xfer_cnt) {
814 sc->result =
815 DID_SOFT_ERROR << 16;
816 printk(KERN_WARNING "Errata"
817 "on LSI53C1030 occurred."
818 "sc->req_bufflen=0x%02x,"
819 "xfer_cnt=0x%02x\n",
820 scsi_bufflen(sc),
821 xfer_cnt);
822 }
823 }
824 }
825
800 if (xfer_cnt < sc->underflow) { 826 if (xfer_cnt < sc->underflow) {
801 if (scsi_status == SAM_STAT_BUSY) 827 if (scsi_status == SAM_STAT_BUSY)
802 sc->result = SAM_STAT_BUSY; 828 sc->result = SAM_STAT_BUSY;
@@ -835,7 +861,58 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
835 sc->result = (DID_OK << 16) | scsi_status; 861 sc->result = (DID_OK << 16) | scsi_status;
836 if (scsi_state == 0) { 862 if (scsi_state == 0) {
837 ; 863 ;
838 } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) { 864 } else if (scsi_state &
865 MPI_SCSI_STATE_AUTOSENSE_VALID) {
866
867 /*
868 * For potential trouble on LSI53C1030.
869 * (date:2007.xx.)
870 * It is checked whether the length of
871 * request data is equal to
872 * the length of transfer and residual.
873 * MEDIUM_ERROR is set by incorrect data.
874 */
875 if ((ioc->bus_type == SPI) &&
876 (sc->sense_buffer[2] & 0x20)) {
877 u32 difftransfer;
878 difftransfer =
879 sc->sense_buffer[3] << 24 |
880 sc->sense_buffer[4] << 16 |
881 sc->sense_buffer[5] << 8 |
882 sc->sense_buffer[6];
883 if (((sc->sense_buffer[3] & 0x80) ==
884 0x80) && (scsi_bufflen(sc)
885 != xfer_cnt)) {
886 sc->sense_buffer[2] =
887 MEDIUM_ERROR;
888 sc->sense_buffer[12] = 0xff;
889 sc->sense_buffer[13] = 0xff;
890 printk(KERN_WARNING"Errata"
891 "on LSI53C1030 occurred."
892 "sc->req_bufflen=0x%02x,"
893 "xfer_cnt=0x%02x\n" ,
894 scsi_bufflen(sc),
895 xfer_cnt);
896 }
897 if (((sc->sense_buffer[3] & 0x80)
898 != 0x80) &&
899 (scsi_bufflen(sc) !=
900 xfer_cnt + difftransfer)) {
901 sc->sense_buffer[2] =
902 MEDIUM_ERROR;
903 sc->sense_buffer[12] = 0xff;
904 sc->sense_buffer[13] = 0xff;
905 printk(KERN_WARNING
906 "Errata on LSI53C1030 occurred"
907 "sc->req_bufflen=0x%02x,"
908 " xfer_cnt=0x%02x,"
909 "difftransfer=0x%02x\n",
910 scsi_bufflen(sc),
911 xfer_cnt,
912 difftransfer);
913 }
914 }
915
839 /* 916 /*
840 * If running against circa 200003dd 909 MPT f/w, 917 * If running against circa 200003dd 909 MPT f/w,
841 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL 918 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
@@ -1362,9 +1439,14 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1362 && (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES) 1439 && (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
1363 && (SCpnt->device->tagged_supported)) { 1440 && (SCpnt->device->tagged_supported)) {
1364 scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ; 1441 scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1365 } else { 1442 if (SCpnt->request && SCpnt->request->ioprio) {
1443 if (((SCpnt->request->ioprio & 0x7) == 1) ||
1444 !(SCpnt->request->ioprio & 0x7))
1445 scsictl |= MPI_SCSIIO_CONTROL_HEADOFQ;
1446 }
1447 } else
1366 scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED; 1448 scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1367 } 1449
1368 1450
1369 /* Use the above information to set up the message frame 1451 /* Use the above information to set up the message frame
1370 */ 1452 */
@@ -1720,7 +1802,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
1720 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "task abort: " 1802 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "task abort: "
1721 "Command not in the active list! (sc=%p)\n", ioc->name, 1803 "Command not in the active list! (sc=%p)\n", ioc->name,
1722 SCpnt)); 1804 SCpnt));
1723 retval = 0; 1805 retval = SUCCESS;
1724 goto out; 1806 goto out;
1725 } 1807 }
1726 1808
@@ -2275,11 +2357,12 @@ mptscsih_slave_destroy(struct scsi_device *sdev)
2275 * mptscsih_change_queue_depth - This function will set a devices queue depth 2357 * mptscsih_change_queue_depth - This function will set a devices queue depth
2276 * @sdev: per scsi_device pointer 2358 * @sdev: per scsi_device pointer
2277 * @qdepth: requested queue depth 2359 * @qdepth: requested queue depth
2360 * @reason: calling context
2278 * 2361 *
2279 * Adding support for new 'change_queue_depth' api. 2362 * Adding support for new 'change_queue_depth' api.
2280*/ 2363*/
2281int 2364int
2282mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth) 2365mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
2283{ 2366{
2284 MPT_SCSI_HOST *hd = shost_priv(sdev->host); 2367 MPT_SCSI_HOST *hd = shost_priv(sdev->host);
2285 VirtTarget *vtarget; 2368 VirtTarget *vtarget;
@@ -2291,6 +2374,9 @@ mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
2291 starget = scsi_target(sdev); 2374 starget = scsi_target(sdev);
2292 vtarget = starget->hostdata; 2375 vtarget = starget->hostdata;
2293 2376
2377 if (reason != SCSI_QDEPTH_DEFAULT)
2378 return -EOPNOTSUPP;
2379
2294 if (ioc->bus_type == SPI) { 2380 if (ioc->bus_type == SPI) {
2295 if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)) 2381 if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2296 max_depth = 1; 2382 max_depth = 1;
@@ -2357,7 +2443,8 @@ mptscsih_slave_configure(struct scsi_device *sdev)
2357 ioc->name, vtarget->negoFlags, vtarget->maxOffset, 2443 ioc->name, vtarget->negoFlags, vtarget->maxOffset,
2358 vtarget->minSyncFactor)); 2444 vtarget->minSyncFactor));
2359 2445
2360 mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH); 2446 mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH,
2447 SCSI_QDEPTH_DEFAULT);
2361 dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2448 dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2362 "tagged %d, simple %d, ordered %d\n", 2449 "tagged %d, simple %d, ordered %d\n",
2363 ioc->name,sdev->tagged_supported, sdev->simple_tags, 2450 ioc->name,sdev->tagged_supported, sdev->simple_tags,
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
index e0b33e04a33b..45a5ff3eff61 100644
--- a/drivers/message/fusion/mptscsih.h
+++ b/drivers/message/fusion/mptscsih.h
@@ -128,7 +128,8 @@ extern int mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_F
128extern int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); 128extern int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
129extern int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); 129extern int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
130extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); 130extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
131extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth); 131extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth,
132 int reason);
132extern u8 mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id); 133extern u8 mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id);
133extern int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id); 134extern int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id);
134extern struct device_attribute *mptscsih_host_attrs[]; 135extern struct device_attribute *mptscsih_host_attrs[];
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c
index 69f4257419b5..e44365193fdf 100644
--- a/drivers/message/fusion/mptspi.c
+++ b/drivers/message/fusion/mptspi.c
@@ -46,6 +46,7 @@
46 46
47#include <linux/module.h> 47#include <linux/module.h>
48#include <linux/kernel.h> 48#include <linux/kernel.h>
49#include <linux/slab.h>
49#include <linux/init.h> 50#include <linux/init.h>
50#include <linux/errno.h> 51#include <linux/errno.h>
51#include <linux/kdev_t.h> 52#include <linux/kdev_t.h>