Lines Matching refs:sc

65  * sc->sc_transform method is used to convert the commands into the appropriate
120 #define DPRINTF_UMASS(sc, m, fmt, ...) \
124 (sc) ? (const char *)(sc)->sc_name : \
318 typedef void (umass_callback_t)(struct umass_softc *sc, union ccb *ccb,
326 typedef uint8_t (umass_transform_t)(struct umass_softc *sc, uint8_t *cmd_ptr,
459 struct umass_softc *sc;
468 static void umass_dev_delete(struct umass_softc *sc, unsigned int dev_unit);
534 static int32_t umass_attach_dev(struct umass_softc *sc, unsigned int dev_unit);
535 static void umass_detach_dev_sub(struct umass_softc *sc, int dev_unit, int flag);
913 struct umass_softc *sc =
927 sc->sc_dev = dev;
928 sc->sc_udev = uaa->device;
929 sc->sc_proto = temp.proto;
930 sc->sc_quirks = temp.quirks;
931 sc->sc_unit = device_get_unit(dev);
932 sc->data_ccb = NULL;
933 sc->sc_detach_status = FALSE;
934 sc->sc_super_disk = FALSE;
940 (void)snprintf_s((char *)sc->sc_name, sizeof(sc->sc_name), sizeof(sc->sc_name) - 1,
945 mtx_init(&sc->sc_mtx, device_get_nameunit(dev),
947 mtx_init(&sc->sc_umass_mtx, device_get_nameunit(dev),
950 (void)LOS_EventInit(&sc->sc_event);
960 sc->sc_iface_no = id->bInterfaceNumber;
964 switch (sc->sc_proto & UMASS_PROTO_COMMAND) {
979 sc->sc_proto & UMASS_PROTO_COMMAND);
985 switch (sc->sc_proto & UMASS_PROTO_WIRE) {
997 sc->sc_proto & UMASS_PROTO_WIRE);
1000 PRINTK("; quirks = 0x%04x\n", sc->sc_quirks);
1002 if (sc->sc_quirks & ALT_IFACE_1) {
1007 DPRINTF_UMASS(sc, UDMASS_USB, "could not switch to "
1014 if (sc->sc_proto & UMASS_PROTO_BBB) {
1016 &uaa->info.bIfaceIndex, sc->sc_xfer, umass_bbb_config,
1017 UMASS_T_BBB_MAX, sc, &sc->sc_mtx);
1020 sc->sc_last_xfer_index = UMASS_T_BBB_COMMAND;
1022 } else if (sc->sc_proto & (UMASS_PROTO_CBI | UMASS_PROTO_CBI_I)) {
1024 &uaa->info.bIfaceIndex, sc->sc_xfer, umass_cbi_config,
1025 UMASS_T_CBI_MAX, sc, &sc->sc_mtx);
1028 sc->sc_last_xfer_index = UMASS_T_CBI_COMMAND;
1052 if (sc->sc_xfer[x] != NULL)
1053 usbd_xfer_set_interval(sc->sc_xfer[x], iv);
1057 sc->sc_transform =
1058 (sc->sc_proto & UMASS_PROTO_SCSI) ? &umass_scsi_transform :
1059 (sc->sc_proto & UMASS_PROTO_UFI) ? &umass_ufi_transform :
1060 (sc->sc_proto & UMASS_PROTO_ATAPI) ? &umass_atapi_transform :
1061 (sc->sc_proto & UMASS_PROTO_RBC) ? &umass_rbc_transform :
1066 if (sc->sc_quirks & SHUTTLE_INIT) {
1067 umass_init_shuttle(sc);
1071 if (((sc->sc_proto & UMASS_PROTO_WIRE) == UMASS_PROTO_BBB) &&
1072 !(sc->sc_quirks & NO_GETMAXLUN))
1073 sc->sc_maxlun = umass_bbb_get_max_lun(sc);
1075 sc->sc_maxlun = 0;
1078 sc->cam_scsi_sense.opcode = REQUEST_SENSE;
1079 sc->cam_scsi_test_unit_ready.opcode = TEST_UNIT_READY;
1082 sc->data_ccb = (union ccb *)malloc(sizeof(union ccb));
1083 if (sc->data_ccb == NULL)
1085 sc->data_ccb->csio.data_ptr = (uint8_t *)memalign(USB_CACHE_ALIGN_SIZE, SKB_DATA_ALIGN(SOFT_CACHE_SIZE));
1086 if (sc->data_ccb->csio.data_ptr == NULL)
1088 sc->data_ccb->csio.dxfer_len = SOFT_CACHE_SIZE;
1090 DPRINTF_UMASS(sc, UDMASS_GEN, "Attach finished\n");
1093 if (umass_attach_dev(sc, device_get_unit(dev))) {
1097 p_umsf = sc;
1108 struct umass_softc *sc = (struct umass_softc *)device_get_softc(dev);
1111 DPRINTF_UMASS(sc, UDMASS_USB, "\n");
1113 sc->sc_detach_status = TRUE;
1116 usbd_transfer_unsetup(sc->sc_xfer, UMASS_T_MAX);
1118 mtx_lock(&sc->sc_mtx);
1121 umass_cancel_ccb(sc);
1123 mtx_lock(&sc->sc_umass_mtx);
1124 if (sc->data_ccb != NULL) {
1125 if (sc->data_ccb->csio.data_ptr != NULL) {
1126 free((void*)sc->data_ccb->csio.data_ptr);
1127 sc->data_ccb->csio.data_ptr = NULL;
1129 free(sc->data_ccb);
1130 sc->data_ccb = NULL;
1132 mtx_unlock(&sc->sc_umass_mtx);
1134 umass_detach_dev_sub(sc, dev_unit, 0);
1139 mtx_unlock(&sc->sc_mtx);
1140 sc->sc_detach_status = FALSE;
1141 mtx_destroy(&sc->sc_mtx);
1142 mtx_destroy(&sc->sc_umass_mtx);
1149 umass_init_shuttle(struct umass_softc *sc)
1162 req.wIndex[0] = sc->sc_iface_no;
1165 err = usbd_do_request(sc->sc_udev, NULL, &req, &status);
1167 DPRINTF_UMASS(sc, UDMASS_GEN, "request failed in %s %d, err=%d\n",
1170 DPRINTF_UMASS(sc, UDMASS_GEN, "Shuttle init returned 0x%02x%02x\n",
1179 umass_transfer_start(struct umass_softc *sc, uint8_t xfer_index)
1181 DPRINTF_UMASS(sc, UDMASS_GEN, "transfer index = "
1184 if (sc->sc_xfer[xfer_index]) {
1185 sc->sc_last_xfer_index = xfer_index;
1186 usbd_transfer_start(sc->sc_xfer[xfer_index]);
1188 umass_cancel_ccb(sc);
1193 umass_cancel_ccb(struct umass_softc *sc)
1197 mtx_assert(&sc->sc_mtx, MA_OWNED);
1199 umass_ccb = sc->sc_transfer.ccb;
1200 sc->sc_transfer.ccb = NULL;
1201 sc->sc_last_xfer_index = 0;
1204 (sc->sc_transfer.callback)
1205 (sc, umass_ccb, (sc->sc_transfer.data_len -
1206 sc->sc_transfer.actlen), STATUS_WIRE_FAILED);
1213 struct umass_softc *sc = (struct umass_softc *)usbd_xfer_softc(xfer);
1216 DPRINTF_UMASS(sc, UDMASS_GEN, "transfer error, %s -> "
1219 umass_cancel_ccb(sc);
1228 umass_scsi_inquiry_data(struct umass_softc *sc, void *data, int len)
1262 DPRINTF_UMASS(sc, UDMASS_BBB, "SCSI: LUN-%d %s %s\n", sc->sc_transfer.lun, name,
1277 struct umass_softc *sc = (struct umass_softc *)usbd_xfer_softc(xfer);
1283 umass_transfer_start(sc, UMASS_T_BBB_RESET2);
1301 DPRINTF_UMASS(sc, UDMASS_BBB, "BBB reset!\n");
1306 req.wIndex[0] = sc->sc_iface_no;
1342 struct umass_softc *sc = (struct umass_softc *)usbd_xfer_softc(xfer);
1347 umass_transfer_start(sc, next_xfer);
1351 if (usbd_clear_stall_callback(xfer, sc->sc_xfer[stall_xfer])) {
1365 struct umass_softc *sc = (struct umass_softc *)usbd_xfer_softc(xfer);
1373 (sc, ((sc->sc_transfer.dir == DIR_IN) ? UMASS_T_BBB_DATA_READ :
1374 (sc->sc_transfer.dir == DIR_OUT) ? UMASS_T_BBB_DATA_WRITE :
1380 sc->sc_status_try = 0;
1386 tag = UGETDW(sc->cbw.dCBWTag) + 1;
1388 USETDW(sc->cbw.dCBWSignature, CBWSIGNATURE);
1389 USETDW(sc->cbw.dCBWTag, tag);
1400 USETDW(sc->cbw.dCBWDataTransferLength, sc->sc_transfer.data_len);
1411 sc->cbw.bCBWFlags = ((sc->sc_transfer.dir == DIR_IN) ?
1413 sc->cbw.bCBWLUN = sc->sc_transfer.lun;
1415 if (sc->sc_transfer.cmd_len > sizeof(sc->cbw.CBWCDB)) {
1416 sc->sc_transfer.cmd_len = sizeof(sc->cbw.CBWCDB);
1417 DPRINTF_UMASS(sc, UDMASS_BBB, "Truncating long command!\n");
1419 sc->cbw.bCDBLength = sc->sc_transfer.cmd_len;
1422 ret = memcpy_s(sc->cbw.CBWCDB, CBWCDBLENGTH,
1423 sc->sc_transfer.cmd_data, sc->sc_transfer.cmd_len);
1425 DPRINTF_UMASS(sc, UDMASS_BBB, "memcpy_s fail, %d\n", ret);
1430 (void)memset_s(sc->cbw.CBWCDB + sc->sc_transfer.cmd_len,
1431 sizeof(sc->cbw.CBWCDB) - sc->sc_transfer.cmd_len, 0,
1432 sizeof(sc->cbw.CBWCDB) - sc->sc_transfer.cmd_len);
1434 DIF(UDMASS_BBB, umass_bbb_dump_cbw(sc, &sc->cbw));
1437 usbd_copy_in(pc, 0, &sc->cbw, sizeof(sc->cbw));
1438 usbd_xfer_set_frame_len(xfer, 0, sizeof(sc->cbw));
1454 struct umass_softc *sc = (struct umass_softc *)usbd_xfer_softc(xfer);
1462 sc->sc_transfer.data_rem -= actlen;
1463 sc->sc_transfer.data_ptr += actlen;
1464 sc->sc_transfer.actlen += actlen;
1468 sc->sc_transfer.data_rem = 0;
1471 DPRINTF_UMASS(sc, UDMASS_BBB, "max_bulk=%u, data_rem=%u\n",
1472 max_bulk, sc->sc_transfer.data_rem);
1474 if (sc->sc_transfer.data_rem == 0) {
1475 umass_transfer_start(sc, UMASS_T_BBB_STATUS);
1478 if (max_bulk > sc->sc_transfer.data_rem) {
1479 max_bulk = sc->sc_transfer.data_rem;
1481 usbd_xfer_set_timeout(xfer, sc->sc_transfer.data_timeout);
1483 usbd_xfer_set_frame_data(xfer, 0, sc->sc_transfer.data_ptr,
1493 umass_transfer_start(sc, xfer_index);
1528 struct umass_softc *sc = (struct umass_softc *)usbd_xfer_softc(xfer);
1529 union ccb *umass_ccb = sc->sc_transfer.ccb;
1542 sc->sc_status_try = 1;
1546 if (actlen < (int)sizeof(sc->csw)) {
1547 (void)memset_s(&sc->csw, sizeof(sc->csw), 0, sizeof(sc->csw));
1552 usbd_copy_out(pc, 0, &sc->csw, actlen);
1554 DIF(UDMASS_BBB, umass_bbb_dump_csw(sc, &sc->csw));
1556 residue = UGETDW(sc->csw.dCSWDataResidue);
1558 if ((!residue) || (sc->sc_quirks & IGNORE_RESIDUE)) {
1559 residue = (sc->sc_transfer.data_len -
1560 sc->sc_transfer.actlen);
1562 if (residue > sc->sc_transfer.data_len) {
1563 DPRINTF_UMASS(sc, UDMASS_BBB, "truncating residue from %d "
1564 "to %d bytes\n", residue, sc->sc_transfer.data_len);
1565 residue = sc->sc_transfer.data_len;
1568 if (sc->sc_quirks & WRONG_CSWSIG) {
1569 uint32_t temp = UGETDW(sc->csw.dCSWSignature);
1573 USETDW(sc->csw.dCSWSignature, CSWSIGNATURE);
1577 if (UGETDW(sc->csw.dCSWSignature) != CSWSIGNATURE) {
1578 DPRINTF_UMASS(sc, UDMASS_BBB, "bad CSW signature 0x%08x != 0x%08x\n",
1579 UGETDW(sc->csw.dCSWSignature), CSWSIGNATURE);
1586 } else if (UGETDW(sc->csw.dCSWTag) != UGETDW(sc->cbw.dCBWTag)) {
1587 DPRINTF_UMASS(sc, UDMASS_BBB, "Invalid CSW: tag 0x%08x should be "
1588 "0x%08x\n", UGETDW(sc->csw.dCSWTag),
1589 UGETDW(sc->cbw.dCBWTag));
1591 } else if (sc->csw.bCSWStatus > CSWSTATUS_PHASE) {
1592 DPRINTF_UMASS(sc, UDMASS_BBB, "Invalid CSW: status %d > %d\n",
1593 sc->csw.bCSWStatus, CSWSTATUS_PHASE);
1595 } else if (sc->csw.bCSWStatus == CSWSTATUS_PHASE) {
1596 DPRINTF_UMASS(sc, UDMASS_BBB, "Phase error, residue = "
1599 } else if (sc->sc_transfer.actlen > sc->sc_transfer.data_len) {
1600 DPRINTF_UMASS(sc, UDMASS_BBB, "Buffer overrun %d > %d\n",
1601 sc->sc_transfer.actlen, sc->sc_transfer.data_len);
1603 } else if (sc->csw.bCSWStatus == CSWSTATUS_FAILED) {
1604 DPRINTF_UMASS(sc, UDMASS_BBB, "Command failed, residue = "
1607 sc->sc_transfer.ccb = NULL;
1609 sc->sc_last_xfer_index = UMASS_T_BBB_COMMAND;
1611 (sc->sc_transfer.callback)
1612 (sc, umass_ccb, residue, STATUS_CMD_FAILED);
1614 sc->sc_transfer.ccb = NULL;
1616 sc->sc_last_xfer_index = UMASS_T_BBB_COMMAND;
1618 (sc->sc_transfer.callback)
1619 (sc, umass_ccb, residue, STATUS_CMD_OK);
1630 DPRINTF_UMASS(sc, UDMASS_BBB, "Failed to read CSW: %s, try %d\n",
1631 usbd_errstr(error), sc->sc_status_try);
1634 (sc->sc_status_try)) {
1637 sc->sc_status_try = 1;
1638 umass_transfer_start(sc, UMASS_T_BBB_DATA_RD_CS);
1645 umass_command_start(struct umass_softc *sc, uint8_t dir,
1650 if (sc->sc_detach_status)
1657 * NOTE: assumes that "sc->sc_transfer.cmd_data" and
1658 * "sc->sc_transfer.cmd_len" has been properly
1662 sc->sc_transfer.dir = data_len ? dir : DIR_NONE;
1663 sc->sc_transfer.data_ptr = (uint8_t *)data_ptr;
1664 sc->sc_transfer.data_len = data_len;
1665 sc->sc_transfer.data_rem = data_len;
1666 sc->sc_transfer.data_timeout = (data_timeout + UMASS_TIMEOUT);
1668 sc->sc_transfer.actlen = 0;
1669 sc->sc_transfer.callback = callback;
1670 sc->sc_transfer.ccb = umass_ccb;
1672 if (sc->sc_xfer[sc->sc_last_xfer_index]) {
1673 usbd_transfer_start(sc->sc_xfer[sc->sc_last_xfer_index]);
1675 umass_cancel_ccb(sc);
1678 (void)LOS_EventRead(&sc->sc_event, 0xFF,
1685 umass_bbb_get_max_lun(struct umass_softc *sc)
1695 req.wIndex[0] = sc->sc_iface_no;
1699 err = usbd_do_request(sc->sc_udev, NULL, &req, &buf);
1705 sc->sc_name, usbd_errstr(err));
1715 umass_cbi_start_status(struct umass_softc *sc)
1717 if (sc->sc_xfer[UMASS_T_CBI_STATUS]) {
1718 umass_transfer_start(sc, UMASS_T_CBI_STATUS);
1720 union ccb *umass_ccb = sc->sc_transfer.ccb;
1722 sc->sc_transfer.ccb = NULL;
1724 sc->sc_last_xfer_index = UMASS_T_CBI_COMMAND;
1726 (sc->sc_transfer.callback)
1727 (sc, umass_ccb, (sc->sc_transfer.data_len -
1728 sc->sc_transfer.actlen), STATUS_CMD_UNKNOWN);
1735 struct umass_softc *sc = (struct umass_softc *)usbd_xfer_softc(xfer);
1744 umass_transfer_start(sc, UMASS_T_CBI_RESET2);
1761 DPRINTF_UMASS(sc, UDMASS_CBI, "CBI reset!\n");
1766 req.wIndex[0] = sc->sc_iface_no;
1798 umass_transfer_start(sc, UMASS_T_CBI_RESET2);
1813 struct umass_softc *sc = (struct umass_softc *)usbd_xfer_softc(xfer);
1816 (xfer, (sc->sc_xfer[UMASS_T_CBI_RESET4] &&
1817 sc->sc_xfer[UMASS_T_CBI_STATUS]) ?
1833 struct umass_softc *sc = (struct umass_softc *)usbd_xfer_softc(xfer);
1839 umass_cbi_start_status(sc);
1841 umass_transfer_start(sc, next_xfer);
1846 if (usbd_clear_stall_callback(xfer, sc->sc_xfer[stall_xfer])) {
1860 struct umass_softc *sc = (struct umass_softc *)usbd_xfer_softc(xfer);
1861 union ccb *umass_ccb = sc->sc_transfer.ccb;
1868 if (sc->sc_transfer.dir == DIR_NONE) {
1869 umass_cbi_start_status(sc);
1872 (sc, (sc->sc_transfer.dir == DIR_IN) ?
1890 req.wIndex[0] = sc->sc_iface_no;
1892 req.wLength[0] = sc->sc_transfer.cmd_len;
1898 usbd_copy_in(pc, 0, sc->sc_transfer.cmd_data,
1899 sc->sc_transfer.cmd_len);
1902 usbd_xfer_set_frame_len(xfer, 1, sc->sc_transfer.cmd_len);
1904 sc->sc_transfer.cmd_len ? 2 : 1);
1907 umass_cbi_dump_cmd(sc,
1908 sc->sc_transfer.cmd_data,
1909 sc->sc_transfer.cmd_len));
1923 (sc->sc_transfer.callback == &umass_cam_cb)) {
1924 sc->sc_transfer.ccb = NULL;
1925 (sc->sc_transfer.callback)
1926 (sc, umass_ccb, sc->sc_transfer.data_len,
1931 sc->sc_last_xfer_index = UMASS_T_CBI_COMMAND;
1940 struct umass_softc *sc = (struct umass_softc *)usbd_xfer_softc(xfer);
1948 sc->sc_transfer.data_rem -= actlen;
1949 sc->sc_transfer.data_ptr += actlen;
1950 sc->sc_transfer.actlen += actlen;
1954 sc->sc_transfer.data_rem = 0;
1957 DPRINTF_UMASS(sc, UDMASS_CBI, "max_bulk=%d, data_rem=%d\n",
1958 max_bulk, sc->sc_transfer.data_rem);
1960 if (sc->sc_transfer.data_rem == 0) {
1961 umass_cbi_start_status(sc);
1964 if (max_bulk > sc->sc_transfer.data_rem) {
1965 max_bulk = sc->sc_transfer.data_rem;
1967 usbd_xfer_set_timeout(xfer, sc->sc_transfer.data_timeout);
1969 usbd_xfer_set_frame_data(xfer, 0, sc->sc_transfer.data_ptr,
1977 (sc->sc_transfer.callback != &umass_cam_cb)) {
1980 umass_transfer_start(sc, UMASS_T_CBI_DATA_RD_CS);
1996 struct umass_softc *sc = (struct umass_softc *)usbd_xfer_softc(xfer);
2004 sc->sc_transfer.data_rem -= actlen;
2005 sc->sc_transfer.data_ptr += actlen;
2006 sc->sc_transfer.actlen += actlen;
2010 sc->sc_transfer.data_rem = 0;
2013 DPRINTF_UMASS(sc, UDMASS_CBI, "max_bulk=%d, data_rem=%d\n",
2014 max_bulk, sc->sc_transfer.data_rem);
2016 if (sc->sc_transfer.data_rem == 0) {
2017 umass_cbi_start_status(sc);
2020 if (max_bulk > sc->sc_transfer.data_rem) {
2021 max_bulk = sc->sc_transfer.data_rem;
2023 usbd_xfer_set_timeout(xfer, sc->sc_transfer.data_timeout);
2025 usbd_xfer_set_frame_data(xfer, 0, sc->sc_transfer.data_ptr,
2033 (sc->sc_transfer.callback != &umass_cam_cb)) {
2036 umass_transfer_start(sc, UMASS_T_CBI_DATA_WR_CS);
2052 struct umass_softc *sc = (struct umass_softc *)usbd_xfer_softc(xfer);
2053 union ccb *umass_ccb = sc->sc_transfer.ccb;
2064 if (actlen < (int)sizeof(sc->sbl)) {
2068 usbd_copy_out(pc, 0, &sc->sbl, sizeof(sc->sbl));
2070 residue = (sc->sc_transfer.data_len -
2071 sc->sc_transfer.actlen);
2075 if (sc->sc_proto & UMASS_PROTO_UFI) {
2082 DPRINTF_UMASS(sc, UDMASS_CBI, "UFI CCI, ASC = 0x%02x, "
2083 "ASCQ = 0x%02x\n", sc->sbl.ufi.asc,
2084 sc->sbl.ufi.ascq);
2086 status = (((sc->sbl.ufi.asc == 0) &&
2087 (sc->sbl.ufi.ascq == 0)) ?
2090 sc->sc_transfer.ccb = NULL;
2092 sc->sc_last_xfer_index = UMASS_T_CBI_COMMAND;
2094 (sc->sc_transfer.callback)
2095 (sc, umass_ccb, residue, status);
2102 DPRINTF_UMASS(sc, UDMASS_CBI, "type=0x%02x, value=0x%02x\n",
2103 sc->sbl.common.type, sc->sbl.common.value);
2105 if (sc->sbl.common.type == IDB_TYPE_CCI) {
2106 status = (sc->sbl.common.value & IDB_VALUE_STATUS_MASK);
2113 sc->sc_transfer.ccb = NULL;
2115 sc->sc_last_xfer_index = UMASS_T_CBI_COMMAND;
2117 (sc->sc_transfer.callback)
2118 (sc, umass_ccb, residue, status);
2133 DPRINTF_UMASS(sc, UDMASS_CBI, "Failed to read CSW: %s\n",
2145 umass_cam_cb(struct umass_softc *sc, union ccb *umass_ccb, uint32_t residue,
2153 (void)LOS_EventWrite(&sc->sc_event, 0x01);
2159 (void)LOS_EventWrite(&sc->sc_event, 0x02);
2163 (void)LOS_EventWrite(&sc->sc_event, 0x04);
2173 umass_scsi_transform(struct umass_softc *sc, uint8_t *cmd_ptr,
2179 (cmd_len > sizeof(sc->sc_transfer.cmd_data))) {
2180 DPRINTF_UMASS(sc, UDMASS_SCSI, "Invalid command "
2184 sc->sc_transfer.cmd_len = cmd_len;
2188 if (sc->sc_quirks & NO_TEST_UNIT_READY) {
2189 DPRINTF_UMASS(sc, UDMASS_SCSI, "Converted TEST_UNIT_READY "
2191 ret = memset_s(sc->sc_transfer.cmd_data, sizeof(sc->sc_transfer.cmd_data), 0, cmd_len);
2196 sc->sc_transfer.cmd_data[0] = START_STOP_UNIT;
2197 sc->sc_transfer.cmd_data[4] = SSS_START;
2207 if (sc->sc_quirks & FORCE_SHORT_INQUIRY) {
2208 ret = memcpy_s(sc->sc_transfer.cmd_data, UMASS_MAX_CMDLEN, cmd_ptr, cmd_len);
2213 sc->sc_transfer.cmd_data[4] = SHORT_INQUIRY_LENGTH;
2219 ret = memcpy_s(sc->sc_transfer.cmd_data, UMASS_MAX_CMDLEN, cmd_ptr, cmd_len);
2229 umass_rbc_transform(struct umass_softc *sc, uint8_t *cmd_ptr, uint8_t cmd_len)
2234 (cmd_len > sizeof(sc->sc_transfer.cmd_data))) {
2235 DPRINTF_UMASS(sc, UDMASS_SCSI, "Invalid command "
2260 ret = memcpy_s(sc->sc_transfer.cmd_data, UMASS_MAX_CMDLEN, cmd_ptr, cmd_len);
2266 if ((sc->sc_quirks & RBC_PAD_TO_12) && (cmd_len < 12)) {
2267 ret = memset_s(sc->sc_transfer.cmd_data + cmd_len,
2275 sc->sc_transfer.cmd_len = cmd_len;
2280 DPRINTF_UMASS(sc, UDMASS_SCSI, "Unsupported RBC "
2287 umass_ufi_transform(struct umass_softc *sc, uint8_t *cmd_ptr,
2293 (cmd_len > sizeof(sc->sc_transfer.cmd_data))) {
2294 DPRINTF_UMASS(sc, UDMASS_SCSI, "Invalid command "
2299 sc->sc_transfer.cmd_len = UFI_COMMAND_LENGTH;
2302 ret = memset_s(sc->sc_transfer.cmd_data, UMASS_MAX_CMDLEN, 0, UFI_COMMAND_LENGTH);
2315 if (sc->sc_quirks & NO_TEST_UNIT_READY) {
2320 DPRINTF_UMASS(sc, UDMASS_UFI, "Converted TEST_UNIT_READY "
2323 sc->sc_transfer.cmd_data[0] = START_STOP_UNIT;
2324 sc->sc_transfer.cmd_data[4] = SSS_START;
2358 DPRINTF_UMASS(sc, UDMASS_SCSI, "Unsupported UFI "
2363 ret = memcpy_s(sc->sc_transfer.cmd_data, UMASS_MAX_CMDLEN, cmd_ptr, cmd_len);
2376 umass_atapi_transform(struct umass_softc *sc, uint8_t *cmd_ptr,
2382 (cmd_len > sizeof(sc->sc_transfer.cmd_data))) {
2383 DPRINTF_UMASS(sc, UDMASS_SCSI, "Invalid command "
2388 sc->sc_transfer.cmd_len = ATAPI_COMMAND_LENGTH;
2391 ret = memset_s(sc->sc_transfer.cmd_data, UMASS_MAX_CMDLEN, 0, ATAPI_COMMAND_LENGTH);
2408 if (sc->sc_quirks & FORCE_SHORT_INQUIRY) {
2409 ret = memcpy_s(sc->sc_transfer.cmd_data, UMASS_MAX_CMDLEN, cmd_ptr, cmd_len);
2414 sc->sc_transfer.cmd_data[4] = SHORT_INQUIRY_LENGTH;
2420 if (sc->sc_quirks & NO_TEST_UNIT_READY) {
2421 DPRINTF_UMASS(sc, UDMASS_SCSI, "Converted TEST_UNIT_READY "
2423 sc->sc_transfer.cmd_data[0] = START_STOP_UNIT;
2424 sc->sc_transfer.cmd_data[4] = SSS_START;
2467 DPRINTF_UMASS(sc, UDMASS_SCSI, "Unsupported ATAPI "
2473 ret = memcpy_s(sc->sc_transfer.cmd_data, UMASS_MAX_CMDLEN, cmd_ptr, cmd_len);
2483 umass_no_transform(struct umass_softc *sc, uint8_t *cmd,
2491 umass_bbb_dump_cbw(struct umass_softc *sc, umass_bbb_cbw_t *cbw)
2502 DPRINTF_UMASS(sc, UDMASS_BBB, "CBW %d: cmd = %db "
2512 umass_bbb_dump_csw(struct umass_softc *sc, umass_bbb_csw_t *csw)
2519 DPRINTF_UMASS(sc, UDMASS_BBB, "CSW %d: sig = 0x%08x (%s), tag = 0x%08x, "
2529 umass_cbi_dump_cmd(struct umass_softc *sc, void *cmd, uint8_t cmdlen)
2532 uint8_t dir = sc->sc_transfer.dir;
2534 DPRINTF_UMASS(sc, UDMASS_BBB, "cmd = %db "
2539 sc->sc_transfer.data_len,
2684 umass_test_unit_ready(struct umass_softc *sc)
2689 if((sc == NULL) || (sc->data_ccb == NULL)) {
2693 (void)umass_scsi_transform(sc, scsi_test_unit_ready, SCSICMD_TESTUNITREADY8_SIZEOF);
2694 res = umass_command_start(sc, DIR_NONE, NULL, 0, 1000, umass_cam_cb, sc->data_ccb);
2699 status = sc->data_ccb->csio.status;
2708 umass_read_capacity_16(struct umass_softc *sc)
2714 (void)umass_scsi_transform(sc, scsi_read_capacity_16, SCSICMD_READCAPACITY16_SIZEOF);
2715 res = (uint32_t)umass_command_start(sc, DIR_IN, sc->data_ccb->csio.data_ptr,
2717 (uint32_t)1000, umass_cam_cb, sc->data_ccb);
2722 ret = memcpy_s((void *)&resp, sizeof(resp), sc->data_ccb->csio.data_ptr,
2729 sc->info.sectornum= usbhost_getbe64(resp.lba) + 1;
2730 sc->info.sectorsize= usbhost_getbe32(resp.blklen);
2736 umass_read_capacity(struct umass_softc *sc)
2741 if ((sc == NULL) || (sc->data_ccb == NULL)) {
2745 (void)umass_scsi_transform(sc, scsi_read_capacity, SCSICMD_READCAPACITY10_SIZEOF);
2746 ret = umass_command_start(sc, DIR_IN, sc->data_ccb->csio.data_ptr,
2748 1000, umass_cam_cb, sc->data_ccb);
2753 ret = memcpy_s((void *)&resp, sizeof(resp), sc->data_ccb->csio.data_ptr,
2762 ret = umass_read_capacity_16(sc);
2767 sc->sc_super_disk = TRUE;
2772 sc->info.sectornum= usbhost_getbe32(resp.lba) + 1;
2773 sc->info.sectorsize= usbhost_getbe32(resp.blklen);
2774 sc->sc_super_disk = FALSE;
2780 umass_read10(struct umass_softc *sc, size_t startsector, uint16_t blocksize,
2789 if ((sc == NULL) || (sc->data_ccb == NULL)) {
2793 if ((sc->info.sectornum < (startsector + nsectors)) || (sc->info.sectorsize < blocksize))
2808 (void)umass_scsi_transform(sc, (uint8_t *)&cdb, SCSICMD_READ10_SIZEOF);
2809 ret = umass_command_start(sc, DIR_IN, (void *)data_buf, blocksize * nsectors, 0,
2810 umass_cam_cb, sc->data_ccb);
2818 if (!LOS_IsUserAddressRange((vaddr_t)buf, blocksize * nsectors - sc->data_ccb->csio.resid)) {
2819 ret = memcpy_s(buf, nsectors * blocksize, data_buf, blocksize * nsectors - sc->data_ccb->csio.resid);
2821 ret = ((nsectors * blocksize >= blocksize * nsectors - sc->data_ccb->csio.resid) ?
2822 LOS_ArchCopyToUser(buf, data_buf, blocksize * nsectors - sc->data_ccb->csio.resid) : ERANGE_AND_RESET);
2830 status = sc->data_ccb->csio.status;
2839 umass_read16(struct umass_softc *sc, uint64_t startsector, uint16_t blocksize,
2849 if ((sc == NULL) || (sc->data_ccb == NULL)) {
2853 if ((sc->info.sectornum < (startsector + nsectors)) || (sc->info.sectorsize < blocksize))
2867 (void)umass_scsi_transform(sc, (uint8_t *)&cdb, SCSICMD_READ16_SIZEOF);
2868 res = umass_command_start(sc, DIR_IN, (void *)data_buf, blocksize * nsectors, 0,
2869 umass_cam_cb, sc->data_ccb);
2877 if (!LOS_IsUserAddressRange((vaddr_t)buf, blocksize * nsectors - sc->data_ccb->csio.resid)) {
2878 ret = memcpy_s(buf, nsectors * blocksize, data_buf, blocksize * nsectors - sc->data_ccb->csio.resid);
2880 ret = ((nsectors * blocksize >= blocksize * nsectors - sc->data_ccb->csio.resid) ?
2881 LOS_ArchCopyToUser(buf, data_buf, blocksize * nsectors - sc->data_ccb->csio.resid) : ERANGE_AND_RESET);
2889 status = sc->data_ccb->csio.status;
2898 umass_write10(struct umass_softc *sc, size_t startsector, uint16_t blocksize,
2907 if((sc == NULL) || (sc->data_ccb == NULL)) {
2911 if ((sc->info.sectornum < (startsector + nsectors)) || (sc->info.sectorsize < blocksize))
2936 (void)umass_scsi_transform(sc, (uint8_t *)&cdb, SCSICMD_WRITE10_SIZEOF);
2937 ret = umass_command_start(sc, DIR_OUT, (void *)data_buf, blocksize * nsectors, 1000,
2938 umass_cam_cb, sc->data_ccb);
2944 status = sc->data_ccb->csio.status;
2953 umass_write16(struct umass_softc *sc, uint64_t startsector, uint16_t blocksize,
2963 if((sc == NULL) || (sc->data_ccb == NULL)) {
2967 if ((sc->info.sectornum < (startsector + nsectors)) || (sc->info.sectorsize < blocksize)) {
2994 (void)umass_scsi_transform(sc, (uint8_t *)&cdb, SCSICMD_WRITE16_SIZEOF);
2995 res = umass_command_start(sc, DIR_OUT, (void *)data_buf, blocksize * nsectors, 1000,
2996 umass_cam_cb, sc->data_ccb);
3003 status = sc->data_ccb->csio.status;
3012 umass_inquiry(struct umass_softc *sc)
3017 if ((sc == NULL) || (sc->data_ccb == NULL)) {
3021 (void)umass_scsi_transform(sc, scsi_inquiry, SCSICMD_INQUIRY_SIZEOF);
3022 ret = umass_command_start(sc, DIR_IN, sc->data_ccb->csio.data_ptr, SCSIRESP_INQUIRY_SIZEOF,
3023 1000, umass_cam_cb, sc->data_ccb);
3028 status = sc->data_ccb->csio.status;
3034 ret = umass_scsi_inquiry_data(sc, sc->data_ccb->csio.data_ptr, SCSIRESP_INQUIRY_SIZEOF);
3048 umass_request_sense(struct umass_softc *sc)
3052 if ((sc == NULL) || (sc->data_ccb == NULL)) {
3056 (void)umass_scsi_transform(sc, scsi_request_sense, SCSICMD_REQUESTSENSE_SIZEOF);
3057 ret = umass_command_start(sc, DIR_IN, sc->data_ccb->csio.data_ptr, SCSIRESP_FIXEDSENSEDATA_SIZEOF,
3058 1000, umass_cam_cb, sc->data_ccb);
3063 status = sc->data_ccb->csio.status;
3080 struct umass_softc *sc = p_umsf;
3091 if (sc == NULL) {
3095 cmd = sc->sc_transfer.cmd_data[0];
3096 lun = sc->sc_transfer.lun;
3097 max = sc->sc_maxlun + 1;
3098 speed = sc->sc_udev->speed;
3099 phase = sc->sc_last_xfer_index;
3100 state = USB_GET_STATE(sc->sc_xfer[phase]);
3101 vid = UGETW(sc->sc_udev->ddesc.idVendor);
3102 pid = UGETW(sc->sc_udev->ddesc.idProduct);
3103 tag = UGETDW(sc->cbw.dCBWTag);
3104 residuce = UGETDW(sc->csw.dCSWDataResidue);
3107 if (sc->sc_transfer.ccb) {
3170 struct umass_softc *sc = (struct umass_softc *)((struct drv_data*)umass_inode->data)->priv;
3172 mtx_lock(&sc->sc_umass_mtx);
3173 if (sc->sc_super_disk == TRUE) {
3174 status = umass_read16(sc, start_sector, (uint16_t)sc->info.sectorsize, nsectors, buffer);
3176 status = umass_read10(sc, (size_t)start_sector, (uint16_t)sc->info.sectorsize, nsectors, buffer);
3178 mtx_unlock(&sc->sc_umass_mtx);
3191 struct umass_softc *sc = (struct umass_softc *)((struct drv_data*)umass_inode->data)->priv;
3193 mtx_lock(&sc->sc_umass_mtx);
3194 if (sc->sc_super_disk == TRUE) {
3195 status = umass_write16(sc, start_sector, (uint16_t)sc->info.sectorsize, nsectors, buffer);
3197 status = umass_write10(sc, (size_t)start_sector, (uint16_t)sc->info.sectorsize, nsectors, buffer);
3199 mtx_unlock(&sc->sc_umass_mtx);
3210 struct umass_softc *sc;
3215 sc = (struct umass_softc *)(struct umass_softc *)((struct drv_data*)umass_inode->data)->priv;
3217 if (sc == NULL)
3220 mtx_lock(&sc->sc_umass_mtx);
3224 ugeometry->geo_nsectors = sc->info.sectornum;
3225 ugeometry->geo_sectorsize = sc->info.sectorsize;
3226 mtx_unlock(&sc->sc_umass_mtx);
3251 umass_dev_is_ready(struct umass_softc *sc)
3257 mtx_lock(&sc->sc_umass_mtx);
3258 for (lun = 0; lun <= sc->sc_maxlun; lun++) {
3259 sc->sc_transfer.lun = lun;
3260 if (umass_inquiry(sc) < 0)
3264 ret = umass_test_unit_ready(sc);
3266 sc->sc_transfer.lun = valid_lun;
3267 ret = umass_read_capacity(sc);
3269 mtx_unlock(&sc->sc_umass_mtx);
3273 mtx_unlock(&sc->sc_umass_mtx);
3277 ret = umass_request_sense(sc);
3280 mtx_unlock(&sc->sc_umass_mtx);
3284 mtx_unlock(&sc->sc_umass_mtx);
3289 umass_attach_dev_sub(struct umass_softc *sc, unsigned int dev_unit)
3305 dev = sc->sc_dev;
3306 udev = sc->sc_udev;
3317 ret = los_disk_init(devname, &g_dev_umass_ops, (void *)sc, disk_id, NULL);
3350 umass_detach_dev_sub(struct umass_softc *sc, int dev_unit, int flag)
3364 dev = sc->sc_dev;
3365 udev = sc->sc_udev;
3391 umass_dev_delete(sc, dev_unit);
3410 struct umass_softc *sc;
3416 sc = dev[i].sc;
3417 ret = umass_dev_is_ready(sc);
3420 umass_detach_dev_sub(sc, dev[i].dev_unit, 1);
3432 ret = umass_attach_dev_sub(sc, dev[i].dev_unit);
3457 umass_dev_add(struct umass_softc *sc, int dev_unit)
3466 g_umass_dev_array[id].sc = sc;
3473 umass_dev_delete(struct umass_softc *sc, unsigned int dev_unit)
3483 g_umass_dev_array[id].sc == sc) {
3485 g_umass_dev_array[id].sc = NULL;
3555 umass_attach_dev(struct umass_softc *sc, unsigned int dev_unit)
3565 umass_dev_add(sc, dev_unit);
3568 ret = umass_dev_is_ready(sc);
3570 ret = umass_attach_dev_sub(sc, dev_unit);
3573 umass_dev_delete(sc, dev_unit);