PERFORCE change 160419 for review

Scott Long scottl at FreeBSD.org
Thu Apr 9 16:12:58 PDT 2009


http://perforce.freebsd.org/chv.cgi?CH=160419

Change 160419 by scottl at scottl-deimos on 2009/04/09 23:11:56

	Move XPT_SCSI_IO handling back into cam_xpt.c, since it's a protocol
	issue and not a transport issue, it needs to stay in common code.
	Provide the beginnings of a default transport.  Have
	xpt_register_bus() do an XPT_PATH_INQ on the SIM as its registering,
	and select a transport based on the returned cpi.tranport attribute.
	When this transitions to newbus, the whole cpi will be provided to
	the transport probe and attach routines.

Affected files ...

.. //depot/projects/scottl-camlock/src/sys/cam/cam_xpt.c#85 edit
.. //depot/projects/scottl-camlock/src/sys/cam/scsi/scsi_xpt.c#12 edit

Differences ...

==== //depot/projects/scottl-camlock/src/sys/cam/cam_xpt.c#85 (text+ko) ====

@@ -274,6 +274,14 @@
 static int		xpt_for_all_busses(xpt_busfunc_t *tr_func, void *arg);
 static int		xpt_for_all_devices(xpt_devicefunc_t *tr_func,
 					    void *arg);
+static void		xpt_dev_async_default(u_int32_t async_code,
+					      struct cam_eb *bus,
+					      struct cam_et *target,
+					      struct cam_ed *device,
+					      void *async_arg);
+static struct cam_ed *	xpt_alloc_device_default(struct cam_eb *bus,
+						 struct cam_et *target,
+						 lun_id_t lun_id);
 static xpt_devicefunc_t	xptsetasyncfunc;
 static xpt_busfunc_t	xptsetasyncbusfunc;
 static cam_status	xptregister(struct cam_periph *periph,
@@ -2391,6 +2399,47 @@
 
 
 	switch (start_ccb->ccb_h.func_code) {
+	case XPT_SCSI_IO:
+	{
+		struct cam_ed *device;
+#ifdef CAMDEBUG
+		char cdb_str[(SCSI_MAX_CDBLEN * 3) + 1];
+		struct cam_path *path;
+
+		path = start_ccb->ccb_h.path;
+#endif
+
+		/*
+		 * For the sake of compatibility with SCSI-1
+		 * devices that may not understand the identify
+		 * message, we include lun information in the
+		 * second byte of all commands.  SCSI-1 specifies
+		 * that luns are a 3 bit value and reserves only 3
+		 * bits for lun information in the CDB.  Later
+		 * revisions of the SCSI spec allow for more than 8
+		 * luns, but have deprecated lun information in the
+		 * CDB.  So, if the lun won't fit, we must omit.
+		 *
+		 * Also be aware that during initial probing for devices,
+		 * the inquiry information is unknown but initialized to 0.
+		 * This means that this code will be exercised while probing
+		 * devices with an ANSI revision greater than 2.
+		 */
+		device = start_ccb->ccb_h.path->device;
+		if (device->protocol_version <= SCSI_REV_2
+		 && start_ccb->ccb_h.target_lun < 8
+		 && (start_ccb->ccb_h.flags & CAM_CDB_POINTER) == 0) {
+
+			start_ccb->csio.cdb_io.cdb_bytes[1] |=
+			    start_ccb->ccb_h.target_lun << 5;
+		}
+		start_ccb->csio.scsi_status = SCSI_STATUS_OK;
+		CAM_DEBUG(path, CAM_DEBUG_CDB,("%s. CDB: %s\n",
+			  scsi_op_desc(start_ccb->csio.cdb_io.cdb_bytes[0],
+			  	       &path->device->inq_data),
+			  scsi_cdb_string(start_ccb->csio.cdb_io.cdb_bytes,
+					  cdb_str, sizeof(cdb_str))));
+	}
 	/* FALLTHROUGH */
 	case XPT_TARGET_IO:
 	case XPT_CONT_TARGET_IO:
@@ -3649,6 +3698,12 @@
 
 /* Functions accessed by SIM drivers */
 
+static struct xpt_xport xport_default = {
+	.alloc_device = xpt_alloc_device_default,
+	.action = xpt_action_default,
+	.async = xpt_dev_async_default,
+};
+
 /*
  * A sim structure, listing the SIM entry points and instance
  * identification info is passed to xpt_bus_register to hook the SIM
@@ -3664,6 +3719,8 @@
 	struct cam_eb *new_bus;
 	struct cam_eb *old_bus;
 	struct ccb_pathinq cpi;
+	struct cam_path path;
+	cam_status status;
 
 	mtx_assert(sim->mtx, MA_OWNED);
 
@@ -3675,10 +3732,7 @@
 		return (CAM_RESRC_UNAVAIL);
 	}
 
-	new_bus->xport = scsi_get_xport();
-
 	if (strcmp(sim->sim_name, "xpt") != 0) {
-
 		sim->path_id =
 		    xptpathid(sim->sim_name, sim->unit_number, sim->bus_id);
 	}
@@ -3691,6 +3745,7 @@
 	new_bus->flags = 0;
 	new_bus->refcount = 1;	/* Held until a bus_deregister event */
 	new_bus->generation = 0;
+
 	mtx_lock(&xsoftc.xpt_topo_lock);
 	old_bus = TAILQ_FIRST(&xsoftc.xpt_busses);
 	while (old_bus != NULL
@@ -3703,18 +3758,43 @@
 	xsoftc.bus_generation++;
 	mtx_unlock(&xsoftc.xpt_topo_lock);
 
+	/*
+	 * Set a default transport so that a PATH_INQ can be issued to
+	 * the SIM.  This will then allow for probing and attaching of
+	 * a more appropriate transport.
+	 */
+	new_bus->xport = &xport_default;
+
+	bzero(&path, sizeof(path));
+	status = xpt_compile_path(&path, /*periph*/NULL, sim->path_id,
+				  CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);
+	if (status != CAM_REQ_CMP)
+		printf("xpt_compile_path returned %d\n", status);
+
+	xpt_print_path(&path);
+	
+	xpt_setup_ccb(&cpi.ccb_h, &path, /*priority*/1);
+	cpi.ccb_h.func_code = XPT_PATH_INQ;
+	xpt_action((union ccb *)&cpi);
+
+	if (cpi.ccb_h.status == CAM_REQ_CMP) {
+		switch (cpi.transport) {
+		case XPORT_SPI:
+		case XPORT_SAS:
+		case XPORT_FC:
+			new_bus->xport = scsi_get_xport();
+			break;
+		default:
+			new_bus->xport = &xport_default;
+			break;
+		}
+	}
+
 	/* Notify interested parties */
 	if (sim->path_id != CAM_XPT_PATH_ID) {
-		struct cam_path path;
-
-		xpt_compile_path(&path, /*periph*/NULL, sim->path_id,
-			         CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);
-		xpt_setup_ccb(&cpi.ccb_h, &path, /*priority*/1);
-		cpi.ccb_h.func_code = XPT_PATH_INQ;
-		xpt_action((union ccb *)&cpi);
 		xpt_async(AC_PATH_REGISTERED, &path, &cpi);
-		xpt_release_path(&path);
 	}
+	xpt_release_path(&path);
 	return (CAM_SUCCESS);
 }
 
@@ -3908,6 +3988,14 @@
 	}
 }
 
+static void
+xpt_dev_async_default(u_int32_t async_code, struct cam_eb *bus,
+		      struct cam_et *target, struct cam_ed *device,
+		      void *async_arg)
+{
+	printf("xpt_dev_async called\n");
+}
+
 u_int32_t
 xpt_freeze_devq(struct cam_path *path, u_int count)
 {
@@ -4219,6 +4307,32 @@
 	}
 }
 
+static struct cam_ed *
+xpt_alloc_device_default(struct cam_eb *bus, struct cam_et *target,
+			 lun_id_t lun_id)
+{
+	struct cam_ed *device, *cur_device;
+
+	device = xpt_alloc_device(bus, target, lun_id);
+	if (device == NULL)
+		return (NULL);
+
+	device->mintags = 1;
+	device->maxtags = 1;
+	bus->sim->max_ccbs = device->ccbq.devq_openings;
+	cur_device = TAILQ_FIRST(&target->ed_entries);
+	while (cur_device != NULL && cur_device->lun_id < lun_id)
+		cur_device = TAILQ_NEXT(cur_device, links);
+	if (cur_device != NULL) {
+		TAILQ_INSERT_BEFORE(cur_device, device, links);
+	} else {
+		TAILQ_INSERT_TAIL(&target->ed_entries, device, links);
+	}
+	target->generation++;
+
+	return (device);
+}
+
 struct cam_ed *
 xpt_alloc_device(struct cam_eb *bus, struct cam_et *target, lun_id_t lun_id)
 {

==== //depot/projects/scottl-camlock/src/sys/cam/scsi/scsi_xpt.c#12 (text+ko) ====

@@ -1969,62 +1969,6 @@
 {
 
 	switch (start_ccb->ccb_h.func_code) {
-	case XPT_SCSI_IO:
-	{
-		struct cam_ed *device;
-#ifdef CAMDEBUG
-		char cdb_str[(SCSI_MAX_CDBLEN * 3) + 1];
-		struct cam_path *path;
-
-		path = start_ccb->ccb_h.path;
-#endif
-
-		/*
-		 * For the sake of compatibility with SCSI-1
-		 * devices that may not understand the identify
-		 * message, we include lun information in the
-		 * second byte of all commands.  SCSI-1 specifies
-		 * that luns are a 3 bit value and reserves only 3
-		 * bits for lun information in the CDB.  Later
-		 * revisions of the SCSI spec allow for more than 8
-		 * luns, but have deprecated lun information in the
-		 * CDB.  So, if the lun won't fit, we must omit.
-		 *
-		 * Also be aware that during initial probing for devices,
-		 * the inquiry information is unknown but initialized to 0.
-		 * This means that this code will be exercised while probing
-		 * devices with an ANSI revision greater than 2.
-		 */
-		device = start_ccb->ccb_h.path->device;
-		if (device->protocol_version <= SCSI_REV_2
-		 && start_ccb->ccb_h.target_lun < 8
-		 && (start_ccb->ccb_h.flags & CAM_CDB_POINTER) == 0) {
-
-			start_ccb->csio.cdb_io.cdb_bytes[1] |=
-			    start_ccb->ccb_h.target_lun << 5;
-		}
-		start_ccb->csio.scsi_status = SCSI_STATUS_OK;
-		CAM_DEBUG(path, CAM_DEBUG_CDB,("%s. CDB: %s\n",
-			  scsi_op_desc(start_ccb->csio.cdb_io.cdb_bytes[0],
-			  	       &path->device->inq_data),
-			  scsi_cdb_string(start_ccb->csio.cdb_io.cdb_bytes,
-					  cdb_str, sizeof(cdb_str))));
-	}
-	{
-		struct cam_path *path;
-		int runq;
-
-		path = start_ccb->ccb_h.path;
-
-		cam_ccbq_insert_ccb(&path->device->ccbq, start_ccb);
-		if (path->device->qfrozen_cnt == 0)
-			runq = xpt_schedule_dev_sendq(path->bus, path->device);
-		else
-			runq = 0;
-		if (runq != 0)
-			xpt_run_dev_sendq(path->bus);
-		break;
-	}
 	case XPT_SET_TRAN_SETTINGS:
 	{
 		scsi_set_transfer_settings(&start_ccb->cts,


More information about the p4-projects mailing list