Date: Thu, 9 Apr 2009 23:12:54 GMT From: Scott Long <scottl@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 160419 for review Message-ID: <200904092312.n39NCsLg004688@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=160419 Change 160419 by scottl@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,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200904092312.n39NCsLg004688>
