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