diff options
Diffstat (limited to 'drivers/message/fusion/mptfc.c')
-rw-r--r-- | drivers/message/fusion/mptfc.c | 92 |
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 | ||
1021 | static int | 1010 | static 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 | } |