addition of an XPT_SCAN_TGT code

Matthew Jacob mj at feral.com
Sat May 15 01:15:36 UTC 2010


Sometimes, particularly in relation to a hotplug event, you just want to 
scan a target id, not the whole bus. It's lighter weight.

The attached patch adds this with a relatively light touch. I'm not 
super happy with it, but it does make rescanning on a target basis doable.

Comments?

-------------- 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	Fri May 14 18:14:46 2010 -0700
@@ -207,6 +207,10 @@
 				/* Notify Host Target driver of event */
 	XPT_NOTIFY_ACKNOWLEDGE	= 0x37 | XPT_FC_QUEUED | XPT_FC_USER_CCB,
 				/* Acknowledgement of event */
+/* overflow commands: 0x40 ->0x4F */
+	XPT_SCAN_TGT		= 0x40 | XPT_FC_QUEUED | XPT_FC_USER_CCB
+				       | XPT_FC_XPT_ONLY,
+				/* (Re)Scan the SCSI Bus */
 
 /* Vendor Unique codes: 0x80->0x8F */
 	XPT_VUNIQUE		= 0x80
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 (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
@@ -3898,7 +3898,7 @@
 	 * 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