Re: new qla2xxx driver breaks SAN setup with 2 controllers

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

 



On Wed, Aug 24, 2005 at 03:08:23PM +0200, Frederik Schueler wrote:
> Hello,
> 
> no change.

What was logged? Any errors?

Try setting scsi logging_level for scan, after boot/load:

     sysctl -w dev.scsi.logging_level=0x1c0

Then reload the qla driver, and post logs.

If the qlogic driver returned DID_NO_CONNECT while scanning (or similar
errors), we stop the scan, but there is no code like that in the mainline
qlogic driver.

Can you also try this patch to use REPORT LUN scan even if no storage on
LUN 0?  Herre posted a similar patch that keeps LUN 0 around after the
scan, this version does not; I was going to post this after 2.6.13 was
out.

Also, you can pass devinfo additions as a module param (or boot time
param).

diff -uprN -X /home/patman/dontdiff linux-2.6.13-rc6-git13/drivers/scsi/scsi_scan.c lun0-linux-2.6.13-rc6-git13/drivers/scsi/scsi_scan.c
--- linux-2.6.13-rc6-git13/drivers/scsi/scsi_scan.c	2005-08-21 03:20:19.000000000 -0700
+++ lun0-linux-2.6.13-rc6-git13/drivers/scsi/scsi_scan.c	2005-08-24 09:22:23.000000000 -0700
@@ -64,14 +64,14 @@
  * SCSI_SCAN_NO_RESPONSE: no valid response received from the target, this
  * includes allocation or general failures preventing IO from being sent.
  *
- * SCSI_SCAN_TARGET_PRESENT: target responded, but no device is available
+ * SCSI_SCAN_LUN_IGNORED: target responded, but no device is available
  * on the given LUN.
  *
  * SCSI_SCAN_LUN_PRESENT: target responded, and a device is available on a
  * given LUN.
  */
 #define SCSI_SCAN_NO_RESPONSE		0
-#define SCSI_SCAN_TARGET_PRESENT	1
+#define SCSI_SCAN_LUN_IGNORED		1
 #define SCSI_SCAN_LUN_PRESENT		2
 
 static char *scsi_null_device_strs = "nullnullnullnull";
@@ -585,7 +585,7 @@ static void scsi_probe_lun(struct scsi_r
 
 	/*
 	 * The scanning code needs to know the scsi_level, even if no
-	 * device is attached at LUN 0 (SCSI_SCAN_TARGET_PRESENT) so
+	 * device is attached at LUN 0 (SCSI_SCAN_LUN_IGNORED) so
 	 * non-zero LUNs can be scanned.
 	 */
 	sdev->scsi_level = inq_result[2] & 0x07;
@@ -776,6 +776,19 @@ static int scsi_add_lun(struct scsi_devi
 	return SCSI_SCAN_LUN_PRESENT;
 }
 
+/*
+ * scsi_scan_remove: Helper funciton to free up sdev's that are not added
+ * as sys devices. That is, we never call scsi_probe_and_add_lun for these
+ * sdev's.
+ */
+static void scsi_scan_remove(struct scsi_device *sdev)
+{
+	if (sdev->host->hostt->slave_destroy)
+		sdev->host->hostt->slave_destroy(sdev);
+	transport_destroy_device(&sdev->sdev_gendev);
+	put_device(&sdev->sdev_gendev);
+}
+
 /**
  * scsi_probe_and_add_lun - probe a LUN, if a LUN is found add it
  * @starget:	pointer to target device structure
@@ -788,9 +801,12 @@ static int scsi_add_lun(struct scsi_devi
  *     Call scsi_probe_lun, if a LUN with an attached device is found,
  *     allocate and set it up by calling scsi_add_lun.
  *
+ * Note: LUN 0 is special cased so it can be used for a REPORT LUN scan,
+ *     the caller must release the sdev if we return SCSI_SCAN_LUN_IGNORED.
+ *
  * Return:
  *     SCSI_SCAN_NO_RESPONSE: could not allocate or setup a Scsi_Device
- *     SCSI_SCAN_TARGET_PRESENT: target responded, but no device is
+ *     SCSI_SCAN_LUN_IGNORED: target responded, but no device is
  *         attached at the LUN
  *     SCSI_SCAN_LUN_PRESENT: a new Scsi_Device was allocated and initialized
  **/
@@ -860,7 +876,7 @@ static int scsi_probe_and_add_lun(struct
 		SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO
 					"scsi scan: peripheral qualifier of 3,"
 					" no device added\n"));
-		res = SCSI_SCAN_TARGET_PRESENT;
+		res = SCSI_SCAN_LUN_IGNORED;
 		goto out_free_result;
 	}
 
@@ -879,17 +895,14 @@ static int scsi_probe_and_add_lun(struct
  out_free_sreq:
 	scsi_release_request(sreq);
  out_free_sdev:
-	if (res == SCSI_SCAN_LUN_PRESENT) {
+	if ((res == SCSI_SCAN_LUN_PRESENT) ||
+	    ((lun == 0) && (res == SCSI_SCAN_LUN_IGNORED))) {
 		if (sdevp) {
 			scsi_device_get(sdev);
 			*sdevp = sdev;
 		}
-	} else {
-		if (sdev->host->hostt->slave_destroy)
-			sdev->host->hostt->slave_destroy(sdev);
-		transport_destroy_device(&sdev->sdev_gendev);
-		put_device(&sdev->sdev_gendev);
-	}
+	} else
+		scsi_scan_remove(sdev);
  out:
 	return res;
 }
@@ -1266,6 +1279,8 @@ struct scsi_device *__scsi_add_device(st
 	get_device(&starget->dev);
 	down(&shost->scan_mutex);
 	res = scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1, hostdata);
+	if ((lun == 0) && (res == SCSI_SCAN_LUN_IGNORED))
+		scsi_scan_remove(sdev);
 	if (res != SCSI_SCAN_LUN_PRESENT)
 		sdev = ERR_PTR(-ENODEV);
 	up(&shost->scan_mutex);
@@ -1337,7 +1352,8 @@ void scsi_scan_target(struct device *par
 		/*
 		 * Scan for a specific host/chan/id/lun.
 		 */
-		scsi_probe_and_add_lun(starget, lun, NULL, NULL, rescan, NULL);
+		res = scsi_probe_and_add_lun(starget, lun, NULL, &sdev,
+					     rescan, NULL);
 		goto out_reap;
 	}
 
@@ -1345,8 +1361,11 @@ void scsi_scan_target(struct device *par
 	 * Scan LUN 0, if there is some response, scan further. Ideally, we
 	 * would not configure LUN 0 until all LUNs are scanned.
 	 */
-	res = scsi_probe_and_add_lun(starget, 0, &bflags, &sdev, rescan, NULL);
-	if (res == SCSI_SCAN_LUN_PRESENT) {
+	lun = 0;
+	res = scsi_probe_and_add_lun(starget, lun, &bflags, &sdev, rescan,
+				     NULL);
+	WARN_ON(!sdev && res != SCSI_SCAN_NO_RESPONSE);
+	if (sdev && res != SCSI_SCAN_NO_RESPONSE)
 		if (scsi_report_lun_scan(sdev, bflags, rescan) != 0)
 			/*
 			 * The REPORT LUN did not scan the target,
@@ -1354,20 +1373,12 @@ void scsi_scan_target(struct device *par
 			 */
 			scsi_sequential_lun_scan(starget, bflags,
 				       	res, sdev->scsi_level, rescan);
-	} else if (res == SCSI_SCAN_TARGET_PRESENT) {
-		/*
-		 * There's a target here, but lun 0 is offline so we
-		 * can't use the report_lun scan.  Fall back to a
-		 * sequential lun scan with a bflags of SPARSELUN and
-		 * a default scsi level of SCSI_2
-		 */
-		scsi_sequential_lun_scan(starget, BLIST_SPARSELUN,
-				SCSI_SCAN_TARGET_PRESENT, SCSI_2, rescan);
-	}
 	if (sdev)
 		scsi_device_put(sdev);
 
  out_reap:
+	if ((lun == 0) && (res == SCSI_SCAN_LUN_IGNORED))
+		scsi_scan_remove(sdev);
 	/* now determine if the target has any children at all
 	 * and if not, nuke it */
 	scsi_target_reap(starget);

-- Patrick Mansfield
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]
  Powered by Linux