diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/message/fusion | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/message/fusion')
-rw-r--r-- | drivers/message/fusion/mptbase.c | 13 | ||||
-rw-r--r-- | drivers/message/fusion/mptbase.h | 4 | ||||
-rw-r--r-- | drivers/message/fusion/mptctl.c | 9 | ||||
-rw-r--r-- | drivers/message/fusion/mptfc.c | 18 | ||||
-rw-r--r-- | drivers/message/fusion/mptlan.c | 1 | ||||
-rw-r--r-- | drivers/message/fusion/mptsas.c | 212 | ||||
-rw-r--r-- | drivers/message/fusion/mptscsih.c | 107 | ||||
-rw-r--r-- | drivers/message/fusion/mptscsih.h | 3 | ||||
-rw-r--r-- | drivers/message/fusion/mptspi.c | 1 |
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 | ||
129 | static 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]; | |||
146 | static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS]; | 144 | static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS]; |
147 | static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS]; | 145 | static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS]; |
148 | 146 | ||
147 | #ifdef CONFIG_PROC_FS | ||
148 | static 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 | ||
1079 | static void | ||
1080 | mptsas_block_io_sdev(struct scsi_device *sdev, void *data) | ||
1081 | { | ||
1082 | scsi_device_set_state(sdev, SDEV_BLOCK); | ||
1083 | } | ||
1084 | |||
1085 | static void | ||
1086 | mptsas_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 | ||
2705 | struct rep_manu_request{ | ||
2706 | u8 smp_frame_type; | ||
2707 | u8 function; | ||
2708 | u8 reserved; | ||
2709 | u8 request_length; | ||
2710 | }; | ||
2711 | |||
2712 | struct 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 | */ | ||
2742 | static int | ||
2743 | mptsas_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 | } | ||
2873 | out_free: | ||
2874 | if (data_out_dma) | ||
2875 | pci_free_consistent(ioc->pcidev, sz, data_out, data_out_dma); | ||
2876 | put_mf: | ||
2877 | if (mf) | ||
2878 | mpt_free_msg_frame(ioc, mf); | ||
2879 | out_unlock: | ||
2880 | CLEAR_MGMT_STATUS(ioc->sas_mgmt.status) | ||
2881 | mutex_unlock(&ioc->sas_mgmt.mutex); | ||
2882 | out: | ||
2883 | return ret; | ||
2884 | } | ||
2885 | |||
2689 | static void | 2886 | static void |
2690 | mptsas_parse_device_info(struct sas_identify *identify, | 2887 | mptsas_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 | */ |
2281 | int | 2364 | int |
2282 | mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth) | 2365 | mptscsih_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 | |||
128 | extern int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); | 128 | extern int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); |
129 | extern int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); | 129 | extern int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); |
130 | extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); | 130 | extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); |
131 | extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth); | 131 | extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth, |
132 | int reason); | ||
132 | extern u8 mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id); | 133 | extern u8 mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id); |
133 | extern int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id); | 134 | extern int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id); |
134 | extern struct device_attribute *mptscsih_host_attrs[]; | 135 | extern 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> |