[PATCH 1/6] mpt fusion - fibre channel target discovery prematurely terminates

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



mpt_config() can return EAGAIN.  When this happens, fibre channel target
discovery can prematurely terminate with fewer than the total number of
targets discovered.  This patch detects EAGAIN and reschedules the scan
work.

Generally, this situation only occurs when the lsiutil program is being
used to reset the board.

Signed-off-by: Michael Reed <mdr@xxxxxxx>



mpt_config() can return EAGAIN.  When this happens, fibre channel target
discovery can prematurely terminate with fewer than the total number of
targets discovered.  This patch detects EAGAIN and reschedules the scan
work.

Generally, this situation only occurs when the lsiutil program is being
used to reset the board.

Signed-off-by: Michael Reed <mdr@xxxxxxx>


--- rc3u/drivers/message/fusion/mptfc.c	2006-05-01 16:06:13.311966423 -0500
+++ rc3/drivers/message/fusion/mptfc.c	2006-05-03 14:16:47.669834844 -0500
@@ -634,6 +634,7 @@
 	MPT_ADAPTER		*ioc = (MPT_ADAPTER *)arg;
 	int			ii;
 	int			work_to_do;
+	int			rc=0;
 	u64			pn;
 	unsigned long		flags;
 	struct mptfc_rport_info *ri;
@@ -651,9 +652,13 @@
 		 * will reregister existing rports
 		 */
 		for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
-			(void) mptbase_GetFcPortPage0(ioc, ii);
+			rc = mptbase_GetFcPortPage0(ioc, ii);
+			if (rc == -EAGAIN)
+				break;
 			mptfc_init_host_attr(ioc,ii);	/* refresh */
-			mptfc_GetFcDevPage0(ioc,ii,mptfc_register_dev);
+			rc = mptfc_GetFcDevPage0(ioc,ii,mptfc_register_dev);
+			if (rc == -EAGAIN)
+				break;
 		}
 
 		/* delete devices still missing */
@@ -686,6 +691,20 @@
 		work_to_do = --ioc->fc_rescan_work_count;
 		spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
 	} while (work_to_do);
+
+	/* if last pass failed with EAGAIN, reschedule work for a later attempt */
+	if (rc == -EAGAIN) {
+		spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
+		if (ioc->fc_rescan_work_q) {
+			queue_delayed_work(ioc->fc_rescan_work_q, &ioc->fc_rescan_work, HZ);
+			ioc->fc_rescan_work_count = 1;
+		}
+		spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
+		dfcprintk ((MYIOC_s_INFO_FMT
+			"mptfc_rescan.%d: rescheduling work\n",
+			ioc->name,
+			ioc->sh->host_no));
+	}
 }
 
 static int
@@ -981,6 +1000,7 @@
 		spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
 		ioc->fc_rescan_work_q = NULL;
 		spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
+		cancel_delayed_work(&ioc->fc_rescan_work);
 		destroy_workqueue(work_q);
 	}
 

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux