addition of an XPT_SCAN_TGT code, rev 2

Matthew Jacob mj at feral.com
Mon May 17 18:55:08 UTC 2010


Incorporating feedback and finding and fixing an amusing bug that kept 
the system from booting (but did not appear to affect changes while the 
system was running).



-------------- next part --------------
diff -r 85c0fa25a2fc sys/cam/ata/ata_xpt.c
--- a/sys/cam/ata/ata_xpt.c	Fri May 14 15:55:34 2010 -0700
+++ b/sys/cam/ata/ata_xpt.c	Fri May 14 18:14:46 2010 -0700
@@ -1189,6 +1189,7 @@
 		  ("xpt_scan_bus\n"));
 	switch (request_ccb->ccb_h.func_code) {
 	case XPT_SCAN_BUS:
+	case XPT_SCAN_TGT:
 		/* Find out the characteristics of the bus */
 		work_ccb = xpt_alloc_ccb_nowait();
 		if (work_ccb == NULL) {
@@ -1530,6 +1531,7 @@
 		break;
 	}
 	case XPT_SCAN_BUS:
+	case XPT_SCAN_TGT:
 		ata_scan_bus(start_ccb->ccb_h.path->periph, start_ccb);
 		break;
 	case XPT_SCAN_LUN:
diff -r 85c0fa25a2fc sys/cam/cam_ccb.h
--- a/sys/cam/cam_ccb.h	Fri May 14 15:55:34 2010 -0700
+++ b/sys/cam/cam_ccb.h	Mon May 17 11:47:24 2010 -0700
@@ -184,6 +184,11 @@
 				/*
 				 * Set SIM specific knob values.
 				 */
+
+	XPT_SCAN_TGT		= 0x1E | XPT_FC_QUEUED | XPT_FC_USER_CCB
+				       | XPT_FC_XPT_ONLY,
+				/* Scan Target */
+
 /* HBA engine commands 0x20->0x2F */
 	XPT_ENG_INQ		= 0x20 | XPT_FC_XPT_ONLY,
 				/* HBA engine feature inquiry */
diff -r 85c0fa25a2fc sys/cam/cam_xpt.c
--- a/sys/cam/cam_xpt.c	Fri May 14 15:55:34 2010 -0700
+++ b/sys/cam/cam_xpt.c	Fri May 14 18:14:46 2010 -0700
@@ -463,6 +463,13 @@
 		case XPT_PATH_INQ:
 		case XPT_ENG_INQ:
 		case XPT_SCAN_LUN:
+		case XPT_SCAN_TGT:
+			if (inccb->ccb_h.func_code == XPT_SCAN_TGT &&
+			    (inccb->ccb_h.target_id == CAM_TARGET_WILDCARD ||
+			    (inccb->ccb_h.target_lun != CAM_LUN_WILDCARD))) {
+				error = EINVAL;
+				break;
+			}
 
 			ccb = xpt_alloc_ccb();
 
@@ -839,11 +846,21 @@
 	struct ccb_hdr *hdr;
 
 	/* Prepare request */
-	if (ccb->ccb_h.path->target->target_id == CAM_TARGET_WILDCARD ||
+	if (ccb->ccb_h.path->target->target_id == CAM_TARGET_WILDCARD &&
 	    ccb->ccb_h.path->device->lun_id == CAM_LUN_WILDCARD)
 		ccb->ccb_h.func_code = XPT_SCAN_BUS;
-	else
+	else if (ccb->ccb_h.path->target->target_id != CAM_TARGET_WILDCARD &&
+	    ccb->ccb_h.path->device->lun_id == CAM_LUN_WILDCARD)
+		ccb->ccb_h.func_code = XPT_SCAN_TGT;
+	else if (ccb->ccb_h.path->target->target_id != CAM_TARGET_WILDCARD &&
+	    ccb->ccb_h.path->device->lun_id != CAM_LUN_WILDCARD)
 		ccb->ccb_h.func_code = XPT_SCAN_LUN;
+	else {
+		xpt_print(ccb->ccb_h.path, "illegal scan path\n");
+		xpt_free_path(ccb->ccb_h.path);
+		xpt_free_ccb(ccb);
+		return;
+	}
 	ccb->ccb_h.ppriv_ptr1 = ccb->ccb_h.cbfcnp;
 	ccb->ccb_h.cbfcnp = xpt_rescan_done;
 	xpt_setup_ccb(&ccb->ccb_h, ccb->ccb_h.path, CAM_PRIORITY_XPT);
diff -r 85c0fa25a2fc sys/cam/scsi/scsi_xpt.c
--- a/sys/cam/scsi/scsi_xpt.c	Fri May 14 15:55:34 2010 -0700
+++ b/sys/cam/scsi/scsi_xpt.c	Fri May 14 18:14:46 2010 -0700
@@ -1487,12 +1487,13 @@
 		  ("scsi_scan_bus\n"));
 	switch (request_ccb->ccb_h.func_code) {
 	case XPT_SCAN_BUS:
+	case XPT_SCAN_TGT:
 	{
 		scsi_scan_bus_info *scan_info;
 		union	ccb *work_ccb, *reset_ccb;
 		struct	cam_path *path;
 		u_int	i;
-		u_int	max_target;
+		u_int	low_target, max_target;
 		u_int	initiator_id;
 
 		/* Find out the characteristics of the bus */
@@ -1557,13 +1558,18 @@
 
 		/* Cache on our stack so we can work asynchronously */
 		max_target = scan_info->cpi->max_target;
+		low_target = 0;
 		initiator_id = scan_info->cpi->initiator_id;
 
 
 		/*
 		 * We can scan all targets in parallel, or do it sequentially.
 		 */
-		if (scan_info->cpi->hba_misc & PIM_SEQSCAN) {
+
+		if (request_ccb->ccb_h.func_code == XPT_SCAN_TGT) {
+			max_target = low_target = request_ccb->ccb_h.target_id;
+			scan_info->counter = 0;
+		} else if (scan_info->cpi->hba_misc & PIM_SEQSCAN) {
 			max_target = 0;
 			scan_info->counter = 0;
 		} else {
@@ -1573,7 +1579,7 @@
 			}
 		}
 
-		for (i = 0; i <= max_target; i++) {
+		for (i = low_target; i <= max_target; i++) {
 			cam_status status;
 			if (i == initiator_id)
 				continue;
@@ -1688,7 +1694,9 @@
 
  hop_again:
 			done = 0;
-			if (scan_info->cpi->hba_misc & PIM_SEQSCAN) {
+			if (scan_info->request_ccb->ccb_h.func_code == XPT_SCAN_TGT) {
+				done = 1;
+			} else if (scan_info->cpi->hba_misc & PIM_SEQSCAN) {
 				scan_info->counter++;
 				if (scan_info->counter ==
 				    scan_info->cpi->initiator_id) {
@@ -2009,6 +2017,7 @@
 		break;
 	}
 	case XPT_SCAN_BUS:
+	case XPT_SCAN_TGT:
 		scsi_scan_bus(start_ccb->ccb_h.path->periph, start_ccb);
 		break;
 	case XPT_SCAN_LUN:
diff -r 85c0fa25a2fc sys/dev/isp/isp_freebsd.c
--- a/sys/dev/isp/isp_freebsd.c	Fri May 14 15:55:34 2010 -0700
+++ b/sys/dev/isp/isp_freebsd.c	Fri May 14 18:14:46 2010 -0700
@@ -3886,19 +3889,14 @@
 	}
 
 	/*
-	 * Allocate a CCB, create a wildcard path for this bus/target and schedule a rescan.
+	 * Allocate a CCB, create a wildcard path for this target and schedule a rescan.
 	 */
 	ccb = xpt_alloc_ccb_nowait();
 	if (ccb == NULL) {
 		isp_prt(isp, ISP_LOGWARN, "Chan %d unable to alloc CCB for rescan", chan);
 		return;
 	}
-	/*
-	 * xpt_rescan only honors wildcard in the target field. 
-	 * Scan the whole bus instead of target, which will then
-	 * force a scan of all luns.
-	 */
-	if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, cam_sim_path(fc->sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
+	if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, cam_sim_path(fc->sim), tgt, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
 		isp_prt(isp, ISP_LOGWARN, "unable to create path for rescan");
 		xpt_free_ccb(ccb);
 		return;


More information about the freebsd-scsi mailing list