Lines Matching +full:sig +full:- +full:dir +full:- +full:cmd
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
43 * http://www.usb.org/developers/devclass_docs/usbmass-ufi10.pdf
53 * - Command/Bulk/Interrupt (CBI)
54 * - Command/Bulk/Interrupt with Command Completion Interrupt (CBI with CCI)
55 * - Mass Storage Bulk-Only (BBB)
59 * - SCSI
60 * - UFI (floppy command set)
61 * - 8070i (ATAPI)
64 * sc->sc_transform method is used to convert the commands into the appropriate
71 * - probe/attach/detach
72 * - generic transfer routines
73 * - BBB
74 * - CBI
75 * - CBI_I (in addition to functions from CBI)
76 * - CAM (Common Access Method)
77 * - SCSI
78 * - UFI
79 * - 8070i (ATAPI)
147 (sc) ? (const char *)(sc)->sc_name : \
159 #define UDMASS_BBB 0x00200000 /* Bulk-Only transfers */
183 #define UMASS_T_BBB_RESET1 0 /* Bulk-Only */
217 #define DEVNAME_SIM "umass-sim"
232 /* Bulk-Only features */
234 #define UR_BBB_RESET 0xff /* Bulk-Only reset */
403 uint8_t dir; member
427 uint32_t sc_proto; /* wire and cmd protocol */
749 (id->bInterfaceClass != UICLASS_MASS)) { in umass_get_proto()
752 switch (id->bInterfaceSubClass) { in umass_get_proto()
770 switch (id->bInterfaceProtocol) { in umass_get_proto()
796 uint32_t proto = umass_get_proto(uaa->iface); in umass_probe_proto()
893 if (uaa->usb_mode != USB_MODE_HOST) { in umass_probe()
916 sc->sc_dev = dev; in umass_attach()
917 sc->sc_udev = uaa->device; in umass_attach()
918 sc->sc_proto = temp.proto; in umass_attach()
919 sc->sc_quirks = temp.quirks; in umass_attach()
920 sc->sc_unit = device_get_unit(dev); in umass_attach()
922 snprintf(sc->sc_name, sizeof(sc->sc_name), in umass_attach()
927 mtx_init(&sc->sc_mtx, device_get_nameunit(dev), in umass_attach()
932 id = usbd_get_interface_descriptor(uaa->iface); in umass_attach()
938 sc->sc_iface_no = id->bInterfaceNumber; in umass_attach()
943 switch (sc->sc_proto & UMASS_PROTO_COMMAND) { in umass_attach()
958 sc->sc_proto & UMASS_PROTO_COMMAND); in umass_attach()
964 switch (sc->sc_proto & UMASS_PROTO_WIRE) { in umass_attach()
966 printf("Bulk-Only"); in umass_attach()
976 sc->sc_proto & UMASS_PROTO_WIRE); in umass_attach()
979 printf("; quirks = 0x%b\n", sc->sc_quirks, UMASS_QUIRKS_STRING); in umass_attach()
982 if (sc->sc_quirks & ALT_IFACE_1) { in umass_attach()
984 (uaa->device, uaa->info.bIfaceIndex, 1); in umass_attach()
994 if (sc->sc_proto & UMASS_PROTO_BBB) { in umass_attach()
995 err = usbd_transfer_setup(uaa->device, in umass_attach()
996 &uaa->info.bIfaceIndex, sc->sc_xfer, umass_bbb_config, in umass_attach()
997 UMASS_T_BBB_MAX, sc, &sc->sc_mtx); in umass_attach()
1000 sc->sc_last_xfer_index = UMASS_T_BBB_COMMAND; in umass_attach()
1002 } else if (sc->sc_proto & (UMASS_PROTO_CBI | UMASS_PROTO_CBI_I)) { in umass_attach()
1003 err = usbd_transfer_setup(uaa->device, in umass_attach()
1004 &uaa->info.bIfaceIndex, sc->sc_xfer, umass_cbi_config, in umass_attach()
1005 UMASS_T_CBI_MAX, sc, &sc->sc_mtx); in umass_attach()
1008 sc->sc_last_xfer_index = UMASS_T_CBI_COMMAND; in umass_attach()
1032 if (sc->sc_xfer[x] != NULL) in umass_attach()
1033 usbd_xfer_set_interval(sc->sc_xfer[x], iv); in umass_attach()
1037 sc->sc_transform = in umass_attach()
1038 (sc->sc_proto & UMASS_PROTO_SCSI) ? &umass_scsi_transform : in umass_attach()
1039 (sc->sc_proto & UMASS_PROTO_UFI) ? &umass_ufi_transform : in umass_attach()
1040 (sc->sc_proto & UMASS_PROTO_ATAPI) ? &umass_atapi_transform : in umass_attach()
1041 (sc->sc_proto & UMASS_PROTO_RBC) ? &umass_rbc_transform : in umass_attach()
1046 if (sc->sc_quirks & SHUTTLE_INIT) { in umass_attach()
1051 if (((sc->sc_proto & UMASS_PROTO_WIRE) == UMASS_PROTO_BBB) && in umass_attach()
1052 !(sc->sc_quirks & NO_GETMAXLUN)) in umass_attach()
1053 sc->sc_maxlun = umass_bbb_get_max_lun(sc); in umass_attach()
1055 sc->sc_maxlun = 0; in umass_attach()
1058 sc->cam_scsi_sense.opcode = REQUEST_SENSE; in umass_attach()
1059 sc->cam_scsi_test_unit_ready.opcode = TEST_UNIT_READY; in umass_attach()
1087 usbd_transfer_unsetup(sc->sc_xfer, UMASS_T_MAX); in umass_detach()
1089 mtx_lock(&sc->sc_mtx); in umass_detach()
1097 mtx_unlock(&sc->sc_mtx); in umass_detach()
1099 mtx_destroy(&sc->sc_mtx); in umass_detach()
1117 req.wIndex[0] = sc->sc_iface_no; in umass_init_shuttle()
1120 usbd_do_request(sc->sc_udev, NULL, &req, &status); in umass_init_shuttle()
1136 if (sc->sc_xfer[xfer_index]) { in umass_transfer_start()
1137 sc->sc_last_xfer_index = xfer_index; in umass_transfer_start()
1138 usbd_transfer_start(sc->sc_xfer[xfer_index]); in umass_transfer_start()
1152 usbd_transfer_stop(sc->sc_xfer[sc->sc_last_xfer_index]); in umass_reset()
1161 USB_MTX_ASSERT(&sc->sc_mtx, MA_OWNED); in umass_cancel_ccb()
1163 ccb = sc->sc_transfer.ccb; in umass_cancel_ccb()
1164 sc->sc_transfer.ccb = NULL; in umass_cancel_ccb()
1165 sc->sc_last_xfer_index = 0; in umass_cancel_ccb()
1168 (sc->sc_transfer.callback) in umass_cancel_ccb()
1169 (sc, ccb, (sc->sc_transfer.data_len - in umass_cancel_ccb()
1170 sc->sc_transfer.actlen), STATUS_WIRE_FAILED); in umass_cancel_ccb()
1180 DPRINTF(sc, UDMASS_GEN, "transfer error, %s -> " in umass_tr_error()
1207 * a) a Bulk-Only Mass Storage Reset in umass_t_bbb_reset1_callback()
1208 * b) a Clear Feature HALT to the Bulk-In endpoint in umass_t_bbb_reset1_callback()
1209 * c) a Clear Feature HALT to the Bulk-Out endpoint in umass_t_bbb_reset1_callback()
1222 req.wIndex[0] = sc->sc_iface_no; in umass_t_bbb_reset1_callback()
1267 if (usbd_clear_stall_callback(xfer, sc->sc_xfer[stall_xfer])) { in umass_t_bbb_data_clear_stall_callback()
1282 union ccb *ccb = sc->sc_transfer.ccb; in umass_t_bbb_command_callback()
1289 (sc, ((sc->sc_transfer.dir == DIR_IN) ? UMASS_T_BBB_DATA_READ : in umass_t_bbb_command_callback()
1290 (sc->sc_transfer.dir == DIR_OUT) ? UMASS_T_BBB_DATA_WRITE : in umass_t_bbb_command_callback()
1296 sc->sc_status_try = 0; in umass_t_bbb_command_callback()
1303 tag = UGETDW(sc->cbw.dCBWTag) + 1; in umass_t_bbb_command_callback()
1305 USETDW(sc->cbw.dCBWSignature, CBWSIGNATURE); in umass_t_bbb_command_callback()
1306 USETDW(sc->cbw.dCBWTag, tag); in umass_t_bbb_command_callback()
1317 USETDW(sc->cbw.dCBWDataTransferLength, sc->sc_transfer.data_len); in umass_t_bbb_command_callback()
1322 * Bits 0-6 reserved in umass_t_bbb_command_callback()
1323 * Bit 7 Direction - this bit shall be ignored if the in umass_t_bbb_command_callback()
1328 sc->cbw.bCBWFlags = ((sc->sc_transfer.dir == DIR_IN) ? in umass_t_bbb_command_callback()
1330 sc->cbw.bCBWLUN = sc->sc_transfer.lun; in umass_t_bbb_command_callback()
1332 if (sc->sc_transfer.cmd_len > sizeof(sc->cbw.CBWCDB)) { in umass_t_bbb_command_callback()
1333 sc->sc_transfer.cmd_len = sizeof(sc->cbw.CBWCDB); in umass_t_bbb_command_callback()
1336 sc->cbw.bCDBLength = sc->sc_transfer.cmd_len; in umass_t_bbb_command_callback()
1339 memcpy(sc->cbw.CBWCDB, sc->sc_transfer.cmd_data, in umass_t_bbb_command_callback()
1340 sc->sc_transfer.cmd_len); in umass_t_bbb_command_callback()
1343 memset(sc->cbw.CBWCDB + in umass_t_bbb_command_callback()
1344 sc->sc_transfer.cmd_len, 0, in umass_t_bbb_command_callback()
1345 sizeof(sc->cbw.CBWCDB) - in umass_t_bbb_command_callback()
1346 sc->sc_transfer.cmd_len); in umass_t_bbb_command_callback()
1348 DIF(UDMASS_BBB, umass_bbb_dump_cbw(sc, &sc->cbw)); in umass_t_bbb_command_callback()
1351 usbd_copy_in(pc, 0, &sc->cbw, sizeof(sc->cbw)); in umass_t_bbb_command_callback()
1352 usbd_xfer_set_frame_len(xfer, 0, sizeof(sc->cbw)); in umass_t_bbb_command_callback()
1375 sc->sc_transfer.data_rem -= actlen; in umass_t_bbb_data_read_callback()
1376 sc->sc_transfer.data_ptr += actlen; in umass_t_bbb_data_read_callback()
1377 sc->sc_transfer.actlen += actlen; in umass_t_bbb_data_read_callback()
1381 sc->sc_transfer.data_rem = 0; in umass_t_bbb_data_read_callback()
1385 max_bulk, sc->sc_transfer.data_rem); in umass_t_bbb_data_read_callback()
1387 if (sc->sc_transfer.data_rem == 0) { in umass_t_bbb_data_read_callback()
1391 if (max_bulk > sc->sc_transfer.data_rem) { in umass_t_bbb_data_read_callback()
1392 max_bulk = sc->sc_transfer.data_rem; in umass_t_bbb_data_read_callback()
1394 usbd_xfer_set_timeout(xfer, sc->sc_transfer.data_timeout); in umass_t_bbb_data_read_callback()
1396 usbd_xfer_set_frame_data(xfer, 0, sc->sc_transfer.data_ptr, in umass_t_bbb_data_read_callback()
1430 sc->sc_transfer.data_rem -= actlen; in umass_t_bbb_data_write_callback()
1431 sc->sc_transfer.data_ptr += actlen; in umass_t_bbb_data_write_callback()
1432 sc->sc_transfer.actlen += actlen; in umass_t_bbb_data_write_callback()
1436 sc->sc_transfer.data_rem = 0; in umass_t_bbb_data_write_callback()
1440 max_bulk, sc->sc_transfer.data_rem); in umass_t_bbb_data_write_callback()
1442 if (sc->sc_transfer.data_rem == 0) { in umass_t_bbb_data_write_callback()
1446 if (max_bulk > sc->sc_transfer.data_rem) { in umass_t_bbb_data_write_callback()
1447 max_bulk = sc->sc_transfer.data_rem; in umass_t_bbb_data_write_callback()
1449 usbd_xfer_set_timeout(xfer, sc->sc_transfer.data_timeout); in umass_t_bbb_data_write_callback()
1451 usbd_xfer_set_frame_data(xfer, 0, sc->sc_transfer.data_ptr, in umass_t_bbb_data_write_callback()
1478 union ccb *ccb = sc->sc_transfer.ccb; in umass_t_bbb_status_callback()
1491 sc->sc_status_try = 1; in umass_t_bbb_status_callback()
1495 if (actlen < (int)sizeof(sc->csw)) in umass_t_bbb_status_callback()
1496 memset(&sc->csw, 0, sizeof(sc->csw)); in umass_t_bbb_status_callback()
1499 usbd_copy_out(pc, 0, &sc->csw, actlen); in umass_t_bbb_status_callback()
1501 DIF(UDMASS_BBB, umass_bbb_dump_csw(sc, &sc->csw)); in umass_t_bbb_status_callback()
1503 residue = UGETDW(sc->csw.dCSWDataResidue); in umass_t_bbb_status_callback()
1505 if ((!residue) || (sc->sc_quirks & IGNORE_RESIDUE)) { in umass_t_bbb_status_callback()
1506 residue = (sc->sc_transfer.data_len - in umass_t_bbb_status_callback()
1507 sc->sc_transfer.actlen); in umass_t_bbb_status_callback()
1509 if (residue > sc->sc_transfer.data_len) { in umass_t_bbb_status_callback()
1511 "to %d bytes\n", residue, sc->sc_transfer.data_len); in umass_t_bbb_status_callback()
1512 residue = sc->sc_transfer.data_len; in umass_t_bbb_status_callback()
1514 /* translate weird command-status signatures: */ in umass_t_bbb_status_callback()
1515 if (sc->sc_quirks & WRONG_CSWSIG) { in umass_t_bbb_status_callback()
1516 uint32_t temp = UGETDW(sc->csw.dCSWSignature); in umass_t_bbb_status_callback()
1520 USETDW(sc->csw.dCSWSignature, CSWSIGNATURE); in umass_t_bbb_status_callback()
1524 if (UGETDW(sc->csw.dCSWSignature) != CSWSIGNATURE) { in umass_t_bbb_status_callback()
1526 UGETDW(sc->csw.dCSWSignature), CSWSIGNATURE); in umass_t_bbb_status_callback()
1533 } else if (UGETDW(sc->csw.dCSWTag) != UGETDW(sc->cbw.dCBWTag)) { in umass_t_bbb_status_callback()
1535 "0x%08x\n", UGETDW(sc->csw.dCSWTag), in umass_t_bbb_status_callback()
1536 UGETDW(sc->cbw.dCBWTag)); in umass_t_bbb_status_callback()
1538 } else if (sc->csw.bCSWStatus > CSWSTATUS_PHASE) { in umass_t_bbb_status_callback()
1540 sc->csw.bCSWStatus, CSWSTATUS_PHASE); in umass_t_bbb_status_callback()
1542 } else if (sc->csw.bCSWStatus == CSWSTATUS_PHASE) { in umass_t_bbb_status_callback()
1546 } else if (sc->sc_transfer.actlen > sc->sc_transfer.data_len) { in umass_t_bbb_status_callback()
1548 sc->sc_transfer.actlen, sc->sc_transfer.data_len); in umass_t_bbb_status_callback()
1550 } else if (sc->csw.bCSWStatus == CSWSTATUS_FAILED) { in umass_t_bbb_status_callback()
1554 sc->sc_transfer.ccb = NULL; in umass_t_bbb_status_callback()
1556 sc->sc_last_xfer_index = UMASS_T_BBB_COMMAND; in umass_t_bbb_status_callback()
1558 (sc->sc_transfer.callback) in umass_t_bbb_status_callback()
1561 sc->sc_transfer.ccb = NULL; in umass_t_bbb_status_callback()
1563 sc->sc_last_xfer_index = UMASS_T_BBB_COMMAND; in umass_t_bbb_status_callback()
1565 (sc->sc_transfer.callback) in umass_t_bbb_status_callback()
1578 usbd_errstr(error), sc->sc_status_try); in umass_t_bbb_status_callback()
1581 (sc->sc_status_try)) { in umass_t_bbb_status_callback()
1584 sc->sc_status_try = 1; in umass_t_bbb_status_callback()
1592 umass_command_start(struct umass_softc *sc, uint8_t dir, in umass_command_start() argument
1597 sc->sc_transfer.lun = ccb->ccb_h.target_lun; in umass_command_start()
1600 * NOTE: assumes that "sc->sc_transfer.cmd_data" and in umass_command_start()
1601 * "sc->sc_transfer.cmd_len" has been properly in umass_command_start()
1605 sc->sc_transfer.dir = data_len ? dir : DIR_NONE; in umass_command_start()
1606 sc->sc_transfer.data_ptr = data_ptr; in umass_command_start()
1607 sc->sc_transfer.data_len = data_len; in umass_command_start()
1608 sc->sc_transfer.data_rem = data_len; in umass_command_start()
1609 sc->sc_transfer.data_timeout = (data_timeout + UMASS_TIMEOUT); in umass_command_start()
1611 sc->sc_transfer.actlen = 0; in umass_command_start()
1612 sc->sc_transfer.callback = callback; in umass_command_start()
1613 sc->sc_transfer.ccb = ccb; in umass_command_start()
1615 if (sc->sc_xfer[sc->sc_last_xfer_index]) { in umass_command_start()
1616 usbd_transfer_start(sc->sc_xfer[sc->sc_last_xfer_index]); in umass_command_start()
1629 /* The Get Max Lun command is a class-specific request. */ in umass_bbb_get_max_lun()
1633 req.wIndex[0] = sc->sc_iface_no; in umass_bbb_get_max_lun()
1637 err = usbd_do_request(sc->sc_udev, NULL, &req, &buf); in umass_bbb_get_max_lun()
1643 sc->sc_name, usbd_errstr(err)); in umass_bbb_get_max_lun()
1655 if (sc->sc_xfer[UMASS_T_CBI_STATUS]) { in umass_cbi_start_status()
1658 union ccb *ccb = sc->sc_transfer.ccb; in umass_cbi_start_status()
1660 sc->sc_transfer.ccb = NULL; in umass_cbi_start_status()
1662 sc->sc_last_xfer_index = UMASS_T_CBI_COMMAND; in umass_cbi_start_status()
1664 (sc->sc_transfer.callback) in umass_cbi_start_status()
1665 (sc, ccb, (sc->sc_transfer.data_len - in umass_cbi_start_status()
1666 sc->sc_transfer.actlen), STATUS_CMD_UNKNOWN); in umass_cbi_start_status()
1704 req.wIndex[0] = sc->sc_iface_no; in umass_t_cbi_reset1_callback()
1754 (xfer, (sc->sc_xfer[UMASS_T_CBI_RESET4] && in umass_t_cbi_reset3_callback()
1755 sc->sc_xfer[UMASS_T_CBI_STATUS]) ? in umass_t_cbi_reset3_callback()
1784 if (usbd_clear_stall_callback(xfer, sc->sc_xfer[stall_xfer])) { in umass_t_cbi_data_clear_stall_callback()
1799 union ccb *ccb = sc->sc_transfer.ccb; in umass_t_cbi_command_callback()
1806 if (sc->sc_transfer.dir == DIR_NONE) { in umass_t_cbi_command_callback()
1810 (sc, (sc->sc_transfer.dir == DIR_IN) ? in umass_t_cbi_command_callback()
1828 req.wIndex[0] = sc->sc_iface_no; in umass_t_cbi_command_callback()
1830 req.wLength[0] = sc->sc_transfer.cmd_len; in umass_t_cbi_command_callback()
1836 usbd_copy_in(pc, 0, sc->sc_transfer.cmd_data, in umass_t_cbi_command_callback()
1837 sc->sc_transfer.cmd_len); in umass_t_cbi_command_callback()
1840 usbd_xfer_set_frame_len(xfer, 1, sc->sc_transfer.cmd_len); in umass_t_cbi_command_callback()
1842 sc->sc_transfer.cmd_len ? 2 : 1); in umass_t_cbi_command_callback()
1846 sc->sc_transfer.cmd_data, in umass_t_cbi_command_callback()
1847 sc->sc_transfer.cmd_len)); in umass_t_cbi_command_callback()
1861 (sc->sc_transfer.callback == &umass_cam_cb)) { in umass_t_cbi_command_callback()
1862 sc->sc_transfer.ccb = NULL; in umass_t_cbi_command_callback()
1863 (sc->sc_transfer.callback) in umass_t_cbi_command_callback()
1864 (sc, ccb, sc->sc_transfer.data_len, in umass_t_cbi_command_callback()
1869 sc->sc_last_xfer_index = UMASS_T_CBI_COMMAND; in umass_t_cbi_command_callback()
1886 sc->sc_transfer.data_rem -= actlen; in umass_t_cbi_data_read_callback()
1887 sc->sc_transfer.data_ptr += actlen; in umass_t_cbi_data_read_callback()
1888 sc->sc_transfer.actlen += actlen; in umass_t_cbi_data_read_callback()
1892 sc->sc_transfer.data_rem = 0; in umass_t_cbi_data_read_callback()
1896 max_bulk, sc->sc_transfer.data_rem); in umass_t_cbi_data_read_callback()
1898 if (sc->sc_transfer.data_rem == 0) { in umass_t_cbi_data_read_callback()
1902 if (max_bulk > sc->sc_transfer.data_rem) { in umass_t_cbi_data_read_callback()
1903 max_bulk = sc->sc_transfer.data_rem; in umass_t_cbi_data_read_callback()
1905 usbd_xfer_set_timeout(xfer, sc->sc_transfer.data_timeout); in umass_t_cbi_data_read_callback()
1907 usbd_xfer_set_frame_data(xfer, 0, sc->sc_transfer.data_ptr, in umass_t_cbi_data_read_callback()
1915 (sc->sc_transfer.callback != &umass_cam_cb)) { in umass_t_cbi_data_read_callback()
1942 sc->sc_transfer.data_rem -= actlen; in umass_t_cbi_data_write_callback()
1943 sc->sc_transfer.data_ptr += actlen; in umass_t_cbi_data_write_callback()
1944 sc->sc_transfer.actlen += actlen; in umass_t_cbi_data_write_callback()
1948 sc->sc_transfer.data_rem = 0; in umass_t_cbi_data_write_callback()
1952 max_bulk, sc->sc_transfer.data_rem); in umass_t_cbi_data_write_callback()
1954 if (sc->sc_transfer.data_rem == 0) { in umass_t_cbi_data_write_callback()
1958 if (max_bulk > sc->sc_transfer.data_rem) { in umass_t_cbi_data_write_callback()
1959 max_bulk = sc->sc_transfer.data_rem; in umass_t_cbi_data_write_callback()
1961 usbd_xfer_set_timeout(xfer, sc->sc_transfer.data_timeout); in umass_t_cbi_data_write_callback()
1963 usbd_xfer_set_frame_data(xfer, 0, sc->sc_transfer.data_ptr, in umass_t_cbi_data_write_callback()
1971 (sc->sc_transfer.callback != &umass_cam_cb)) { in umass_t_cbi_data_write_callback()
1991 union ccb *ccb = sc->sc_transfer.ccb; in umass_t_cbi_status_callback()
2002 if (actlen < (int)sizeof(sc->sbl)) { in umass_t_cbi_status_callback()
2006 usbd_copy_out(pc, 0, &sc->sbl, sizeof(sc->sbl)); in umass_t_cbi_status_callback()
2008 residue = (sc->sc_transfer.data_len - in umass_t_cbi_status_callback()
2009 sc->sc_transfer.actlen); in umass_t_cbi_status_callback()
2013 if (sc->sc_proto & UMASS_PROTO_UFI) { in umass_t_cbi_status_callback()
2019 * non-zero, in which case we should succeed. in umass_t_cbi_status_callback()
2023 "ASCQ = 0x%02x\n", sc->sbl.ufi.asc, in umass_t_cbi_status_callback()
2024 sc->sbl.ufi.ascq); in umass_t_cbi_status_callback()
2026 if ((sc->sbl.ufi.asc == 0 && sc->sbl.ufi.ascq == 0) || in umass_t_cbi_status_callback()
2027 sc->sc_transfer.cmd_data[0] == REQUEST_SENSE) in umass_t_cbi_status_callback()
2032 sc->sc_transfer.ccb = NULL; in umass_t_cbi_status_callback()
2034 sc->sc_last_xfer_index = UMASS_T_CBI_COMMAND; in umass_t_cbi_status_callback()
2036 (sc->sc_transfer.callback) in umass_t_cbi_status_callback()
2045 sc->sbl.common.type, sc->sbl.common.value); in umass_t_cbi_status_callback()
2047 if (sc->sbl.common.type == IDB_TYPE_CCI) { in umass_t_cbi_status_callback()
2048 status = (sc->sbl.common.value & IDB_VALUE_STATUS_MASK); in umass_t_cbi_status_callback()
2055 sc->sc_transfer.ccb = NULL; in umass_t_cbi_status_callback()
2057 sc->sc_last_xfer_index = UMASS_T_CBI_COMMAND; in umass_t_cbi_status_callback()
2059 (sc->sc_transfer.callback) in umass_t_cbi_status_callback()
2103 sc->sc_sim = cam_sim_alloc in umass_cam_attach_sim()
2107 sc->sc_unit /* unit number */ , in umass_cam_attach_sim()
2108 &sc->sc_mtx /* mutex */ , in umass_cam_attach_sim()
2113 if (sc->sc_sim == NULL) { in umass_cam_attach_sim()
2118 mtx_lock(&sc->sc_mtx); in umass_cam_attach_sim()
2119 status = xpt_bus_register(sc->sc_sim, sc->sc_dev, sc->sc_unit); in umass_cam_attach_sim()
2121 cam_sim_free(sc->sc_sim, /* free_devq */ TRUE); in umass_cam_attach_sim()
2122 mtx_unlock(&sc->sc_mtx); in umass_cam_attach_sim()
2127 mtx_unlock(&sc->sc_mtx); in umass_cam_attach_sim()
2139 sc->sc_name, cam_sim_path(sc->sc_sim), in umass_cam_attach()
2140 sc->sc_unit, cam_sim_path(sc->sc_sim)); in umass_cam_attach()
2152 if (sc->sc_sim != NULL) { in umass_cam_detach_sim()
2153 error = xpt_bus_deregister(cam_sim_path(sc->sc_sim)); in umass_cam_detach_sim()
2156 sc->sc_sim->softc = NULL; in umass_cam_detach_sim()
2159 __func__, sc->sc_name, cam_sim_path(sc->sc_sim), in umass_cam_detach_sim()
2160 sc->sc_unit, sc->sc_sim, in umass_cam_detach_sim()
2161 sc->sc_sim->refcount, sc->sc_sim->mtx); in umass_cam_detach_sim()
2162 cam_sim_free(sc->sc_sim, /* free_devq */ TRUE); in umass_cam_detach_sim()
2165 __func__, sc->sc_name, error); in umass_cam_detach_sim()
2167 sc->sc_sim = NULL; in umass_cam_detach_sim()
2181 ccb->ccb_h.status = CAM_SEL_TIMEOUT; in umass_cam_action()
2187 switch (ccb->ccb_h.func_code) { in umass_cam_action()
2190 uint8_t *cmd; in umass_cam_action() local
2191 uint8_t dir; in umass_cam_action() local
2193 if (ccb->csio.ccb_h.flags & CAM_CDB_POINTER) { in umass_cam_action()
2194 cmd = (uint8_t *)(ccb->csio.cdb_io.cdb_ptr); in umass_cam_action()
2196 cmd = (uint8_t *)(ccb->csio.cdb_io.cdb_bytes); in umass_cam_action()
2200 "cmd: 0x%02x, flags: 0x%02x, " in umass_cam_action()
2201 "%db cmd/%db data/%db sense\n", in umass_cam_action()
2202 cam_sim_path(sc->sc_sim), ccb->ccb_h.target_id, in umass_cam_action()
2203 (uintmax_t)ccb->ccb_h.target_lun, cmd[0], in umass_cam_action()
2204 ccb->ccb_h.flags & CAM_DIR_MASK, ccb->csio.cdb_len, in umass_cam_action()
2205 ccb->csio.dxfer_len, ccb->csio.sense_len); in umass_cam_action()
2207 if (sc->sc_transfer.ccb) { in umass_cam_action()
2210 cam_sim_path(sc->sc_sim), ccb->ccb_h.target_id, in umass_cam_action()
2211 (uintmax_t)ccb->ccb_h.target_lun); in umass_cam_action()
2212 ccb->ccb_h.status = CAM_SCSI_BUSY; in umass_cam_action()
2216 switch (ccb->ccb_h.flags & CAM_DIR_MASK) { in umass_cam_action()
2218 dir = DIR_IN; in umass_cam_action()
2221 dir = DIR_OUT; in umass_cam_action()
2223 umass_dump_buffer(sc, ccb->csio.data_ptr, in umass_cam_action()
2224 ccb->csio.dxfer_len, 48)); in umass_cam_action()
2227 dir = DIR_NONE; in umass_cam_action()
2230 ccb->ccb_h.status = CAM_REQ_INPROG | CAM_SIM_QUEUED; in umass_cam_action()
2233 * sc->sc_transform will convert the command to the in umass_cam_action()
2236 * "sc->sc_transfer.cmd_data" in umass_cam_action()
2245 if (umass_std_transform(sc, ccb, cmd, ccb->csio.cdb_len)) { in umass_cam_action()
2246 if (sc->sc_transfer.cmd_data[0] == INQUIRY) { in umass_cam_action()
2249 pserial = usb_get_serial(sc->sc_udev); in umass_cam_action()
2255 if ((sc->sc_transfer.cmd_data[1] & SI_EVPD) && in umass_cam_action()
2256 (sc->sc_transfer.cmd_data[2] == SVPD_UNIT_SERIAL_NUMBER) && in umass_cam_action()
2260 vpd_serial = (struct scsi_vpd_unit_serial_number *)ccb->csio.data_ptr; in umass_cam_action()
2261 vpd_serial->length = strlen(pserial); in umass_cam_action()
2262 if (vpd_serial->length > sizeof(vpd_serial->serial_num)) in umass_cam_action()
2263 vpd_serial->length = sizeof(vpd_serial->serial_num); in umass_cam_action()
2264 memcpy(vpd_serial->serial_num, pserial, vpd_serial->length); in umass_cam_action()
2265 ccb->csio.scsi_status = SCSI_STATUS_OK; in umass_cam_action()
2266 ccb->ccb_h.status = CAM_REQ_CMP; in umass_cam_action()
2275 if ((sc->sc_quirks & (NO_INQUIRY_EVPD | NO_INQUIRY)) && in umass_cam_action()
2276 (sc->sc_transfer.cmd_data[1] & SI_EVPD)) { in umass_cam_action()
2284 if (sc->sc_quirks & NO_INQUIRY) { in umass_cam_action()
2285 memcpy(ccb->csio.data_ptr, &fake_inq_data, in umass_cam_action()
2287 ccb->csio.scsi_status = SCSI_STATUS_OK; in umass_cam_action()
2288 ccb->ccb_h.status = CAM_REQ_CMP; in umass_cam_action()
2292 if (sc->sc_quirks & FORCE_SHORT_INQUIRY) { in umass_cam_action()
2293 ccb->csio.dxfer_len = SHORT_INQUIRY_LENGTH; in umass_cam_action()
2295 } else if (sc->sc_transfer.cmd_data[0] == PREVENT_ALLOW) { in umass_cam_action()
2296 if (sc->sc_quirks & NO_PREVENT_ALLOW) { in umass_cam_action()
2297 ccb->csio.scsi_status = SCSI_STATUS_OK; in umass_cam_action()
2298 ccb->ccb_h.status = CAM_REQ_CMP; in umass_cam_action()
2302 } else if (sc->sc_transfer.cmd_data[0] == SYNCHRONIZE_CACHE) { in umass_cam_action()
2303 if (sc->sc_quirks & NO_SYNCHRONIZE_CACHE) { in umass_cam_action()
2307 } else if (sc->sc_transfer.cmd_data[0] == START_STOP_UNIT) { in umass_cam_action()
2308 if (sc->sc_quirks & NO_START_STOP) { in umass_cam_action()
2309 ccb->csio.scsi_status = SCSI_STATUS_OK; in umass_cam_action()
2310 ccb->ccb_h.status = CAM_REQ_CMP; in umass_cam_action()
2315 umass_command_start(sc, dir, ccb->csio.data_ptr, in umass_cam_action()
2316 ccb->csio.dxfer_len, in umass_cam_action()
2317 ccb->ccb_h.timeout, in umass_cam_action()
2324 struct ccb_pathinq *cpi = &ccb->cpi; in umass_cam_action()
2327 sc ? cam_sim_path(sc->sc_sim) : -1, ccb->ccb_h.target_id, in umass_cam_action()
2328 (uintmax_t)ccb->ccb_h.target_lun); in umass_cam_action()
2331 cpi->version_num = 1; in umass_cam_action()
2332 cpi->hba_inquiry = 0; in umass_cam_action()
2333 cpi->target_sprt = 0; in umass_cam_action()
2334 cpi->hba_misc = PIM_NO_6_BYTE; in umass_cam_action()
2335 cpi->hba_eng_cnt = 0; in umass_cam_action()
2336 cpi->max_target = UMASS_SCSIID_MAX; /* one target */ in umass_cam_action()
2337 cpi->initiator_id = UMASS_SCSIID_HOST; in umass_cam_action()
2338 strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); in umass_cam_action()
2339 strlcpy(cpi->hba_vid, "USB SCSI", HBA_IDLEN); in umass_cam_action()
2340 strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); in umass_cam_action()
2341 cpi->unit_number = cam_sim_unit(sim); in umass_cam_action()
2342 cpi->bus_id = sc->sc_unit; in umass_cam_action()
2343 cpi->protocol = PROTO_SCSI; in umass_cam_action()
2344 cpi->protocol_version = SCSI_REV_2; in umass_cam_action()
2345 cpi->transport = XPORT_USB; in umass_cam_action()
2346 cpi->transport_version = 0; in umass_cam_action()
2349 cpi->base_transfer_speed = 0; in umass_cam_action()
2350 cpi->max_lun = 0; in umass_cam_action()
2352 if (sc->sc_quirks & FLOPPY_SPEED) { in umass_cam_action()
2353 cpi->base_transfer_speed = in umass_cam_action()
2356 switch (usbd_get_speed(sc->sc_udev)) { in umass_cam_action()
2358 cpi->base_transfer_speed = in umass_cam_action()
2360 cpi->maxio = maxphys; in umass_cam_action()
2363 cpi->base_transfer_speed = in umass_cam_action()
2367 cpi->base_transfer_speed = in umass_cam_action()
2372 cpi->max_lun = sc->sc_maxlun; in umass_cam_action()
2375 cpi->ccb_h.status = CAM_REQ_CMP; in umass_cam_action()
2382 cam_sim_path(sc->sc_sim), ccb->ccb_h.target_id, in umass_cam_action()
2383 (uintmax_t)ccb->ccb_h.target_lun); in umass_cam_action()
2387 ccb->ccb_h.status = CAM_REQ_CMP; in umass_cam_action()
2393 struct ccb_trans_settings *cts = &ccb->cts; in umass_cam_action()
2396 cam_sim_path(sc->sc_sim), ccb->ccb_h.target_id, in umass_cam_action()
2397 (uintmax_t)ccb->ccb_h.target_lun); in umass_cam_action()
2399 cts->protocol = PROTO_SCSI; in umass_cam_action()
2400 cts->protocol_version = SCSI_REV_2; in umass_cam_action()
2401 cts->transport = XPORT_USB; in umass_cam_action()
2402 cts->transport_version = 0; in umass_cam_action()
2403 cts->xport_specific.valid = 0; in umass_cam_action()
2405 ccb->ccb_h.status = CAM_REQ_CMP; in umass_cam_action()
2412 cam_sim_path(sc->sc_sim), ccb->ccb_h.target_id, in umass_cam_action()
2413 (uintmax_t)ccb->ccb_h.target_lun); in umass_cam_action()
2415 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; in umass_cam_action()
2421 cam_calc_geometry(&ccb->ccg, /* extended */ 1); in umass_cam_action()
2428 sc ? cam_sim_path(sc->sc_sim) : -1, ccb->ccb_h.target_id, in umass_cam_action()
2429 (uintmax_t)ccb->ccb_h.target_lun); in umass_cam_action()
2431 ccb->ccb_h.status = CAM_REQ_CMP; in umass_cam_action()
2438 sc ? cam_sim_path(sc->sc_sim) : -1, ccb->ccb_h.target_id, in umass_cam_action()
2439 (uintmax_t)ccb->ccb_h.target_lun, ccb->ccb_h.func_code); in umass_cam_action()
2441 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; in umass_cam_action()
2460 usbd_transfer_poll(sc->sc_xfer, UMASS_T_MAX); in umass_cam_poll()
2470 scsi_set_sense_data(&ccb->csio.sense_data, in umass_cam_illegal_request()
2477 ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND; in umass_cam_illegal_request()
2478 ccb->ccb_h.status = in umass_cam_illegal_request()
2482 xpt_freeze_devq(ccb->ccb_h.path, 1); in umass_cam_illegal_request()
2494 ccb->csio.resid = residue; in umass_cam_cb()
2498 ccb->ccb_h.status = CAM_REQ_CMP; in umass_cam_cb()
2499 if ((sc->sc_quirks & READ_CAPACITY_OFFBY1) && in umass_cam_cb()
2500 (ccb->ccb_h.func_code == XPT_SCSI_IO) && in umass_cam_cb()
2501 (ccb->csio.cdb_io.cdb_bytes[0] == READ_CAPACITY)) { in umass_cam_cb()
2505 rcap = (void *)(ccb->csio.data_ptr); in umass_cam_cb()
2506 maxsector = scsi_4btoul(rcap->addr) - 1; in umass_cam_cb()
2507 scsi_ulto4b(maxsector, rcap->addr); in umass_cam_cb()
2511 * of pages supported by the device - otherwise, CAM in umass_cam_cb()
2515 if (ccb->ccb_h.func_code == XPT_SCSI_IO && in umass_cam_cb()
2516 sc->sc_transfer.cmd_data[0] == INQUIRY && in umass_cam_cb()
2517 (sc->sc_transfer.cmd_data[1] & SI_EVPD) && in umass_cam_cb()
2518 sc->sc_transfer.cmd_data[2] == SVPD_SUPPORTED_PAGE_LIST && in umass_cam_cb()
2519 (usb_get_serial(sc->sc_udev)[0] != '\0')) { in umass_cam_cb()
2523 csio = &ccb->csio; in umass_cam_cb()
2524 page_list = (struct scsi_vpd_supported_page_list *)csio->data_ptr; in umass_cam_cb()
2525 if (page_list->length + 1 < SVPD_SUPPORTED_PAGES_SIZE) { in umass_cam_cb()
2526 page_list->list[page_list->length] = SVPD_UNIT_SERIAL_NUMBER; in umass_cam_cb()
2527 page_list->length++; in umass_cam_cb()
2539 sc->cam_scsi_sense.length = ccb->csio.sense_len; in umass_cam_cb()
2542 "sense data\n", ccb->csio.sense_len); in umass_cam_cb()
2544 if (umass_std_transform(sc, ccb, &sc->cam_scsi_sense.opcode, in umass_cam_cb()
2545 sizeof(sc->cam_scsi_sense))) { in umass_cam_cb()
2546 umass_command_start(sc, DIR_IN, &ccb->csio.sense_data.error_code, in umass_cam_cb()
2547 ccb->csio.sense_len, ccb->ccb_h.timeout, in umass_cam_cb()
2558 xpt_freeze_devq(ccb->ccb_h.path, 1); in umass_cam_cb()
2559 ccb->ccb_h.status = CAM_REQ_CMP_ERR | CAM_DEV_QFRZN; in umass_cam_cb()
2572 uint8_t *cmd; in umass_cam_sense_cb() local
2580 ccb->csio.sense_resid = residue; in umass_cam_sense_cb()
2581 sense_len = ccb->csio.sense_len - ccb->csio.sense_resid; in umass_cam_sense_cb()
2582 key = scsi_get_sense_key(&ccb->csio.sense_data, sense_len, in umass_cam_sense_cb()
2585 if (ccb->csio.ccb_h.flags & CAM_CDB_POINTER) { in umass_cam_sense_cb()
2586 cmd = (uint8_t *)(ccb->csio.cdb_io.cdb_ptr); in umass_cam_sense_cb()
2588 cmd = (uint8_t *)(ccb->csio.cdb_io.cdb_bytes); in umass_cam_sense_cb()
2595 if ((sc->sc_quirks & RS_NO_CLEAR_UA) && in umass_cam_sense_cb()
2596 (cmd[0] == INQUIRY) && in umass_cam_sense_cb()
2604 ccb->ccb_h.status = CAM_REQ_CMP; in umass_cam_sense_cb()
2610 ccb->ccb_h.status = CAM_REQ_CMP; in umass_cam_sense_cb()
2611 } else if ((sc->sc_quirks & RS_NO_CLEAR_UA) && in umass_cam_sense_cb()
2612 (cmd[0] == READ_CAPACITY) && in umass_cam_sense_cb()
2622 xpt_freeze_devq(ccb->ccb_h.path, 1); in umass_cam_sense_cb()
2623 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR in umass_cam_sense_cb()
2625 ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND; in umass_cam_sense_cb()
2639 &sc->cam_scsi_test_unit_ready.opcode, in umass_cam_sense_cb()
2640 sizeof(sc->cam_scsi_test_unit_ready))) { in umass_cam_sense_cb()
2642 ccb->ccb_h.timeout, in umass_cam_sense_cb()
2647 xpt_freeze_devq(ccb->ccb_h.path, 1); in umass_cam_sense_cb()
2649 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR in umass_cam_sense_cb()
2651 ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND; in umass_cam_sense_cb()
2653 ccb->ccb_h.status = CAM_AUTOSENSE_FAIL in umass_cam_sense_cb()
2662 xpt_freeze_devq(ccb->ccb_h.path, 1); in umass_cam_sense_cb()
2663 ccb->ccb_h.status = CAM_AUTOSENSE_FAIL | CAM_DEV_QFRZN; in umass_cam_sense_cb()
2669 * This completion code just handles the fact that we sent a test-unit-ready
2691 sc->sc_transfer.cmd_len = cmd_len; in umass_scsi_transform()
2719 if ((sc->sc_quirks & RBC_PAD_TO_12) && (cmd_len < 12)) { in umass_rbc_transform()
2720 memset(sc->sc_transfer.cmd_data + cmd_len, in umass_rbc_transform()
2721 0, 12 - cmd_len); in umass_rbc_transform()
2724 sc->sc_transfer.cmd_len = cmd_len; in umass_rbc_transform()
2740 sc->sc_transfer.cmd_len = UFI_COMMAND_LENGTH; in umass_ufi_transform()
2794 sc->sc_transfer.cmd_len = ATAPI_COMMAND_LENGTH; in umass_atapi_transform()
2843 "command 0x%02x - trying anyway\n", in umass_atapi_transform()
2852 umass_no_transform(struct umass_softc *sc, uint8_t *cmd, in umass_no_transform() argument
2860 uint8_t *cmd, uint8_t cmd_len) in umass_std_transform() argument
2862 if (cmd_len == 0 || cmd_len > sizeof(sc->sc_transfer.cmd_data)) { in umass_std_transform()
2873 memset(sc->sc_transfer.cmd_data, 0, sizeof(sc->sc_transfer.cmd_data)); in umass_std_transform()
2874 memcpy(sc->sc_transfer.cmd_data, cmd, cmd_len); in umass_std_transform()
2875 switch (cmd[0]) { in umass_std_transform()
2881 if ((sc->sc_quirks & NO_TEST_UNIT_READY) != 0) { in umass_std_transform()
2884 memset(sc->sc_transfer.cmd_data, 0, cmd_len); in umass_std_transform()
2885 sc->sc_transfer.cmd_data[0] = START_STOP_UNIT; in umass_std_transform()
2886 sc->sc_transfer.cmd_data[4] = SSS_START; in umass_std_transform()
2895 if ((sc->sc_quirks & FORCE_SHORT_INQUIRY) != 0) in umass_std_transform()
2896 sc->sc_transfer.cmd_data[4] = SHORT_INQUIRY_LENGTH; in umass_std_transform()
2899 if (sc->sc_transform(sc, cmd, cmd_len)) in umass_std_transform()
2903 return (false); /* Already failed -- don't submit */ in umass_std_transform()
2910 uint8_t *c = cbw->CBWCDB; in umass_bbb_dump_cbw()
2912 uint32_t dlen = UGETDW(cbw->dCBWDataTransferLength); in umass_bbb_dump_cbw()
2913 uint32_t tag = UGETDW(cbw->dCBWTag); in umass_bbb_dump_cbw()
2915 uint8_t clen = cbw->bCDBLength; in umass_bbb_dump_cbw()
2916 uint8_t flags = cbw->bCBWFlags; in umass_bbb_dump_cbw()
2917 uint8_t lun = cbw->bCBWLUN; in umass_bbb_dump_cbw()
2919 DPRINTF(sc, UDMASS_BBB, "CBW %d: cmd = %db " in umass_bbb_dump_cbw()
2921 "data = %db, lun = %d, dir = %s\n", in umass_bbb_dump_cbw()
2931 uint32_t sig = UGETDW(csw->dCSWSignature); in umass_bbb_dump_csw() local
2932 uint32_t tag = UGETDW(csw->dCSWTag); in umass_bbb_dump_csw()
2933 uint32_t res = UGETDW(csw->dCSWDataResidue); in umass_bbb_dump_csw()
2934 uint8_t status = csw->bCSWStatus; in umass_bbb_dump_csw()
2936 DPRINTF(sc, UDMASS_BBB, "CSW %d: sig = 0x%08x (%s), tag = 0x%08x, " in umass_bbb_dump_csw()
2938 tag, sig, (sig == CSWSIGNATURE ? "valid" : "invalid"), in umass_bbb_dump_csw()
2946 umass_cbi_dump_cmd(struct umass_softc *sc, void *cmd, uint8_t cmdlen) in umass_cbi_dump_cmd() argument
2948 uint8_t *c = cmd; in umass_cbi_dump_cmd()
2949 uint8_t dir = sc->sc_transfer.dir; in umass_cbi_dump_cmd() local
2951 DPRINTF(sc, UDMASS_BBB, "cmd = %db " in umass_cbi_dump_cmd()
2953 "data = %db, dir = %s\n", in umass_cbi_dump_cmd()
2956 sc->sc_transfer.data_len, in umass_cbi_dump_cmd()
2957 (dir == DIR_IN ? "in" : in umass_cbi_dump_cmd()
2958 (dir == DIR_OUT ? "out" : in umass_cbi_dump_cmd()
2959 (dir == DIR_NONE ? "no data phase" : "<invalid>")))); in umass_cbi_dump_cmd()