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 90da7d63b08e..85696f34c310 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c | |||
@@ -669,7 +669,10 @@ mptfc_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum) | |||
669 | * if still doing discovery, | 669 | * if still doing discovery, |
670 | * hang loose a while until finished | 670 | * hang loose a while until finished |
671 | */ | 671 | */ |
672 | if (pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_UNKNOWN) { | 672 | if ((pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_UNKNOWN) || |
673 | (pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_ONLINE && | ||
674 | (pp0dest->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_TYPE_MASK) | ||
675 | == MPI_FCPORTPAGE0_FLAGS_ATTACH_NO_INIT)) { | ||
673 | if (count-- > 0) { | 676 | if (count-- > 0) { |
674 | msleep(100); | 677 | msleep(100); |
675 | goto try_again; | 678 | goto try_again; |
@@ -895,59 +898,45 @@ mptfc_rescan_devices(void *arg) | |||
895 | { | 898 | { |
896 | MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg; | 899 | MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg; |
897 | int ii; | 900 | int ii; |
898 | int work_to_do; | ||
899 | u64 pn; | 901 | u64 pn; |
900 | unsigned long flags; | ||
901 | struct mptfc_rport_info *ri; | 902 | struct mptfc_rport_info *ri; |
902 | 903 | ||
903 | do { | 904 | /* start by tagging all ports as missing */ |
904 | /* start by tagging all ports as missing */ | 905 | list_for_each_entry(ri, &ioc->fc_rports, list) { |
905 | list_for_each_entry(ri, &ioc->fc_rports, list) { | 906 | if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) { |
906 | if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) { | 907 | ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING; |
907 | ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING; | ||
908 | } | ||
909 | } | 908 | } |
909 | } | ||
910 | 910 | ||
911 | /* | 911 | /* |
912 | * now rescan devices known to adapter, | 912 | * now rescan devices known to adapter, |
913 | * will reregister existing rports | 913 | * will reregister existing rports |
914 | */ | 914 | */ |
915 | for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) { | 915 | for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) { |
916 | (void) mptfc_GetFcPortPage0(ioc, ii); | 916 | (void) mptfc_GetFcPortPage0(ioc, ii); |
917 | mptfc_init_host_attr(ioc,ii); /* refresh */ | 917 | mptfc_init_host_attr(ioc, ii); /* refresh */ |
918 | mptfc_GetFcDevPage0(ioc,ii,mptfc_register_dev); | 918 | mptfc_GetFcDevPage0(ioc, ii, mptfc_register_dev); |
919 | } | 919 | } |
920 | 920 | ||
921 | /* delete devices still missing */ | 921 | /* delete devices still missing */ |
922 | list_for_each_entry(ri, &ioc->fc_rports, list) { | 922 | list_for_each_entry(ri, &ioc->fc_rports, list) { |
923 | /* if newly missing, delete it */ | 923 | /* if newly missing, delete it */ |
924 | if (ri->flags & MPT_RPORT_INFO_FLAGS_MISSING) { | 924 | if (ri->flags & MPT_RPORT_INFO_FLAGS_MISSING) { |
925 | 925 | ||
926 | ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED| | 926 | ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED| |
927 | MPT_RPORT_INFO_FLAGS_MISSING); | 927 | MPT_RPORT_INFO_FLAGS_MISSING); |
928 | fc_remote_port_delete(ri->rport); /* won't sleep */ | 928 | fc_remote_port_delete(ri->rport); /* won't sleep */ |
929 | ri->rport = NULL; | 929 | ri->rport = NULL; |
930 | 930 | ||
931 | pn = (u64)ri->pg0.WWPN.High << 32 | | 931 | pn = (u64)ri->pg0.WWPN.High << 32 | |
932 | (u64)ri->pg0.WWPN.Low; | 932 | (u64)ri->pg0.WWPN.Low; |
933 | dfcprintk ((MYIOC_s_INFO_FMT | 933 | dfcprintk ((MYIOC_s_INFO_FMT |
934 | "mptfc_rescan.%d: %llx deleted\n", | 934 | "mptfc_rescan.%d: %llx deleted\n", |
935 | ioc->name, | 935 | ioc->name, |
936 | ioc->sh->host_no, | 936 | ioc->sh->host_no, |
937 | (unsigned long long)pn)); | 937 | (unsigned long long)pn)); |
938 | } | ||
939 | } | 938 | } |
940 | 939 | } | |
941 | /* | ||
942 | * allow multiple passes as target state | ||
943 | * might have changed during scan | ||
944 | */ | ||
945 | spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags); | ||
946 | if (ioc->fc_rescan_work_count > 2) /* only need one more */ | ||
947 | ioc->fc_rescan_work_count = 2; | ||
948 | work_to_do = --ioc->fc_rescan_work_count; | ||
949 | spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags); | ||
950 | } while (work_to_do); | ||
951 | } | 940 | } |
952 | 941 | ||
953 | static int | 942 | static int |
@@ -1159,7 +1148,6 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1159 | * by doing it via the workqueue, some locking is eliminated | 1148 | * by doing it via the workqueue, some locking is eliminated |
1160 | */ | 1149 | */ |
1161 | 1150 | ||
1162 | ioc->fc_rescan_work_count = 1; | ||
1163 | queue_work(ioc->fc_rescan_work_q, &ioc->fc_rescan_work); | 1151 | queue_work(ioc->fc_rescan_work_q, &ioc->fc_rescan_work); |
1164 | flush_workqueue(ioc->fc_rescan_work_q); | 1152 | flush_workqueue(ioc->fc_rescan_work_q); |
1165 | 1153 | ||
@@ -1202,10 +1190,8 @@ mptfc_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) | |||
1202 | case MPI_EVENT_RESCAN: | 1190 | case MPI_EVENT_RESCAN: |
1203 | spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags); | 1191 | spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags); |
1204 | if (ioc->fc_rescan_work_q) { | 1192 | if (ioc->fc_rescan_work_q) { |
1205 | if (ioc->fc_rescan_work_count++ == 0) { | 1193 | queue_work(ioc->fc_rescan_work_q, |
1206 | queue_work(ioc->fc_rescan_work_q, | 1194 | &ioc->fc_rescan_work); |
1207 | &ioc->fc_rescan_work); | ||
1208 | } | ||
1209 | } | 1195 | } |
1210 | spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags); | 1196 | spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags); |
1211 | break; | 1197 | break; |
@@ -1248,10 +1234,8 @@ mptfc_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) | |||
1248 | mptfc_SetFcPortPage1_defaults(ioc); | 1234 | mptfc_SetFcPortPage1_defaults(ioc); |
1249 | spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags); | 1235 | spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags); |
1250 | if (ioc->fc_rescan_work_q) { | 1236 | if (ioc->fc_rescan_work_q) { |
1251 | if (ioc->fc_rescan_work_count++ == 0) { | 1237 | queue_work(ioc->fc_rescan_work_q, |
1252 | queue_work(ioc->fc_rescan_work_q, | 1238 | &ioc->fc_rescan_work); |
1253 | &ioc->fc_rescan_work); | ||
1254 | } | ||
1255 | } | 1239 | } |
1256 | spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags); | 1240 | spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags); |
1257 | } | 1241 | } |