aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/fusion/mptfc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/message/fusion/mptfc.c')
-rw-r--r--drivers/message/fusion/mptfc.c228
1 files changed, 133 insertions, 95 deletions
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index 74714e5bcf0..e57bb035a02 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -77,10 +77,6 @@ MODULE_DESCRIPTION(my_NAME);
77MODULE_LICENSE("GPL"); 77MODULE_LICENSE("GPL");
78 78
79/* Command line args */ 79/* Command line args */
80static int mpt_pq_filter = 0;
81module_param(mpt_pq_filter, int, 0);
82MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1 (default=0)");
83
84#define MPTFC_DEV_LOSS_TMO (60) 80#define MPTFC_DEV_LOSS_TMO (60)
85static int mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO; /* reasonable default */ 81static int mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO; /* reasonable default */
86module_param(mptfc_dev_loss_tmo, int, 0); 82module_param(mptfc_dev_loss_tmo, int, 0);
@@ -132,21 +128,21 @@ static struct scsi_host_template mptfc_driver_template = {
132 */ 128 */
133 129
134static struct pci_device_id mptfc_pci_table[] = { 130static struct pci_device_id mptfc_pci_table[] = {
135 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC909, 131 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC909,
136 PCI_ANY_ID, PCI_ANY_ID }, 132 PCI_ANY_ID, PCI_ANY_ID },
137 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919, 133 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC919,
138 PCI_ANY_ID, PCI_ANY_ID }, 134 PCI_ANY_ID, PCI_ANY_ID },
139 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929, 135 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC929,
140 PCI_ANY_ID, PCI_ANY_ID }, 136 PCI_ANY_ID, PCI_ANY_ID },
141 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919X, 137 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC919X,
142 PCI_ANY_ID, PCI_ANY_ID }, 138 PCI_ANY_ID, PCI_ANY_ID },
143 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929X, 139 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC929X,
144 PCI_ANY_ID, PCI_ANY_ID }, 140 PCI_ANY_ID, PCI_ANY_ID },
145 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC939X, 141 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC939X,
146 PCI_ANY_ID, PCI_ANY_ID }, 142 PCI_ANY_ID, PCI_ANY_ID },
147 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC949X, 143 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC949X,
148 PCI_ANY_ID, PCI_ANY_ID }, 144 PCI_ANY_ID, PCI_ANY_ID },
149 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC949ES, 145 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC949E,
150 PCI_ANY_ID, PCI_ANY_ID }, 146 PCI_ANY_ID, PCI_ANY_ID },
151 {0} /* Terminating entry */ 147 {0} /* Terminating entry */
152}; 148};
@@ -166,7 +162,13 @@ static struct fc_function_template mptfc_transport_functions = {
166 .show_starget_port_id = 1, 162 .show_starget_port_id = 1,
167 .set_rport_dev_loss_tmo = mptfc_set_rport_loss_tmo, 163 .set_rport_dev_loss_tmo = mptfc_set_rport_loss_tmo,
168 .show_rport_dev_loss_tmo = 1, 164 .show_rport_dev_loss_tmo = 1,
169 165 .show_host_supported_speeds = 1,
166 .show_host_maxframe_size = 1,
167 .show_host_speed = 1,
168 .show_host_fabric_name = 1,
169 .show_host_port_type = 1,
170 .show_host_port_state = 1,
171 .show_host_symbolic_name = 1,
170}; 172};
171 173
172static void 174static void
@@ -305,10 +307,8 @@ mptfc_GetFcDevPage0(MPT_ADAPTER *ioc, int ioc_port,
305 } 307 }
306 308
307 out: 309 out:
308 if (pp0_array) 310 kfree(pp0_array);
309 kfree(pp0_array); 311 kfree(p0_array);
310 if (p0_array)
311 kfree(p0_array);
312 return rc; 312 return rc;
313} 313}
314 314
@@ -515,8 +515,7 @@ mptfc_slave_alloc(struct scsi_device *sdev)
515 515
516 if (vtarget->num_luns == 0) { 516 if (vtarget->num_luns == 0) {
517 vtarget->ioc_id = hd->ioc->id; 517 vtarget->ioc_id = hd->ioc->id;
518 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES | 518 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
519 MPT_TARGET_FLAGS_VALID_INQUIRY;
520 hd->Targets[sdev->id] = vtarget; 519 hd->Targets[sdev->id] = vtarget;
521 } 520 }
522 521
@@ -676,7 +675,10 @@ mptfc_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
676 * if still doing discovery, 675 * if still doing discovery,
677 * hang loose a while until finished 676 * hang loose a while until finished
678 */ 677 */
679 if (pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_UNKNOWN) { 678 if ((pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_UNKNOWN) ||
679 (pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_ONLINE &&
680 (pp0dest->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_TYPE_MASK)
681 == MPI_FCPORTPAGE0_FLAGS_ATTACH_NO_INIT)) {
680 if (count-- > 0) { 682 if (count-- > 0) {
681 msleep(100); 683 msleep(100);
682 goto try_again; 684 goto try_again;
@@ -843,33 +845,95 @@ mptfc_SetFcPortPage1_defaults(MPT_ADAPTER *ioc)
843static void 845static void
844mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum) 846mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum)
845{ 847{
846 unsigned class = 0, cos = 0; 848 unsigned class = 0;
849 unsigned cos = 0;
850 unsigned speed;
851 unsigned port_type;
852 unsigned port_state;
853 FCPortPage0_t *pp0;
854 struct Scsi_Host *sh;
855 char *sn;
847 856
848 /* don't know what to do as only one scsi (fc) host was allocated */ 857 /* don't know what to do as only one scsi (fc) host was allocated */
849 if (portnum != 0) 858 if (portnum != 0)
850 return; 859 return;
851 860
852 class = ioc->fc_port_page0[portnum].SupportedServiceClass; 861 pp0 = &ioc->fc_port_page0[portnum];
862 sh = ioc->sh;
863
864 sn = fc_host_symbolic_name(sh);
865 snprintf(sn, FC_SYMBOLIC_NAME_SIZE, "%s %s%08xh",
866 ioc->prod_name,
867 MPT_FW_REV_MAGIC_ID_STRING,
868 ioc->facts.FWVersion.Word);
869
870 fc_host_tgtid_bind_type(sh) = FC_TGTID_BIND_BY_WWPN;
871
872 fc_host_maxframe_size(sh) = pp0->MaxFrameSize;
873
874 fc_host_node_name(sh) =
875 (u64)pp0->WWNN.High << 32 | (u64)pp0->WWNN.Low;
876
877 fc_host_port_name(sh) =
878 (u64)pp0->WWPN.High << 32 | (u64)pp0->WWPN.Low;
879
880 fc_host_port_id(sh) = pp0->PortIdentifier;
881
882 class = pp0->SupportedServiceClass;
853 if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_1) 883 if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_1)
854 cos |= FC_COS_CLASS1; 884 cos |= FC_COS_CLASS1;
855 if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_2) 885 if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_2)
856 cos |= FC_COS_CLASS2; 886 cos |= FC_COS_CLASS2;
857 if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_3) 887 if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_3)
858 cos |= FC_COS_CLASS3; 888 cos |= FC_COS_CLASS3;
889 fc_host_supported_classes(sh) = cos;
890
891 if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT)
892 speed = FC_PORTSPEED_1GBIT;
893 else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT)
894 speed = FC_PORTSPEED_2GBIT;
895 else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT)
896 speed = FC_PORTSPEED_4GBIT;
897 else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_10GBIT)
898 speed = FC_PORTSPEED_10GBIT;
899 else
900 speed = FC_PORTSPEED_UNKNOWN;
901 fc_host_speed(sh) = speed;
902
903 speed = 0;
904 if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_1GBIT_SPEED)
905 speed |= FC_PORTSPEED_1GBIT;
906 if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_2GBIT_SPEED)
907 speed |= FC_PORTSPEED_2GBIT;
908 if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_4GBIT_SPEED)
909 speed |= FC_PORTSPEED_4GBIT;
910 if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_10GBIT_SPEED)
911 speed |= FC_PORTSPEED_10GBIT;
912 fc_host_supported_speeds(sh) = speed;
913
914 port_state = FC_PORTSTATE_UNKNOWN;
915 if (pp0->PortState == MPI_FCPORTPAGE0_PORTSTATE_ONLINE)
916 port_state = FC_PORTSTATE_ONLINE;
917 else if (pp0->PortState == MPI_FCPORTPAGE0_PORTSTATE_OFFLINE)
918 port_state = FC_PORTSTATE_LINKDOWN;
919 fc_host_port_state(sh) = port_state;
920
921 port_type = FC_PORTTYPE_UNKNOWN;
922 if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_POINT_TO_POINT)
923 port_type = FC_PORTTYPE_PTP;
924 else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_PRIVATE_LOOP)
925 port_type = FC_PORTTYPE_LPORT;
926 else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_PUBLIC_LOOP)
927 port_type = FC_PORTTYPE_NLPORT;
928 else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_FABRIC_DIRECT)
929 port_type = FC_PORTTYPE_NPORT;
930 fc_host_port_type(sh) = port_type;
931
932 fc_host_fabric_name(sh) =
933 (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_FABRIC_WWN_VALID) ?
934 (u64) pp0->FabricWWNN.High << 32 | (u64) pp0->FabricWWPN.Low :
935 (u64)pp0->WWNN.High << 32 | (u64)pp0->WWNN.Low;
859 936
860 fc_host_node_name(ioc->sh) =
861 (u64)ioc->fc_port_page0[portnum].WWNN.High << 32
862 | (u64)ioc->fc_port_page0[portnum].WWNN.Low;
863
864 fc_host_port_name(ioc->sh) =
865 (u64)ioc->fc_port_page0[portnum].WWPN.High << 32
866 | (u64)ioc->fc_port_page0[portnum].WWPN.Low;
867
868 fc_host_port_id(ioc->sh) = ioc->fc_port_page0[portnum].PortIdentifier;
869
870 fc_host_supported_classes(ioc->sh) = cos;
871
872 fc_host_tgtid_bind_type(ioc->sh) = FC_TGTID_BIND_BY_WWPN;
873} 937}
874 938
875static void 939static void
@@ -902,59 +966,45 @@ mptfc_rescan_devices(void *arg)
902{ 966{
903 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg; 967 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
904 int ii; 968 int ii;
905 int work_to_do;
906 u64 pn; 969 u64 pn;
907 unsigned long flags;
908 struct mptfc_rport_info *ri; 970 struct mptfc_rport_info *ri;
909 971
910 do { 972 /* start by tagging all ports as missing */
911 /* start by tagging all ports as missing */ 973 list_for_each_entry(ri, &ioc->fc_rports, list) {
912 list_for_each_entry(ri, &ioc->fc_rports, list) { 974 if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
913 if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) { 975 ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING;
914 ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING;
915 }
916 } 976 }
977 }
917 978
918 /* 979 /*
919 * now rescan devices known to adapter, 980 * now rescan devices known to adapter,
920 * will reregister existing rports 981 * will reregister existing rports
921 */ 982 */
922 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) { 983 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
923 (void) mptfc_GetFcPortPage0(ioc, ii); 984 (void) mptfc_GetFcPortPage0(ioc, ii);
924 mptfc_init_host_attr(ioc,ii); /* refresh */ 985 mptfc_init_host_attr(ioc, ii); /* refresh */
925 mptfc_GetFcDevPage0(ioc,ii,mptfc_register_dev); 986 mptfc_GetFcDevPage0(ioc, ii, mptfc_register_dev);
926 } 987 }
927 988
928 /* delete devices still missing */ 989 /* delete devices still missing */
929 list_for_each_entry(ri, &ioc->fc_rports, list) { 990 list_for_each_entry(ri, &ioc->fc_rports, list) {
930 /* if newly missing, delete it */ 991 /* if newly missing, delete it */
931 if (ri->flags & MPT_RPORT_INFO_FLAGS_MISSING) { 992 if (ri->flags & MPT_RPORT_INFO_FLAGS_MISSING) {
932 993
933 ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED| 994 ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED|
934 MPT_RPORT_INFO_FLAGS_MISSING); 995 MPT_RPORT_INFO_FLAGS_MISSING);
935 fc_remote_port_delete(ri->rport); /* won't sleep */ 996 fc_remote_port_delete(ri->rport); /* won't sleep */
936 ri->rport = NULL; 997 ri->rport = NULL;
937 998
938 pn = (u64)ri->pg0.WWPN.High << 32 | 999 pn = (u64)ri->pg0.WWPN.High << 32 |
939 (u64)ri->pg0.WWPN.Low; 1000 (u64)ri->pg0.WWPN.Low;
940 dfcprintk ((MYIOC_s_INFO_FMT 1001 dfcprintk ((MYIOC_s_INFO_FMT
941 "mptfc_rescan.%d: %llx deleted\n", 1002 "mptfc_rescan.%d: %llx deleted\n",
942 ioc->name, 1003 ioc->name,
943 ioc->sh->host_no, 1004 ioc->sh->host_no,
944 (unsigned long long)pn)); 1005 (unsigned long long)pn));
945 }
946 } 1006 }
947 1007 }
948 /*
949 * allow multiple passes as target state
950 * might have changed during scan
951 */
952 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
953 if (ioc->fc_rescan_work_count > 2) /* only need one more */
954 ioc->fc_rescan_work_count = 2;
955 work_to_do = --ioc->fc_rescan_work_count;
956 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
957 } while (work_to_do);
958} 1008}
959 1009
960static int 1010static int
@@ -1131,13 +1181,6 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1131 hd->timer.data = (unsigned long) hd; 1181 hd->timer.data = (unsigned long) hd;
1132 hd->timer.function = mptscsih_timer_expired; 1182 hd->timer.function = mptscsih_timer_expired;
1133 1183
1134 hd->mpt_pq_filter = mpt_pq_filter;
1135
1136 ddvprintk((MYIOC_s_INFO_FMT
1137 "mpt_pq_filter %x\n",
1138 ioc->name,
1139 mpt_pq_filter));
1140
1141 init_waitqueue_head(&hd->scandv_waitq); 1184 init_waitqueue_head(&hd->scandv_waitq);
1142 hd->scandv_wait_done = 0; 1185 hd->scandv_wait_done = 0;
1143 hd->last_queue_full = 0; 1186 hd->last_queue_full = 0;
@@ -1173,7 +1216,6 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1173 * by doing it via the workqueue, some locking is eliminated 1216 * by doing it via the workqueue, some locking is eliminated
1174 */ 1217 */
1175 1218
1176 ioc->fc_rescan_work_count = 1;
1177 queue_work(ioc->fc_rescan_work_q, &ioc->fc_rescan_work); 1219 queue_work(ioc->fc_rescan_work_q, &ioc->fc_rescan_work);
1178 flush_workqueue(ioc->fc_rescan_work_q); 1220 flush_workqueue(ioc->fc_rescan_work_q);
1179 1221
@@ -1216,10 +1258,8 @@ mptfc_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
1216 case MPI_EVENT_RESCAN: 1258 case MPI_EVENT_RESCAN:
1217 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags); 1259 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1218 if (ioc->fc_rescan_work_q) { 1260 if (ioc->fc_rescan_work_q) {
1219 if (ioc->fc_rescan_work_count++ == 0) { 1261 queue_work(ioc->fc_rescan_work_q,
1220 queue_work(ioc->fc_rescan_work_q, 1262 &ioc->fc_rescan_work);
1221 &ioc->fc_rescan_work);
1222 }
1223 } 1263 }
1224 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags); 1264 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1225 break; 1265 break;
@@ -1262,10 +1302,8 @@ mptfc_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
1262 mptfc_SetFcPortPage1_defaults(ioc); 1302 mptfc_SetFcPortPage1_defaults(ioc);
1263 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags); 1303 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1264 if (ioc->fc_rescan_work_q) { 1304 if (ioc->fc_rescan_work_q) {
1265 if (ioc->fc_rescan_work_count++ == 0) { 1305 queue_work(ioc->fc_rescan_work_q,
1266 queue_work(ioc->fc_rescan_work_q, 1306 &ioc->fc_rescan_work);
1267 &ioc->fc_rescan_work);
1268 }
1269 } 1307 }
1270 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags); 1308 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1271 } 1309 }