svn commit: r208582 - in head/sys: cam cam/ata cam/scsi dev/isp

Matt Jacob mjacob at FreeBSD.org
Wed May 26 22:49:42 UTC 2010


Author: mjacob
Date: Wed May 26 22:49:42 2010
New Revision: 208582
URL: http://svn.freebsd.org/changeset/base/208582

Log:
  Add a new primitive, XPT_SCAN_TGT, to cover the range between scanning a
  whole bus (XPT_SCAN_BUS) and a single lun on that bus (XPT_SCAN_LUN).
  
  It's less resource comsumptive than scanning a whole bus when the
  caller knows only one target has changes.
  
  Reviewed by:	scsi@
  Sponsored by:	Panasas
  MFC after:	1 month

Modified:
  head/sys/cam/ata/ata_xpt.c
  head/sys/cam/cam_ccb.h
  head/sys/cam/cam_xpt.c
  head/sys/cam/scsi/scsi_xpt.c
  head/sys/dev/isp/isp_freebsd.c

Modified: head/sys/cam/ata/ata_xpt.c
==============================================================================
--- head/sys/cam/ata/ata_xpt.c	Wed May 26 22:38:45 2010	(r208581)
+++ head/sys/cam/ata/ata_xpt.c	Wed May 26 22:49:42 2010	(r208582)
@@ -1185,6 +1185,7 @@ ata_scan_bus(struct cam_periph *periph, 
 		  ("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) {
@@ -1526,6 +1527,7 @@ ata_action(union ccb *start_ccb)
 		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:

Modified: head/sys/cam/cam_ccb.h
==============================================================================
--- head/sys/cam/cam_ccb.h	Wed May 26 22:38:45 2010	(r208581)
+++ head/sys/cam/cam_ccb.h	Wed May 26 22:49:42 2010	(r208582)
@@ -184,6 +184,11 @@ typedef enum {
 				/*
 				 * 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 */

Modified: head/sys/cam/cam_xpt.c
==============================================================================
--- head/sys/cam/cam_xpt.c	Wed May 26 22:38:45 2010	(r208581)
+++ head/sys/cam/cam_xpt.c	Wed May 26 22:49:42 2010	(r208582)
@@ -446,23 +446,36 @@ xptioctl(struct cdev *dev, u_long cmd, c
 		inccb = (union ccb *)addr;
 
 		bus = xpt_find_bus(inccb->ccb_h.path_id);
-		if (bus == NULL) {
-			error = EINVAL;
+		if (bus == NULL)
+			return (EINVAL);
+
+		switch (inccb->ccb_h.func_code) {
+		case XPT_SCAN_BUS:
+		case XPT_RESET_BUS:
+			if (inccb->ccb_h.target_id != CAM_TARGET_WILDCARD ||
+			    inccb->ccb_h.target_lun != CAM_LUN_WILDCARD) {
+				xpt_release_bus(bus);
+				return (EINVAL);
+			}
+			break;
+		case XPT_SCAN_TGT:
+			if (inccb->ccb_h.target_id == CAM_TARGET_WILDCARD ||
+			    inccb->ccb_h.target_lun != CAM_LUN_WILDCARD) {
+				xpt_release_bus(bus);
+				return (EINVAL);
+			}
+			break;
+		default:
 			break;
 		}
 
 		switch(inccb->ccb_h.func_code) {
 		case XPT_SCAN_BUS:
 		case XPT_RESET_BUS:
-			if ((inccb->ccb_h.target_id != CAM_TARGET_WILDCARD)
-			 || (inccb->ccb_h.target_lun != CAM_LUN_WILDCARD)) {
-				error = EINVAL;
-				break;
-			}
-			/* FALLTHROUGH */
 		case XPT_PATH_INQ:
 		case XPT_ENG_INQ:
 		case XPT_SCAN_LUN:
+		case XPT_SCAN_TGT:
 
 			ccb = xpt_alloc_ccb();
 
@@ -839,11 +852,21 @@ xpt_rescan(union ccb *ccb)
 	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);

Modified: head/sys/cam/scsi/scsi_xpt.c
==============================================================================
--- head/sys/cam/scsi/scsi_xpt.c	Wed May 26 22:38:45 2010	(r208581)
+++ head/sys/cam/scsi/scsi_xpt.c	Wed May 26 22:49:42 2010	(r208582)
@@ -1494,12 +1494,13 @@ scsi_scan_bus(struct cam_periph *periph,
 		  ("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 */
@@ -1564,13 +1565,18 @@ scsi_scan_bus(struct cam_periph *periph,
 
 		/* 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 {
@@ -1580,7 +1586,7 @@ scsi_scan_bus(struct cam_periph *periph,
 			}
 		}
 
-		for (i = 0; i <= max_target; i++) {
+		for (i = low_target; i <= max_target; i++) {
 			cam_status status;
 			if (i == initiator_id)
 				continue;
@@ -1695,7 +1701,9 @@ scsi_scan_bus(struct cam_periph *periph,
 
  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) {
@@ -2016,6 +2024,7 @@ scsi_action(union ccb *start_ccb)
 		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:

Modified: head/sys/dev/isp/isp_freebsd.c
==============================================================================
--- head/sys/dev/isp/isp_freebsd.c	Wed May 26 22:38:45 2010	(r208581)
+++ head/sys/dev/isp/isp_freebsd.c	Wed May 26 22:49:42 2010	(r208582)
@@ -3893,19 +3893,14 @@ isp_make_here(ispsoftc_t *isp, int chan,
 	}
 
 	/*
-	 * 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 svn-src-all mailing list