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.c92
1 files changed, 38 insertions, 54 deletions
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index 244a32c66f06..e57bb035a021 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -675,7 +675,10 @@ mptfc_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
675 * if still doing discovery, 675 * if still doing discovery,
676 * hang loose a while until finished 676 * hang loose a while until finished
677 */ 677 */
678 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)) {
679 if (count-- > 0) { 682 if (count-- > 0) {
680 msleep(100); 683 msleep(100);
681 goto try_again; 684 goto try_again;
@@ -963,59 +966,45 @@ mptfc_rescan_devices(void *arg)
963{ 966{
964 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg; 967 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
965 int ii; 968 int ii;
966 int work_to_do;
967 u64 pn; 969 u64 pn;
968 unsigned long flags;
969 struct mptfc_rport_info *ri; 970 struct mptfc_rport_info *ri;
970 971
971 do { 972 /* start by tagging all ports as missing */
972 /* start by tagging all ports as missing */ 973 list_for_each_entry(ri, &ioc->fc_rports, list) {
973 list_for_each_entry(ri, &ioc->fc_rports, list) { 974 if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
974 if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) { 975 ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING;
975 ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING;
976 }
977 } 976 }
977 }
978 978
979 /* 979 /*
980 * now rescan devices known to adapter, 980 * now rescan devices known to adapter,
981 * will reregister existing rports 981 * will reregister existing rports
982 */ 982 */
983 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) { 983 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
984 (void) mptfc_GetFcPortPage0(ioc, ii); 984 (void) mptfc_GetFcPortPage0(ioc, ii);
985 mptfc_init_host_attr(ioc,ii); /* refresh */ 985 mptfc_init_host_attr(ioc, ii); /* refresh */
986 mptfc_GetFcDevPage0(ioc,ii,mptfc_register_dev); 986 mptfc_GetFcDevPage0(ioc, ii, mptfc_register_dev);
987 } 987 }
988 988
989 /* delete devices still missing */ 989 /* delete devices still missing */
990 list_for_each_entry(ri, &ioc->fc_rports, list) { 990 list_for_each_entry(ri, &ioc->fc_rports, list) {
991 /* if newly missing, delete it */ 991 /* if newly missing, delete it */
992 if (ri->flags & MPT_RPORT_INFO_FLAGS_MISSING) { 992 if (ri->flags & MPT_RPORT_INFO_FLAGS_MISSING) {
993 993
994 ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED| 994 ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED|
995 MPT_RPORT_INFO_FLAGS_MISSING); 995 MPT_RPORT_INFO_FLAGS_MISSING);
996 fc_remote_port_delete(ri->rport); /* won't sleep */ 996 fc_remote_port_delete(ri->rport); /* won't sleep */
997 ri->rport = NULL; 997 ri->rport = NULL;
998 998
999 pn = (u64)ri->pg0.WWPN.High << 32 | 999 pn = (u64)ri->pg0.WWPN.High << 32 |
1000 (u64)ri->pg0.WWPN.Low; 1000 (u64)ri->pg0.WWPN.Low;
1001 dfcprintk ((MYIOC_s_INFO_FMT 1001 dfcprintk ((MYIOC_s_INFO_FMT
1002 "mptfc_rescan.%d: %llx deleted\n", 1002 "mptfc_rescan.%d: %llx deleted\n",
1003 ioc->name, 1003 ioc->name,
1004 ioc->sh->host_no, 1004 ioc->sh->host_no,
1005 (unsigned long long)pn)); 1005 (unsigned long long)pn));
1006 }
1007 } 1006 }
1008 1007 }
1009 /*
1010 * allow multiple passes as target state
1011 * might have changed during scan
1012 */
1013 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1014 if (ioc->fc_rescan_work_count > 2) /* only need one more */
1015 ioc->fc_rescan_work_count = 2;
1016 work_to_do = --ioc->fc_rescan_work_count;
1017 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1018 } while (work_to_do);
1019} 1008}
1020 1009
1021static int 1010static int
@@ -1227,7 +1216,6 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1227 * by doing it via the workqueue, some locking is eliminated 1216 * by doing it via the workqueue, some locking is eliminated
1228 */ 1217 */
1229 1218
1230 ioc->fc_rescan_work_count = 1;
1231 queue_work(ioc->fc_rescan_work_q, &ioc->fc_rescan_work); 1219 queue_work(ioc->fc_rescan_work_q, &ioc->fc_rescan_work);
1232 flush_workqueue(ioc->fc_rescan_work_q); 1220 flush_workqueue(ioc->fc_rescan_work_q);
1233 1221
@@ -1270,10 +1258,8 @@ mptfc_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
1270 case MPI_EVENT_RESCAN: 1258 case MPI_EVENT_RESCAN:
1271 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags); 1259 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1272 if (ioc->fc_rescan_work_q) { 1260 if (ioc->fc_rescan_work_q) {
1273 if (ioc->fc_rescan_work_count++ == 0) { 1261 queue_work(ioc->fc_rescan_work_q,
1274 queue_work(ioc->fc_rescan_work_q, 1262 &ioc->fc_rescan_work);
1275 &ioc->fc_rescan_work);
1276 }
1277 } 1263 }
1278 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags); 1264 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1279 break; 1265 break;
@@ -1316,10 +1302,8 @@ mptfc_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
1316 mptfc_SetFcPortPage1_defaults(ioc); 1302 mptfc_SetFcPortPage1_defaults(ioc);
1317 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags); 1303 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1318 if (ioc->fc_rescan_work_q) { 1304 if (ioc->fc_rescan_work_q) {
1319 if (ioc->fc_rescan_work_count++ == 0) { 1305 queue_work(ioc->fc_rescan_work_q,
1320 queue_work(ioc->fc_rescan_work_q, 1306 &ioc->fc_rescan_work);
1321 &ioc->fc_rescan_work);
1322 }
1323 } 1307 }
1324 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags); 1308 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1325 } 1309 }