Lines Matching +full:cmd +full:- +full:timeout +full:- +full:ms
2 /*-
3 * SPDX-License-Identifier: BSD-2-Clause
44 * http://www.usb.org/developers/devclass_docs/usbmass-ufi10.pdf
54 * - Command/Bulk/Interrupt (CBI)
55 * - Command/Bulk/Interrupt with Command Completion Interrupt (CBI with CCI)
56 * - Mass Storage Bulk-Only (BBB)
60 * - SCSI
61 * - UFI (floppy command set)
62 * - 8070i (ATAPI)
65 * sc->sc_transform method is used to convert the commands into the appropriate
72 * - probe/attach/detach
73 * - generic transfer routines
74 * - BBB
75 * - CBI
76 * - CBI_I (in addition to functions from CBI)
77 * - CAM (Common Access Method)
78 * - SCSI
79 * - UFI
80 * - 8070i (ATAPI)
148 (sc) ? (const char *)(sc)->sc_name : \
160 #define UDMASS_BBB 0x00200000 /* Bulk-Only transfers */
184 #define UMASS_T_BBB_RESET1 0 /* Bulk-Only */
218 #define DEVNAME_SIM "umass-sim"
226 #define UMASS_TIMEOUT 5000 /* ms */
233 /* Bulk-Only features */
235 #define UR_BBB_RESET 0xff /* Bulk-Only reset */
379 uint32_t data_timeout; /* ms */
408 uint32_t sc_proto; /* wire and cmd protocol */
497 .timeout = 5000, /* 5 seconds */
507 .timeout = 5000, /* 5 seconds */
517 .timeout = 5000, /* 5 seconds */
527 .timeout = 5000, /* 5 seconds */
537 .timeout = 0, /* overwritten later */
546 .timeout = 5000, /* 5 seconds */
556 .timeout = 0, /* overwritten later */
565 .timeout = 5000, /* 5 seconds */
575 .timeout = 5000, /* ms */
587 .timeout = 5000, /* 5 seconds */
597 .timeout = 5000, /* 5 seconds */
607 .timeout = 5000, /* 5 seconds */
618 .timeout = 5000, /* 5 seconds */
628 .timeout = 0, /* overwritten later */
637 .timeout = 5000, /* 5 seconds */
647 .timeout = 0, /* overwritten later */
656 .timeout = 5000, /* 5 seconds */
666 .timeout = 5000, /* ms */
675 .timeout = 5000, /* ms */
729 (id->bInterfaceClass != UICLASS_MASS)) {
732 switch (id->bInterfaceSubClass) {
750 switch (id->bInterfaceProtocol) {
776 uint32_t proto = umass_get_proto(uaa->iface);
873 if (uaa->usb_mode != USB_MODE_HOST) {
896 sc->sc_dev = dev;
897 sc->sc_udev = uaa->device;
898 sc->sc_proto = temp.proto;
899 sc->sc_quirks = temp.quirks;
900 sc->sc_unit = device_get_unit(dev);
902 snprintf(sc->sc_name, sizeof(sc->sc_name),
907 mtx_init(&sc->sc_mtx, device_get_nameunit(dev),
912 id = usbd_get_interface_descriptor(uaa->iface);
918 sc->sc_iface_no = id->bInterfaceNumber;
923 switch (sc->sc_proto & UMASS_PROTO_COMMAND) {
938 sc->sc_proto & UMASS_PROTO_COMMAND);
944 switch (sc->sc_proto & UMASS_PROTO_WIRE) {
946 printf("Bulk-Only");
956 sc->sc_proto & UMASS_PROTO_WIRE);
959 printf("; quirks = 0x%04x\n", sc->sc_quirks);
962 if (sc->sc_quirks & ALT_IFACE_1) {
964 (uaa->device, uaa->info.bIfaceIndex, 1);
974 if (sc->sc_proto & UMASS_PROTO_BBB) {
975 err = usbd_transfer_setup(uaa->device,
976 &uaa->info.bIfaceIndex, sc->sc_xfer, umass_bbb_config,
977 UMASS_T_BBB_MAX, sc, &sc->sc_mtx);
980 sc->sc_last_xfer_index = UMASS_T_BBB_COMMAND;
982 } else if (sc->sc_proto & (UMASS_PROTO_CBI | UMASS_PROTO_CBI_I)) {
983 err = usbd_transfer_setup(uaa->device,
984 &uaa->info.bIfaceIndex, sc->sc_xfer, umass_cbi_config,
985 UMASS_T_CBI_MAX, sc, &sc->sc_mtx);
988 sc->sc_last_xfer_index = UMASS_T_CBI_COMMAND;
1012 if (sc->sc_xfer[x] != NULL)
1013 usbd_xfer_set_interval(sc->sc_xfer[x], iv);
1017 sc->sc_transform =
1018 (sc->sc_proto & UMASS_PROTO_SCSI) ? &umass_scsi_transform :
1019 (sc->sc_proto & UMASS_PROTO_UFI) ? &umass_ufi_transform :
1020 (sc->sc_proto & UMASS_PROTO_ATAPI) ? &umass_atapi_transform :
1021 (sc->sc_proto & UMASS_PROTO_RBC) ? &umass_rbc_transform :
1026 if (sc->sc_quirks & SHUTTLE_INIT) {
1031 if (((sc->sc_proto & UMASS_PROTO_WIRE) == UMASS_PROTO_BBB) &&
1032 !(sc->sc_quirks & NO_GETMAXLUN))
1033 sc->sc_maxlun = umass_bbb_get_max_lun(sc);
1035 sc->sc_maxlun = 0;
1038 sc->cam_scsi_sense.opcode = REQUEST_SENSE;
1039 sc->cam_scsi_test_unit_ready.opcode = TEST_UNIT_READY;
1067 usbd_transfer_unsetup(sc->sc_xfer, UMASS_T_MAX);
1069 mtx_lock(&sc->sc_mtx);
1077 mtx_unlock(&sc->sc_mtx);
1079 mtx_destroy(&sc->sc_mtx);
1097 req.wIndex[0] = sc->sc_iface_no;
1100 usbd_do_request(sc->sc_udev, NULL, &req, &status);
1116 if (sc->sc_xfer[xfer_index]) {
1117 sc->sc_last_xfer_index = xfer_index;
1118 usbd_transfer_start(sc->sc_xfer[xfer_index]);
1132 usbd_transfer_stop(sc->sc_xfer[sc->sc_last_xfer_index]);
1141 USB_MTX_ASSERT(&sc->sc_mtx, MA_OWNED);
1143 ccb = sc->sc_transfer.ccb;
1144 sc->sc_transfer.ccb = NULL;
1145 sc->sc_last_xfer_index = 0;
1148 (sc->sc_transfer.callback)
1149 (sc, ccb, (sc->sc_transfer.data_len -
1150 sc->sc_transfer.actlen), STATUS_WIRE_FAILED);
1160 DPRINTF(sc, UDMASS_GEN, "transfer error, %s -> "
1187 * a) a Bulk-Only Mass Storage Reset
1188 * b) a Clear Feature HALT to the Bulk-In endpoint
1189 * c) a Clear Feature HALT to the Bulk-Out endpoint
1202 req.wIndex[0] = sc->sc_iface_no;
1247 if (usbd_clear_stall_callback(xfer, sc->sc_xfer[stall_xfer])) {
1262 union ccb *ccb = sc->sc_transfer.ccb;
1269 (sc, ((sc->sc_transfer.dir == DIR_IN) ? UMASS_T_BBB_DATA_READ :
1270 (sc->sc_transfer.dir == DIR_OUT) ? UMASS_T_BBB_DATA_WRITE :
1276 sc->sc_status_try = 0;
1283 tag = UGETDW(sc->cbw.dCBWTag) + 1;
1285 USETDW(sc->cbw.dCBWSignature, CBWSIGNATURE);
1286 USETDW(sc->cbw.dCBWTag, tag);
1297 USETDW(sc->cbw.dCBWDataTransferLength, sc->sc_transfer.data_len);
1302 * Bits 0-6 reserved
1303 * Bit 7 Direction - this bit shall be ignored if the
1308 sc->cbw.bCBWFlags = ((sc->sc_transfer.dir == DIR_IN) ?
1310 sc->cbw.bCBWLUN = sc->sc_transfer.lun;
1312 if (sc->sc_transfer.cmd_len > sizeof(sc->cbw.CBWCDB)) {
1313 sc->sc_transfer.cmd_len = sizeof(sc->cbw.CBWCDB);
1316 sc->cbw.bCDBLength = sc->sc_transfer.cmd_len;
1319 memcpy(sc->cbw.CBWCDB, sc->sc_transfer.cmd_data,
1320 sc->sc_transfer.cmd_len);
1323 memset(sc->cbw.CBWCDB +
1324 sc->sc_transfer.cmd_len, 0,
1325 sizeof(sc->cbw.CBWCDB) -
1326 sc->sc_transfer.cmd_len);
1328 DIF(UDMASS_BBB, umass_bbb_dump_cbw(sc, &sc->cbw));
1331 usbd_copy_in(pc, 0, &sc->cbw, sizeof(sc->cbw));
1332 usbd_xfer_set_frame_len(xfer, 0, sizeof(sc->cbw));
1355 sc->sc_transfer.data_rem -= actlen;
1356 sc->sc_transfer.data_ptr += actlen;
1357 sc->sc_transfer.actlen += actlen;
1361 sc->sc_transfer.data_rem = 0;
1365 max_bulk, sc->sc_transfer.data_rem);
1367 if (sc->sc_transfer.data_rem == 0) {
1371 if (max_bulk > sc->sc_transfer.data_rem) {
1372 max_bulk = sc->sc_transfer.data_rem;
1374 usbd_xfer_set_timeout(xfer, sc->sc_transfer.data_timeout);
1376 usbd_xfer_set_frame_data(xfer, 0, sc->sc_transfer.data_ptr,
1410 sc->sc_transfer.data_rem -= actlen;
1411 sc->sc_transfer.data_ptr += actlen;
1412 sc->sc_transfer.actlen += actlen;
1416 sc->sc_transfer.data_rem = 0;
1420 max_bulk, sc->sc_transfer.data_rem);
1422 if (sc->sc_transfer.data_rem == 0) {
1426 if (max_bulk > sc->sc_transfer.data_rem) {
1427 max_bulk = sc->sc_transfer.data_rem;
1429 usbd_xfer_set_timeout(xfer, sc->sc_transfer.data_timeout);
1431 usbd_xfer_set_frame_data(xfer, 0, sc->sc_transfer.data_ptr,
1458 union ccb *ccb = sc->sc_transfer.ccb;
1471 sc->sc_status_try = 1;
1475 if (actlen < (int)sizeof(sc->csw))
1476 memset(&sc->csw, 0, sizeof(sc->csw));
1479 usbd_copy_out(pc, 0, &sc->csw, actlen);
1481 DIF(UDMASS_BBB, umass_bbb_dump_csw(sc, &sc->csw));
1483 residue = UGETDW(sc->csw.dCSWDataResidue);
1485 if ((!residue) || (sc->sc_quirks & IGNORE_RESIDUE)) {
1486 residue = (sc->sc_transfer.data_len -
1487 sc->sc_transfer.actlen);
1489 if (residue > sc->sc_transfer.data_len) {
1491 "to %d bytes\n", residue, sc->sc_transfer.data_len);
1492 residue = sc->sc_transfer.data_len;
1494 /* translate weird command-status signatures: */
1495 if (sc->sc_quirks & WRONG_CSWSIG) {
1496 uint32_t temp = UGETDW(sc->csw.dCSWSignature);
1500 USETDW(sc->csw.dCSWSignature, CSWSIGNATURE);
1504 if (UGETDW(sc->csw.dCSWSignature) != CSWSIGNATURE) {
1506 UGETDW(sc->csw.dCSWSignature), CSWSIGNATURE);
1513 } else if (UGETDW(sc->csw.dCSWTag) != UGETDW(sc->cbw.dCBWTag)) {
1515 "0x%08x\n", UGETDW(sc->csw.dCSWTag),
1516 UGETDW(sc->cbw.dCBWTag));
1518 } else if (sc->csw.bCSWStatus > CSWSTATUS_PHASE) {
1520 sc->csw.bCSWStatus, CSWSTATUS_PHASE);
1522 } else if (sc->csw.bCSWStatus == CSWSTATUS_PHASE) {
1526 } else if (sc->sc_transfer.actlen > sc->sc_transfer.data_len) {
1528 sc->sc_transfer.actlen, sc->sc_transfer.data_len);
1530 } else if (sc->csw.bCSWStatus == CSWSTATUS_FAILED) {
1534 sc->sc_transfer.ccb = NULL;
1536 sc->sc_last_xfer_index = UMASS_T_BBB_COMMAND;
1538 (sc->sc_transfer.callback)
1541 sc->sc_transfer.ccb = NULL;
1543 sc->sc_last_xfer_index = UMASS_T_BBB_COMMAND;
1545 (sc->sc_transfer.callback)
1558 usbd_errstr(error), sc->sc_status_try);
1561 (sc->sc_status_try)) {
1564 sc->sc_status_try = 1;
1577 sc->sc_transfer.lun = ccb->ccb_h.target_lun;
1580 * NOTE: assumes that "sc->sc_transfer.cmd_data" and
1581 * "sc->sc_transfer.cmd_len" has been properly
1585 sc->sc_transfer.dir = data_len ? dir : DIR_NONE;
1586 sc->sc_transfer.data_ptr = data_ptr;
1587 sc->sc_transfer.data_len = data_len;
1588 sc->sc_transfer.data_rem = data_len;
1589 sc->sc_transfer.data_timeout = (data_timeout + UMASS_TIMEOUT);
1591 sc->sc_transfer.actlen = 0;
1592 sc->sc_transfer.callback = callback;
1593 sc->sc_transfer.ccb = ccb;
1595 if (sc->sc_xfer[sc->sc_last_xfer_index]) {
1596 usbd_transfer_start(sc->sc_xfer[sc->sc_last_xfer_index]);
1609 /* The Get Max Lun command is a class-specific request. */
1613 req.wIndex[0] = sc->sc_iface_no;
1617 err = usbd_do_request(sc->sc_udev, NULL, &req, &buf);
1623 sc->sc_name, usbd_errstr(err));
1635 if (sc->sc_xfer[UMASS_T_CBI_STATUS]) {
1638 union ccb *ccb = sc->sc_transfer.ccb;
1640 sc->sc_transfer.ccb = NULL;
1642 sc->sc_last_xfer_index = UMASS_T_CBI_COMMAND;
1644 (sc->sc_transfer.callback)
1645 (sc, ccb, (sc->sc_transfer.data_len -
1646 sc->sc_transfer.actlen), STATUS_CMD_UNKNOWN);
1684 req.wIndex[0] = sc->sc_iface_no;
1734 (xfer, (sc->sc_xfer[UMASS_T_CBI_RESET4] &&
1735 sc->sc_xfer[UMASS_T_CBI_STATUS]) ?
1764 if (usbd_clear_stall_callback(xfer, sc->sc_xfer[stall_xfer])) {
1779 union ccb *ccb = sc->sc_transfer.ccb;
1786 if (sc->sc_transfer.dir == DIR_NONE) {
1790 (sc, (sc->sc_transfer.dir == DIR_IN) ?
1808 req.wIndex[0] = sc->sc_iface_no;
1810 req.wLength[0] = sc->sc_transfer.cmd_len;
1816 usbd_copy_in(pc, 0, sc->sc_transfer.cmd_data,
1817 sc->sc_transfer.cmd_len);
1820 usbd_xfer_set_frame_len(xfer, 1, sc->sc_transfer.cmd_len);
1822 sc->sc_transfer.cmd_len ? 2 : 1);
1826 sc->sc_transfer.cmd_data,
1827 sc->sc_transfer.cmd_len));
1841 (sc->sc_transfer.callback == &umass_cam_cb)) {
1842 sc->sc_transfer.ccb = NULL;
1843 (sc->sc_transfer.callback)
1844 (sc, ccb, sc->sc_transfer.data_len,
1849 sc->sc_last_xfer_index = UMASS_T_CBI_COMMAND;
1866 sc->sc_transfer.data_rem -= actlen;
1867 sc->sc_transfer.data_ptr += actlen;
1868 sc->sc_transfer.actlen += actlen;
1872 sc->sc_transfer.data_rem = 0;
1876 max_bulk, sc->sc_transfer.data_rem);
1878 if (sc->sc_transfer.data_rem == 0) {
1882 if (max_bulk > sc->sc_transfer.data_rem) {
1883 max_bulk = sc->sc_transfer.data_rem;
1885 usbd_xfer_set_timeout(xfer, sc->sc_transfer.data_timeout);
1887 usbd_xfer_set_frame_data(xfer, 0, sc->sc_transfer.data_ptr,
1895 (sc->sc_transfer.callback != &umass_cam_cb)) {
1922 sc->sc_transfer.data_rem -= actlen;
1923 sc->sc_transfer.data_ptr += actlen;
1924 sc->sc_transfer.actlen += actlen;
1928 sc->sc_transfer.data_rem = 0;
1932 max_bulk, sc->sc_transfer.data_rem);
1934 if (sc->sc_transfer.data_rem == 0) {
1938 if (max_bulk > sc->sc_transfer.data_rem) {
1939 max_bulk = sc->sc_transfer.data_rem;
1941 usbd_xfer_set_timeout(xfer, sc->sc_transfer.data_timeout);
1943 usbd_xfer_set_frame_data(xfer, 0, sc->sc_transfer.data_ptr,
1951 (sc->sc_transfer.callback != &umass_cam_cb)) {
1971 union ccb *ccb = sc->sc_transfer.ccb;
1982 if (actlen < (int)sizeof(sc->sbl)) {
1986 usbd_copy_out(pc, 0, &sc->sbl, sizeof(sc->sbl));
1988 residue = (sc->sc_transfer.data_len -
1989 sc->sc_transfer.actlen);
1993 if (sc->sc_proto & UMASS_PROTO_UFI) {
2001 "ASCQ = 0x%02x\n", sc->sbl.ufi.asc,
2002 sc->sbl.ufi.ascq);
2004 status = (((sc->sbl.ufi.asc == 0) &&
2005 (sc->sbl.ufi.ascq == 0)) ?
2008 sc->sc_transfer.ccb = NULL;
2010 sc->sc_last_xfer_index = UMASS_T_CBI_COMMAND;
2012 (sc->sc_transfer.callback)
2021 sc->sbl.common.type, sc->sbl.common.value);
2023 if (sc->sbl.common.type == IDB_TYPE_CCI) {
2024 status = (sc->sbl.common.value & IDB_VALUE_STATUS_MASK);
2031 sc->sc_transfer.ccb = NULL;
2033 sc->sc_last_xfer_index = UMASS_T_CBI_COMMAND;
2035 (sc->sc_transfer.callback)
2079 sc->sc_sim = cam_sim_alloc
2083 sc->sc_unit /* unit number */ ,
2084 &sc->sc_mtx /* mutex */ ,
2089 if (sc->sc_sim == NULL) {
2094 mtx_lock(&sc->sc_mtx);
2095 status = xpt_bus_register(sc->sc_sim, sc->sc_dev, sc->sc_unit);
2097 cam_sim_free(sc->sc_sim, /* free_devq */ TRUE);
2098 mtx_unlock(&sc->sc_mtx);
2103 mtx_unlock(&sc->sc_mtx);
2115 sc->sc_name, cam_sim_path(sc->sc_sim),
2116 sc->sc_unit, cam_sim_path(sc->sc_sim));
2128 if (sc->sc_sim != NULL) {
2129 error = xpt_bus_deregister(cam_sim_path(sc->sc_sim));
2132 sc->sc_sim->softc = NULL;
2135 __func__, sc->sc_name, cam_sim_path(sc->sc_sim),
2136 sc->sc_unit, sc->sc_sim,
2137 sc->sc_sim->refcount, sc->sc_sim->mtx);
2138 cam_sim_free(sc->sc_sim, /* free_devq */ TRUE);
2141 __func__, sc->sc_name, error);
2143 sc->sc_sim = NULL;
2157 ccb->ccb_h.status = CAM_SEL_TIMEOUT;
2163 switch (ccb->ccb_h.func_code) {
2166 uint8_t *cmd;
2169 if (ccb->csio.ccb_h.flags & CAM_CDB_POINTER) {
2170 cmd = (uint8_t *)(ccb->csio.cdb_io.cdb_ptr);
2172 cmd = (uint8_t *)(ccb->csio.cdb_io.cdb_bytes);
2176 "cmd: 0x%02x, flags: 0x%02x, "
2177 "%db cmd/%db data/%db sense\n",
2178 cam_sim_path(sc->sc_sim), ccb->ccb_h.target_id,
2179 (uintmax_t)ccb->ccb_h.target_lun, cmd[0],
2180 ccb->ccb_h.flags & CAM_DIR_MASK, ccb->csio.cdb_len,
2181 ccb->csio.dxfer_len, ccb->csio.sense_len);
2183 if (sc->sc_transfer.ccb) {
2186 cam_sim_path(sc->sc_sim), ccb->ccb_h.target_id,
2187 (uintmax_t)ccb->ccb_h.target_lun);
2188 ccb->ccb_h.status = CAM_SCSI_BUSY;
2192 switch (ccb->ccb_h.flags & CAM_DIR_MASK) {
2199 umass_dump_buffer(sc, ccb->csio.data_ptr,
2200 ccb->csio.dxfer_len, 48));
2206 ccb->ccb_h.status = CAM_REQ_INPROG | CAM_SIM_QUEUED;
2209 * sc->sc_transform will convert the command to the
2212 * "sc->sc_transfer.cmd_data"
2214 if (umass_std_transform(sc, ccb, cmd, ccb->csio.cdb_len)) {
2215 if (sc->sc_transfer.cmd_data[0] == INQUIRY) {
2218 pserial = usb_get_serial(sc->sc_udev);
2224 if ((sc->sc_transfer.cmd_data[1] & SI_EVPD) &&
2225 (sc->sc_transfer.cmd_data[2] == SVPD_UNIT_SERIAL_NUMBER) &&
2229 vpd_serial = (struct scsi_vpd_unit_serial_number *)ccb->csio.data_ptr;
2230 vpd_serial->length = strlen(pserial);
2231 if (vpd_serial->length > sizeof(vpd_serial->serial_num))
2232 vpd_serial->length = sizeof(vpd_serial->serial_num);
2233 memcpy(vpd_serial->serial_num, pserial, vpd_serial->length);
2234 ccb->csio.scsi_status = SCSI_STATUS_OK;
2235 ccb->ccb_h.status = CAM_REQ_CMP;
2244 if ((sc->sc_quirks & (NO_INQUIRY_EVPD | NO_INQUIRY)) &&
2245 (sc->sc_transfer.cmd_data[1] & SI_EVPD)) {
2246 scsi_set_sense_data(&ccb->csio.sense_data,
2253 ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
2254 ccb->ccb_h.status =
2258 xpt_freeze_devq(ccb->ccb_h.path, 1);
2266 if (sc->sc_quirks & NO_INQUIRY) {
2267 memcpy(ccb->csio.data_ptr, &fake_inq_data,
2269 ccb->csio.scsi_status = SCSI_STATUS_OK;
2270 ccb->ccb_h.status = CAM_REQ_CMP;
2274 if (sc->sc_quirks & FORCE_SHORT_INQUIRY) {
2275 ccb->csio.dxfer_len = SHORT_INQUIRY_LENGTH;
2277 } else if (sc->sc_transfer.cmd_data[0] == PREVENT_ALLOW) {
2278 if (sc->sc_quirks & NO_PREVENT_ALLOW) {
2279 ccb->csio.scsi_status = SCSI_STATUS_OK;
2280 ccb->ccb_h.status = CAM_REQ_CMP;
2284 } else if (sc->sc_transfer.cmd_data[0] == SYNCHRONIZE_CACHE) {
2285 if (sc->sc_quirks & NO_SYNCHRONIZE_CACHE) {
2286 ccb->csio.scsi_status = SCSI_STATUS_OK;
2287 ccb->ccb_h.status = CAM_REQ_CMP;
2291 } else if (sc->sc_transfer.cmd_data[0] == START_STOP_UNIT) {
2292 if (sc->sc_quirks & NO_START_STOP) {
2293 ccb->csio.scsi_status = SCSI_STATUS_OK;
2294 ccb->ccb_h.status = CAM_REQ_CMP;
2299 umass_command_start(sc, dir, ccb->csio.data_ptr,
2300 ccb->csio.dxfer_len,
2301 ccb->ccb_h.timeout,
2308 struct ccb_pathinq *cpi = &ccb->cpi;
2311 sc ? cam_sim_path(sc->sc_sim) : -1, ccb->ccb_h.target_id,
2312 (uintmax_t)ccb->ccb_h.target_lun);
2315 cpi->version_num = 1;
2316 cpi->hba_inquiry = 0;
2317 cpi->target_sprt = 0;
2318 cpi->hba_misc = PIM_NO_6_BYTE;
2319 cpi->hba_eng_cnt = 0;
2320 cpi->max_target = UMASS_SCSIID_MAX; /* one target */
2321 cpi->initiator_id = UMASS_SCSIID_HOST;
2322 strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
2323 strlcpy(cpi->hba_vid, "USB SCSI", HBA_IDLEN);
2324 strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
2325 cpi->unit_number = cam_sim_unit(sim);
2326 cpi->bus_id = sc->sc_unit;
2327 cpi->protocol = PROTO_SCSI;
2328 cpi->protocol_version = SCSI_REV_2;
2329 cpi->transport = XPORT_USB;
2330 cpi->transport_version = 0;
2333 cpi->base_transfer_speed = 0;
2334 cpi->max_lun = 0;
2336 if (sc->sc_quirks & FLOPPY_SPEED) {
2337 cpi->base_transfer_speed =
2340 switch (usbd_get_speed(sc->sc_udev)) {
2342 cpi->base_transfer_speed =
2344 cpi->maxio = maxphys;
2347 cpi->base_transfer_speed =
2351 cpi->base_transfer_speed =
2356 cpi->max_lun = sc->sc_maxlun;
2359 cpi->ccb_h.status = CAM_REQ_CMP;
2366 cam_sim_path(sc->sc_sim), ccb->ccb_h.target_id,
2367 (uintmax_t)ccb->ccb_h.target_lun);
2371 ccb->ccb_h.status = CAM_REQ_CMP;
2377 struct ccb_trans_settings *cts = &ccb->cts;
2380 cam_sim_path(sc->sc_sim), ccb->ccb_h.target_id,
2381 (uintmax_t)ccb->ccb_h.target_lun);
2383 cts->protocol = PROTO_SCSI;
2384 cts->protocol_version = SCSI_REV_2;
2385 cts->transport = XPORT_USB;
2386 cts->transport_version = 0;
2387 cts->xport_specific.valid = 0;
2389 ccb->ccb_h.status = CAM_REQ_CMP;
2396 cam_sim_path(sc->sc_sim), ccb->ccb_h.target_id,
2397 (uintmax_t)ccb->ccb_h.target_lun);
2399 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
2405 cam_calc_geometry(&ccb->ccg, /* extended */ 1);
2412 sc ? cam_sim_path(sc->sc_sim) : -1, ccb->ccb_h.target_id,
2413 (uintmax_t)ccb->ccb_h.target_lun);
2415 ccb->ccb_h.status = CAM_REQ_CMP;
2422 sc ? cam_sim_path(sc->sc_sim) : -1, ccb->ccb_h.target_id,
2423 (uintmax_t)ccb->ccb_h.target_lun, ccb->ccb_h.func_code);
2425 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
2444 usbd_transfer_poll(sc->sc_xfer, UMASS_T_MAX);
2455 ccb->csio.resid = residue;
2459 ccb->ccb_h.status = CAM_REQ_CMP;
2460 if ((sc->sc_quirks & READ_CAPACITY_OFFBY1) &&
2461 (ccb->ccb_h.func_code == XPT_SCSI_IO) &&
2462 (ccb->csio.cdb_io.cdb_bytes[0] == READ_CAPACITY)) {
2466 rcap = (void *)(ccb->csio.data_ptr);
2467 maxsector = scsi_4btoul(rcap->addr) - 1;
2468 scsi_ulto4b(maxsector, rcap->addr);
2472 * of pages supported by the device - otherwise, CAM
2476 if (ccb->ccb_h.func_code == XPT_SCSI_IO &&
2477 sc->sc_transfer.cmd_data[0] == INQUIRY &&
2478 (sc->sc_transfer.cmd_data[1] & SI_EVPD) &&
2479 sc->sc_transfer.cmd_data[2] == SVPD_SUPPORTED_PAGE_LIST &&
2480 (usb_get_serial(sc->sc_udev)[0] != '\0')) {
2484 csio = &ccb->csio;
2485 page_list = (struct scsi_vpd_supported_page_list *)csio->data_ptr;
2486 if (page_list->length + 1 < SVPD_SUPPORTED_PAGES_SIZE) {
2487 page_list->list[page_list->length] = SVPD_UNIT_SERIAL_NUMBER;
2488 page_list->length++;
2500 sc->cam_scsi_sense.length = ccb->csio.sense_len;
2503 "sense data\n", ccb->csio.sense_len);
2505 if (umass_std_transform(sc, ccb, &sc->cam_scsi_sense.opcode,
2506 sizeof(sc->cam_scsi_sense))) {
2507 if ((sc->sc_quirks & FORCE_SHORT_INQUIRY) &&
2508 (sc->sc_transfer.cmd_data[0] == INQUIRY)) {
2509 ccb->csio.sense_len = SHORT_INQUIRY_LENGTH;
2511 umass_command_start(sc, DIR_IN, &ccb->csio.sense_data.error_code,
2512 ccb->csio.sense_len, ccb->ccb_h.timeout,
2523 xpt_freeze_devq(ccb->ccb_h.path, 1);
2524 ccb->ccb_h.status = CAM_REQ_CMP_ERR | CAM_DEV_QFRZN;
2537 uint8_t *cmd;
2545 ccb->csio.sense_resid = residue;
2546 sense_len = ccb->csio.sense_len - ccb->csio.sense_resid;
2547 key = scsi_get_sense_key(&ccb->csio.sense_data, sense_len,
2550 if (ccb->csio.ccb_h.flags & CAM_CDB_POINTER) {
2551 cmd = (uint8_t *)(ccb->csio.cdb_io.cdb_ptr);
2553 cmd = (uint8_t *)(ccb->csio.cdb_io.cdb_bytes);
2560 if ((sc->sc_quirks & RS_NO_CLEAR_UA) &&
2561 (cmd[0] == INQUIRY) &&
2569 ccb->ccb_h.status = CAM_REQ_CMP;
2575 ccb->ccb_h.status = CAM_REQ_CMP;
2576 } else if ((sc->sc_quirks & RS_NO_CLEAR_UA) &&
2577 (cmd[0] == READ_CAPACITY) &&
2587 xpt_freeze_devq(ccb->ccb_h.path, 1);
2588 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR
2590 ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
2600 if ((sc->sc_transform)(sc,
2601 &sc->cam_scsi_test_unit_ready.opcode,
2602 sizeof(sc->cam_scsi_test_unit_ready)) == 1) {
2604 ccb->ccb_h.timeout,
2609 xpt_freeze_devq(ccb->ccb_h.path, 1);
2611 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR
2613 ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
2615 ccb->ccb_h.status = CAM_AUTOSENSE_FAIL
2624 xpt_freeze_devq(ccb->ccb_h.path, 1);
2625 ccb->ccb_h.status = CAM_AUTOSENSE_FAIL | CAM_DEV_QFRZN;
2631 * This completion code just handles the fact that we sent a test-unit-ready
2654 (cmd_len > sizeof(sc->sc_transfer.cmd_data))) {
2659 sc->sc_transfer.cmd_len = cmd_len;
2663 if (sc->sc_quirks & NO_TEST_UNIT_READY) {
2666 memset(sc->sc_transfer.cmd_data, 0, cmd_len);
2667 sc->sc_transfer.cmd_data[0] = START_STOP_UNIT;
2668 sc->sc_transfer.cmd_data[4] = SSS_START;
2678 if (sc->sc_quirks & FORCE_SHORT_INQUIRY) {
2679 memcpy(sc->sc_transfer.cmd_data, cmd_ptr, cmd_len);
2680 sc->sc_transfer.cmd_data[4] = SHORT_INQUIRY_LENGTH;
2686 memcpy(sc->sc_transfer.cmd_data, cmd_ptr, cmd_len);
2694 (cmd_len > sizeof(sc->sc_transfer.cmd_data))) {
2720 memcpy(sc->sc_transfer.cmd_data, cmd_ptr, cmd_len);
2722 if ((sc->sc_quirks & RBC_PAD_TO_12) && (cmd_len < 12)) {
2723 memset(sc->sc_transfer.cmd_data + cmd_len,
2724 0, 12 - cmd_len);
2727 sc->sc_transfer.cmd_len = cmd_len;
2743 (cmd_len > sizeof(sc->sc_transfer.cmd_data))) {
2749 sc->sc_transfer.cmd_len = UFI_COMMAND_LENGTH;
2752 memset(sc->sc_transfer.cmd_data, 0, UFI_COMMAND_LENGTH);
2761 if (sc->sc_quirks & NO_TEST_UNIT_READY) {
2769 sc->sc_transfer.cmd_data[0] = START_STOP_UNIT;
2770 sc->sc_transfer.cmd_data[4] = SSS_START;
2809 memcpy(sc->sc_transfer.cmd_data, cmd_ptr, cmd_len);
2821 (cmd_len > sizeof(sc->sc_transfer.cmd_data))) {
2827 sc->sc_transfer.cmd_len = ATAPI_COMMAND_LENGTH;
2830 memset(sc->sc_transfer.cmd_data, 0, ATAPI_COMMAND_LENGTH);
2843 if (sc->sc_quirks & FORCE_SHORT_INQUIRY) {
2844 memcpy(sc->sc_transfer.cmd_data, cmd_ptr, cmd_len);
2846 sc->sc_transfer.cmd_data[4] = SHORT_INQUIRY_LENGTH;
2852 if (sc->sc_quirks & NO_TEST_UNIT_READY) {
2855 sc->sc_transfer.cmd_data[0] = START_STOP_UNIT;
2856 sc->sc_transfer.cmd_data[4] = SSS_START;
2900 "command 0x%02x - trying anyway\n",
2905 memcpy(sc->sc_transfer.cmd_data, cmd_ptr, cmd_len);
2910 umass_no_transform(struct umass_softc *sc, uint8_t *cmd,
2918 uint8_t *cmd, uint8_t cmdlen)
2922 retval = (sc->sc_transform) (sc, cmd, cmdlen);
2925 ccb->ccb_h.status = CAM_REQ_CMP;
2929 xpt_freeze_devq(ccb->ccb_h.path, 1);
2930 ccb->ccb_h.status = CAM_REQ_INVALID | CAM_DEV_QFRZN;
2942 uint8_t *c = cbw->CBWCDB;
2944 uint32_t dlen = UGETDW(cbw->dCBWDataTransferLength);
2945 uint32_t tag = UGETDW(cbw->dCBWTag);
2947 uint8_t clen = cbw->bCDBLength;
2948 uint8_t flags = cbw->bCBWFlags;
2949 uint8_t lun = cbw->bCBWLUN;
2951 DPRINTF(sc, UDMASS_BBB, "CBW %d: cmd = %db "
2963 uint32_t sig = UGETDW(csw->dCSWSignature);
2964 uint32_t tag = UGETDW(csw->dCSWTag);
2965 uint32_t res = UGETDW(csw->dCSWDataResidue);
2966 uint8_t status = csw->bCSWStatus;
2978 umass_cbi_dump_cmd(struct umass_softc *sc, void *cmd, uint8_t cmdlen)
2980 uint8_t *c = cmd;
2981 uint8_t dir = sc->sc_transfer.dir;
2983 DPRINTF(sc, UDMASS_BBB, "cmd = %db "
2988 sc->sc_transfer.data_len,