aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/message/fusion/mptbase.h1
-rw-r--r--drivers/message/fusion/mptfc.c87
2 files changed, 34 insertions, 54 deletions
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index d4cb144ab402..c537d71c18e4 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -640,7 +640,6 @@ typedef struct _MPT_ADAPTER
640 struct work_struct fc_setup_reset_work; 640 struct work_struct fc_setup_reset_work;
641 struct list_head fc_rports; 641 struct list_head fc_rports;
642 spinlock_t fc_rescan_work_lock; 642 spinlock_t fc_rescan_work_lock;
643 int fc_rescan_work_count;
644 struct work_struct fc_rescan_work; 643 struct work_struct fc_rescan_work;
645 char fc_rescan_work_q_name[KOBJ_NAME_LEN]; 644 char fc_rescan_work_q_name[KOBJ_NAME_LEN];
646 struct workqueue_struct *fc_rescan_work_q; 645 struct workqueue_struct *fc_rescan_work_q;
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index 2144554a640d..85696f34c310 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -898,59 +898,45 @@ mptfc_rescan_devices(void *arg)
898{ 898{
899 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg; 899 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
900 int ii; 900 int ii;
901 int work_to_do;
902 u64 pn; 901 u64 pn;
903 unsigned long flags;
904 struct mptfc_rport_info *ri; 902 struct mptfc_rport_info *ri;
905 903
906 do { 904 /* start by tagging all ports as missing */
907 /* start by tagging all ports as missing */ 905 list_for_each_entry(ri, &ioc->fc_rports, list) {
908 list_for_each_entry(ri, &ioc->fc_rports, list) { 906 if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
909 if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) { 907 ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING;
910 ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING;
911 }
912 } 908 }
909 }
913 910
914 /* 911 /*
915 * now rescan devices known to adapter, 912 * now rescan devices known to adapter,
916 * will reregister existing rports 913 * will reregister existing rports
917 */ 914 */
918 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) { 915 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
919 (void) mptfc_GetFcPortPage0(ioc, ii); 916 (void) mptfc_GetFcPortPage0(ioc, ii);
920 mptfc_init_host_attr(ioc,ii); /* refresh */ 917 mptfc_init_host_attr(ioc, ii); /* refresh */
921 mptfc_GetFcDevPage0(ioc,ii,mptfc_register_dev); 918 mptfc_GetFcDevPage0(ioc, ii, mptfc_register_dev);
922 } 919 }
923 920
924 /* delete devices still missing */ 921 /* delete devices still missing */
925 list_for_each_entry(ri, &ioc->fc_rports, list) { 922 list_for_each_entry(ri, &ioc->fc_rports, list) {
926 /* if newly missing, delete it */ 923 /* if newly missing, delete it */
927 if (ri->flags & MPT_RPORT_INFO_FLAGS_MISSING) { 924 if (ri->flags & MPT_RPORT_INFO_FLAGS_MISSING) {
928 925
929 ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED| 926 ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED|
930 MPT_RPORT_INFO_FLAGS_MISSING); 927 MPT_RPORT_INFO_FLAGS_MISSING);
931 fc_remote_port_delete(ri->rport); /* won't sleep */ 928 fc_remote_port_delete(ri->rport); /* won't sleep */
932 ri->rport = NULL; 929 ri->rport = NULL;
933 930
934 pn = (u64)ri->pg0.WWPN.High << 32 | 931 pn = (u64)ri->pg0.WWPN.High << 32 |
935 (u64)ri->pg0.WWPN.Low; 932 (u64)ri->pg0.WWPN.Low;
936 dfcprintk ((MYIOC_s_INFO_FMT 933 dfcprintk ((MYIOC_s_INFO_FMT
937 "mptfc_rescan.%d: %llx deleted\n", 934 "mptfc_rescan.%d: %llx deleted\n",
938 ioc->name, 935 ioc->name,
939 ioc->sh->host_no, 936 ioc->sh->host_no,
940 (unsigned long long)pn)); 937 (unsigned long long)pn));
941 }
942 } 938 }
943 939 }
944 /*
945 * allow multiple passes as target state
946 * might have changed during scan
947 */
948 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
949 if (ioc->fc_rescan_work_count > 2) /* only need one more */
950 ioc->fc_rescan_work_count = 2;
951 work_to_do = --ioc->fc_rescan_work_count;
952 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
953 } while (work_to_do);
954} 940}
955 941
956static int 942static int
@@ -1162,7 +1148,6 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1162 * by doing it via the workqueue, some locking is eliminated 1148 * by doing it via the workqueue, some locking is eliminated
1163 */ 1149 */
1164 1150
1165 ioc->fc_rescan_work_count = 1;
1166 queue_work(ioc->fc_rescan_work_q, &ioc->fc_rescan_work); 1151 queue_work(ioc->fc_rescan_work_q, &ioc->fc_rescan_work);
1167 flush_workqueue(ioc->fc_rescan_work_q); 1152 flush_workqueue(ioc->fc_rescan_work_q);
1168 1153
@@ -1205,10 +1190,8 @@ mptfc_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
1205 case MPI_EVENT_RESCAN: 1190 case MPI_EVENT_RESCAN:
1206 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags); 1191 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1207 if (ioc->fc_rescan_work_q) { 1192 if (ioc->fc_rescan_work_q) {
1208 if (ioc->fc_rescan_work_count++ == 0) { 1193 queue_work(ioc->fc_rescan_work_q,
1209 queue_work(ioc->fc_rescan_work_q, 1194 &ioc->fc_rescan_work);
1210 &ioc->fc_rescan_work);
1211 }
1212 } 1195 }
1213 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags); 1196 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1214 break; 1197 break;
@@ -1251,10 +1234,8 @@ mptfc_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
1251 mptfc_SetFcPortPage1_defaults(ioc); 1234 mptfc_SetFcPortPage1_defaults(ioc);
1252 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags); 1235 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1253 if (ioc->fc_rescan_work_q) { 1236 if (ioc->fc_rescan_work_q) {
1254 if (ioc->fc_rescan_work_count++ == 0) { 1237 queue_work(ioc->fc_rescan_work_q,
1255 queue_work(ioc->fc_rescan_work_q, 1238 &ioc->fc_rescan_work);
1256 &ioc->fc_rescan_work);
1257 }
1258 } 1239 }
1259 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags); 1240 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1260 } 1241 }