aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-02-28 22:23:06 -0500
committerDavid S. Miller <davem@davemloft.net>2010-02-28 22:23:06 -0500
commit47871889c601d8199c51a4086f77eebd77c29b0b (patch)
tree40cdcac3bff0ee40cc33dcca61d0577cdf965f77 /drivers/message
parentc16cc0b464b8876cfd57ce1c1dbcb6f9a6a0bce3 (diff)
parent30ff056c42c665b9ea535d8515890857ae382540 (diff)
Merge branch 'master' of /home/davem/src/GIT/linux-2.6/
Conflicts: drivers/firmware/iscsi_ibft.c
Diffstat (limited to 'drivers/message')
-rw-r--r--drivers/message/fusion/mptbase.c5
-rw-r--r--drivers/message/fusion/mptbase.h4
-rw-r--r--drivers/message/fusion/mptctl.c4
-rw-r--r--drivers/message/fusion/mptfc.c17
-rw-r--r--drivers/message/fusion/mptsas.c211
-rw-r--r--drivers/message/fusion/mptscsih.c9
6 files changed, 231 insertions, 19 deletions
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 44d2037e9e56..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
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index b4948671eb92..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.13" 79#define MPT_LINUX_VERSION_COMMON "3.04.14"
80#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.13" 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 352acd05c46b..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;
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index ebf6ae024da4..612ab3c51a6b 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -195,29 +195,34 @@ mptfc_block_error_handler(struct scsi_cmnd *SCpnt,
195 unsigned long flags; 195 unsigned long flags;
196 int ready; 196 int ready;
197 MPT_ADAPTER *ioc; 197 MPT_ADAPTER *ioc;
198 int loops = 40; /* seconds */
198 199
199 hd = shost_priv(SCpnt->device->host); 200 hd = shost_priv(SCpnt->device->host);
200 ioc = hd->ioc; 201 ioc = hd->ioc;
201 spin_lock_irqsave(shost->host_lock, flags); 202 spin_lock_irqsave(shost->host_lock, flags);
202 while ((ready = fc_remote_port_chkready(rport) >> 16) == DID_IMM_RETRY) { 203 while ((ready = fc_remote_port_chkready(rport) >> 16) == DID_IMM_RETRY
204 || (loops > 0 && ioc->active == 0)) {
203 spin_unlock_irqrestore(shost->host_lock, flags); 205 spin_unlock_irqrestore(shost->host_lock, flags);
204 dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT 206 dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
205 "mptfc_block_error_handler.%d: %d:%d, port status is " 207 "mptfc_block_error_handler.%d: %d:%d, port status is "
206 "DID_IMM_RETRY, deferring %s recovery.\n", 208 "%x, active flag %d, deferring %s recovery.\n",
207 ioc->name, ioc->sh->host_no, 209 ioc->name, ioc->sh->host_no,
208 SCpnt->device->id, SCpnt->device->lun, caller)); 210 SCpnt->device->id, SCpnt->device->lun,
211 ready, ioc->active, caller));
209 msleep(1000); 212 msleep(1000);
210 spin_lock_irqsave(shost->host_lock, flags); 213 spin_lock_irqsave(shost->host_lock, flags);
214 loops --;
211 } 215 }
212 spin_unlock_irqrestore(shost->host_lock, flags); 216 spin_unlock_irqrestore(shost->host_lock, flags);
213 217
214 if (ready == DID_NO_CONNECT || !SCpnt->device->hostdata) { 218 if (ready == DID_NO_CONNECT || !SCpnt->device->hostdata
219 || ioc->active == 0) {
215 dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT 220 dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
216 "%s.%d: %d:%d, failing recovery, " 221 "%s.%d: %d:%d, failing recovery, "
217 "port state %d, vdevice %p.\n", caller, 222 "port state %x, active %d, vdevice %p.\n", caller,
218 ioc->name, ioc->sh->host_no, 223 ioc->name, ioc->sh->host_no,
219 SCpnt->device->id, SCpnt->device->lun, ready, 224 SCpnt->device->id, SCpnt->device->lun, ready,
220 SCpnt->device->hostdata)); 225 ioc->active, SCpnt->device->hostdata));
221 return FAILED; 226 return FAILED;
222 } 227 }
223 dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT 228 dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index 83873e3d0ce7..c20bbe45da82 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -1075,6 +1075,19 @@ mptsas_target_reset(MPT_ADAPTER *ioc, u8 channel, u8 id)
1075 return 0; 1075 return 0;
1076} 1076}
1077 1077
1078static void
1079mptsas_block_io_sdev(struct scsi_device *sdev, void *data)
1080{
1081 scsi_device_set_state(sdev, SDEV_BLOCK);
1082}
1083
1084static void
1085mptsas_block_io_starget(struct scsi_target *starget)
1086{
1087 if (starget)
1088 starget_for_each_device(starget, NULL, mptsas_block_io_sdev);
1089}
1090
1078/** 1091/**
1079 * mptsas_target_reset_queue 1092 * mptsas_target_reset_queue
1080 * 1093 *
@@ -1098,10 +1111,11 @@ mptsas_target_reset_queue(MPT_ADAPTER *ioc,
1098 id = sas_event_data->TargetID; 1111 id = sas_event_data->TargetID;
1099 channel = sas_event_data->Bus; 1112 channel = sas_event_data->Bus;
1100 1113
1101 if (!(vtarget = mptsas_find_vtarget(ioc, channel, id))) 1114 vtarget = mptsas_find_vtarget(ioc, channel, id);
1102 return; 1115 if (vtarget) {
1103 1116 mptsas_block_io_starget(vtarget->starget);
1104 vtarget->deleted = 1; /* block IO */ 1117 vtarget->deleted = 1; /* block IO */
1118 }
1105 1119
1106 target_reset_list = kzalloc(sizeof(struct mptsas_target_reset_event), 1120 target_reset_list = kzalloc(sizeof(struct mptsas_target_reset_event),
1107 GFP_ATOMIC); 1121 GFP_ATOMIC);
@@ -1868,7 +1882,8 @@ mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1868 if (ioc->sas_discovery_quiesce_io) 1882 if (ioc->sas_discovery_quiesce_io)
1869 return SCSI_MLQUEUE_HOST_BUSY; 1883 return SCSI_MLQUEUE_HOST_BUSY;
1870 1884
1871// scsi_print_command(SCpnt); 1885 if (ioc->debug_level & MPT_DEBUG_SCSI)
1886 scsi_print_command(SCpnt);
1872 1887
1873 return mptscsih_qcmd(SCpnt,done); 1888 return mptscsih_qcmd(SCpnt,done);
1874} 1889}
@@ -2686,6 +2701,187 @@ mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
2686 return error; 2701 return error;
2687} 2702}
2688 2703
2704struct rep_manu_request{
2705 u8 smp_frame_type;
2706 u8 function;
2707 u8 reserved;
2708 u8 request_length;
2709};
2710
2711struct rep_manu_reply{
2712 u8 smp_frame_type; /* 0x41 */
2713 u8 function; /* 0x01 */
2714 u8 function_result;
2715 u8 response_length;
2716 u16 expander_change_count;
2717 u8 reserved0[2];
2718 u8 sas_format:1;
2719 u8 reserved1:7;
2720 u8 reserved2[3];
2721 u8 vendor_id[SAS_EXPANDER_VENDOR_ID_LEN];
2722 u8 product_id[SAS_EXPANDER_PRODUCT_ID_LEN];
2723 u8 product_rev[SAS_EXPANDER_PRODUCT_REV_LEN];
2724 u8 component_vendor_id[SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN];
2725 u16 component_id;
2726 u8 component_revision_id;
2727 u8 reserved3;
2728 u8 vendor_specific[8];
2729};
2730
2731/**
2732 * mptsas_exp_repmanufacture_info -
2733 * @ioc: per adapter object
2734 * @sas_address: expander sas address
2735 * @edev: the sas_expander_device object
2736 *
2737 * Fills in the sas_expander_device object when SMP port is created.
2738 *
2739 * Returns 0 for success, non-zero for failure.
2740 */
2741static int
2742mptsas_exp_repmanufacture_info(MPT_ADAPTER *ioc,
2743 u64 sas_address, struct sas_expander_device *edev)
2744{
2745 MPT_FRAME_HDR *mf;
2746 SmpPassthroughRequest_t *smpreq;
2747 SmpPassthroughReply_t *smprep;
2748 struct rep_manu_reply *manufacture_reply;
2749 struct rep_manu_request *manufacture_request;
2750 int ret;
2751 int flagsLength;
2752 unsigned long timeleft;
2753 char *psge;
2754 unsigned long flags;
2755 void *data_out = NULL;
2756 dma_addr_t data_out_dma = 0;
2757 u32 sz;
2758
2759 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2760 if (ioc->ioc_reset_in_progress) {
2761 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2762 printk(MYIOC_s_INFO_FMT "%s: host reset in progress!\n",
2763 __func__, ioc->name);
2764 return -EFAULT;
2765 }
2766 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2767
2768 ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex);
2769 if (ret)
2770 goto out;
2771
2772 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
2773 if (!mf) {
2774 ret = -ENOMEM;
2775 goto out_unlock;
2776 }
2777
2778 smpreq = (SmpPassthroughRequest_t *)mf;
2779 memset(smpreq, 0, sizeof(*smpreq));
2780
2781 sz = sizeof(struct rep_manu_request) + sizeof(struct rep_manu_reply);
2782
2783 data_out = pci_alloc_consistent(ioc->pcidev, sz, &data_out_dma);
2784 if (!data_out) {
2785 printk(KERN_ERR "Memory allocation failure at %s:%d/%s()!\n",
2786 __FILE__, __LINE__, __func__);
2787 ret = -ENOMEM;
2788 goto put_mf;
2789 }
2790
2791 manufacture_request = data_out;
2792 manufacture_request->smp_frame_type = 0x40;
2793 manufacture_request->function = 1;
2794 manufacture_request->reserved = 0;
2795 manufacture_request->request_length = 0;
2796
2797 smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
2798 smpreq->PhysicalPort = 0xFF;
2799 *((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address);
2800 smpreq->RequestDataLength = sizeof(struct rep_manu_request);
2801
2802 psge = (char *)
2803 (((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4));
2804
2805 flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2806 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
2807 MPI_SGE_FLAGS_HOST_TO_IOC |
2808 MPI_SGE_FLAGS_END_OF_BUFFER;
2809 flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
2810 flagsLength |= sizeof(struct rep_manu_request);
2811
2812 ioc->add_sge(psge, flagsLength, data_out_dma);
2813 psge += ioc->SGE_size;
2814
2815 flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2816 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
2817 MPI_SGE_FLAGS_IOC_TO_HOST |
2818 MPI_SGE_FLAGS_END_OF_BUFFER;
2819 flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
2820 flagsLength |= sizeof(struct rep_manu_reply);
2821 ioc->add_sge(psge, flagsLength, data_out_dma +
2822 sizeof(struct rep_manu_request));
2823
2824 INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
2825 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
2826
2827 timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
2828 if (!(ioc->sas_mgmt.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2829 ret = -ETIME;
2830 mpt_free_msg_frame(ioc, mf);
2831 mf = NULL;
2832 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET)
2833 goto out_free;
2834 if (!timeleft)
2835 mpt_HardResetHandler(ioc, CAN_SLEEP);
2836 goto out_free;
2837 }
2838
2839 mf = NULL;
2840
2841 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_RF_VALID) {
2842 u8 *tmp;
2843
2844 smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
2845 if (le16_to_cpu(smprep->ResponseDataLength) !=
2846 sizeof(struct rep_manu_reply))
2847 goto out_free;
2848
2849 manufacture_reply = data_out + sizeof(struct rep_manu_request);
2850 strncpy(edev->vendor_id, manufacture_reply->vendor_id,
2851 SAS_EXPANDER_VENDOR_ID_LEN);
2852 strncpy(edev->product_id, manufacture_reply->product_id,
2853 SAS_EXPANDER_PRODUCT_ID_LEN);
2854 strncpy(edev->product_rev, manufacture_reply->product_rev,
2855 SAS_EXPANDER_PRODUCT_REV_LEN);
2856 edev->level = manufacture_reply->sas_format;
2857 if (manufacture_reply->sas_format) {
2858 strncpy(edev->component_vendor_id,
2859 manufacture_reply->component_vendor_id,
2860 SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN);
2861 tmp = (u8 *)&manufacture_reply->component_id;
2862 edev->component_id = tmp[0] << 8 | tmp[1];
2863 edev->component_revision_id =
2864 manufacture_reply->component_revision_id;
2865 }
2866 } else {
2867 printk(MYIOC_s_ERR_FMT
2868 "%s: smp passthru reply failed to be returned\n",
2869 ioc->name, __func__);
2870 ret = -ENXIO;
2871 }
2872out_free:
2873 if (data_out_dma)
2874 pci_free_consistent(ioc->pcidev, sz, data_out, data_out_dma);
2875put_mf:
2876 if (mf)
2877 mpt_free_msg_frame(ioc, mf);
2878out_unlock:
2879 CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
2880 mutex_unlock(&ioc->sas_mgmt.mutex);
2881out:
2882 return ret;
2883 }
2884
2689static void 2885static void
2690mptsas_parse_device_info(struct sas_identify *identify, 2886mptsas_parse_device_info(struct sas_identify *identify,
2691 struct mptsas_devinfo *device_info) 2887 struct mptsas_devinfo *device_info)
@@ -2967,6 +3163,11 @@ static int mptsas_probe_one_phy(struct device *dev,
2967 goto out; 3163 goto out;
2968 } 3164 }
2969 mptsas_set_rphy(ioc, phy_info, rphy); 3165 mptsas_set_rphy(ioc, phy_info, rphy);
3166 if (identify.device_type == SAS_EDGE_EXPANDER_DEVICE ||
3167 identify.device_type == SAS_FANOUT_EXPANDER_DEVICE)
3168 mptsas_exp_repmanufacture_info(ioc,
3169 identify.sas_address,
3170 rphy_to_expander_device(rphy));
2970 } 3171 }
2971 3172
2972 out: 3173 out:
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 81279b3d694c..4a7d1afcb666 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -1438,9 +1438,14 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1438 && (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES) 1438 && (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
1439 && (SCpnt->device->tagged_supported)) { 1439 && (SCpnt->device->tagged_supported)) {
1440 scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ; 1440 scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1441 } else { 1441 if (SCpnt->request && SCpnt->request->ioprio) {
1442 if (((SCpnt->request->ioprio & 0x7) == 1) ||
1443 !(SCpnt->request->ioprio & 0x7))
1444 scsictl |= MPI_SCSIIO_CONTROL_HEADOFQ;
1445 }
1446 } else
1442 scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED; 1447 scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1443 } 1448
1444 1449
1445 /* Use the above information to set up the message frame 1450 /* Use the above information to set up the message frame
1446 */ 1451 */