Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 2 Oct 2014 09:42:12 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r272401 - head/sys/cam/scsi
Message-ID:  <201410020942.s929gCW7073411@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Thu Oct  2 09:42:11 2014
New Revision: 272401
URL: https://svnweb.freebsd.org/changeset/base/272401

Log:
  Rework the logic of sequential SCSI LUN scanner.
  
  Previous logic was not differentiating disconnected LUNs and absent targets.
  That made it to stop scan if LUN 0 was not found for any reason.  That made
  problematic, for example, using iSCSI targets declaring SPC-2 compliance and
  having no LUN 0 configured.
  
  The new logic continues sequential LUN scan if:
   -- we have more configured LUNs that need recheck;
   -- this LUN is connected and its SCSI version allows more LUNs;
   -- this LUN is disconnected, its SCSI version allows more LUNs and we
      guess they may be connected (we haven't scanned first 8 LUNs yet or
      kern.cam.cam_srch_hi sysctl is set to scan more).
  
  Reported by:	trasz
  MFC after:	1 month

Modified:
  head/sys/cam/scsi/scsi_xpt.c

Modified: head/sys/cam/scsi/scsi_xpt.c
==============================================================================
--- head/sys/cam/scsi/scsi_xpt.c	Thu Oct  2 08:57:11 2014	(r272400)
+++ head/sys/cam/scsi/scsi_xpt.c	Thu Oct  2 09:42:11 2014	(r272401)
@@ -1135,6 +1135,7 @@ out:
 			u_int8_t periph_qual;
 
 			path->device->flags |= CAM_DEV_INQUIRY_DATA_VALID;
+			scsi_find_quirk(path->device);
 			inq_buf = &path->device->inq_data;
 
 			periph_qual = SID_QUAL(inq_buf);
@@ -1163,8 +1164,6 @@ out:
 					goto out;
 				}
 
-				scsi_find_quirk(path->device);
-
 				scsi_devise_transport(path);
 
 				if (path->device->lun_id == 0 &&
@@ -1213,10 +1212,13 @@ out:
 					    : SF_RETRY_UA,
 					    &softc->saved_ccb) == ERESTART) {
 			goto outr;
-		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
-			/* Don't wedge the queue */
-			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
-					 /*run_queue*/TRUE);
+		} else {
+			if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
+				/* Don't wedge the queue */
+				xpt_release_devq(done_ccb->ccb_h.path,
+				    /*count*/1, /*run_queue*/TRUE);
+			}
+			path->device->flags &= ~CAM_DEV_INQUIRY_DATA_VALID;
 		}
 		/*
 		 * If we get to this point, we got an error status back
@@ -1975,7 +1977,7 @@ scsi_scan_bus(struct cam_periph *periph,
 		struct cam_path *path, *oldpath;
 		scsi_scan_bus_info *scan_info;
 		struct cam_et *target;
-		struct cam_ed *device;
+		struct cam_ed *device, *nextdev;
 		int next_target;
 		path_id_t path_id;
 		target_id_t target_id;
@@ -1984,18 +1986,10 @@ scsi_scan_bus(struct cam_periph *periph,
 		oldpath = request_ccb->ccb_h.path;
 
 		status = cam_ccb_status(request_ccb);
-		/* Reuse the same CCB to query if a device was really found */
 		scan_info = (scsi_scan_bus_info *)request_ccb->ccb_h.ppriv_ptr0;
-		xpt_setup_ccb(&request_ccb->ccb_h, request_ccb->ccb_h.path,
-			      request_ccb->ccb_h.pinfo.priority);
-		request_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
-
-
 		path_id = request_ccb->ccb_h.path_id;
 		target_id = request_ccb->ccb_h.target_id;
 		lun_id = request_ccb->ccb_h.target_lun;
-		xpt_action(request_ccb);
-
 		target = request_ccb->ccb_h.path->target;
 		next_target = 1;
 
@@ -2068,56 +2062,36 @@ scsi_scan_bus(struct cam_periph *periph,
 				}
 			}
 		} else {
-		    mtx_unlock(&target->luns_mtx);
-		    if (request_ccb->ccb_h.status != CAM_REQ_CMP) {
-			int phl;
-
-			/*
-			 * If we already probed lun 0 successfully, or
-			 * we have additional configured luns on this
-			 * target that might have "gone away", go onto
-			 * the next lun.
-			 */
-			/*
-			 * We may touch devices that we don't
-			 * hold references too, so ensure they
-			 * don't disappear out from under us.
-			 * The target above is referenced by the
-			 * path in the request ccb.
-			 */
-			phl = 0;
-			device = TAILQ_FIRST(&target->ed_entries);
-			if (device != NULL) {
-				phl = CAN_SRCH_HI_SPARSE(device);
-				if (device->lun_id == 0)
-					device = TAILQ_NEXT(device, links);
-			}
-			if ((lun_id != 0) || (device != NULL)) {
-				if (lun_id < (CAM_SCSI2_MAXLUN-1) || phl) {
-					lun_id++;
-					next_target = 0;
-				}
-			}
-			if (lun_id == request_ccb->ccb_h.target_lun
-			    || lun_id > scan_info->cpi->max_lun)
-				next_target = 1;
-		    } else {
-
+			mtx_unlock(&target->luns_mtx);
 			device = request_ccb->ccb_h.path->device;
-
-			if ((SCSI_QUIRK(device)->quirks &
-			    CAM_QUIRK_NOLUNS) == 0) {
-				/* Try the next lun */
-				if (lun_id < (CAM_SCSI2_MAXLUN-1)
-				  || CAN_SRCH_HI_DENSE(device)) {
-					lun_id++;
+			/* Continue sequential LUN scan if: */
+			/*  -- we have more LUNs that need recheck */
+			mtx_lock(&target->bus->eb_mtx);
+			nextdev = device;
+			while ((nextdev = TAILQ_NEXT(nextdev, links)) != NULL)
+				if ((nextdev->flags & CAM_DEV_UNCONFIGURED) == 0)
+					break;
+			mtx_unlock(&target->bus->eb_mtx);
+			if (nextdev != NULL) {
+				next_target = 0;
+			/*  -- this LUN is connected and its SCSI version
+			 *     allows more LUNs. */
+			} else if ((device->flags & CAM_DEV_UNCONFIGURED) == 0) {
+				if (lun_id < (CAM_SCSI2_MAXLUN-1) ||
+				    CAN_SRCH_HI_DENSE(device))
 					next_target = 0;
-				}
+			/*  -- this LUN is disconnected, its SCSI version
+			 *     allows more LUNs and we guess they may be. */
+			} else if ((device->flags & CAM_DEV_INQUIRY_DATA_VALID) != 0) {
+				if (lun_id < (CAM_SCSI2_MAXLUN-1) ||
+				    CAN_SRCH_HI_SPARSE(device))
+					next_target = 0;
+			}
+			if (next_target == 0) {
+				lun_id++;
+				if (lun_id > scan_info->cpi->max_lun)
+					next_target = 1;
 			}
-			if (lun_id == request_ccb->ccb_h.target_lun
-			    || lun_id > scan_info->cpi->max_lun)
-				next_target = 1;
-		    }
 		}
 
 		/*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201410020942.s929gCW7073411>