107#include <sys/stdint.h>
108#include <sys/stddef.h>
109#include <sys/param.h>
110#include <sys/queue.h>
111#include <sys/types.h>
112#include <sys/systm.h>
113#include <sys/kernel.h>
115#include <sys/module.h>
117#include <sys/mutex.h>
118#include <sys/condvar.h>
119#include <sys/sysctl.h>
121#include <sys/unistd.h>
122#include <sys/callout.h>
123#include <sys/malloc.h>
134#include <cam/cam_ccb.h>
135#include <cam/cam_sim.h>
136#include <cam/cam_xpt_sim.h>
137#include <cam/scsi/scsi_all.h>
138#include <cam/scsi/scsi_da.h>
140#include <cam/cam_periph.h>
145 if (umass_debug & (m)) { x ; } \
148#define DPRINTF(sc, m, fmt, ...) \
150 if (umass_debug & (m)) { \
151 printf("%s:%s: " fmt, \
152 (sc) ? (const char *)(sc)->sc_name : \
153 (const char *)"umassX", \
154 __FUNCTION__ ,## __VA_ARGS__); \
158#define UDMASS_GEN 0x00010000
159#define UDMASS_SCSI 0x00020000
160#define UDMASS_UFI 0x00040000
161#define UDMASS_ATAPI 0x00080000
162#define UDMASS_CMD (UDMASS_SCSI|UDMASS_UFI|UDMASS_ATAPI)
163#define UDMASS_USB 0x00100000
164#define UDMASS_BBB 0x00200000
165#define UDMASS_CBI 0x00400000
166#define UDMASS_WIRE (UDMASS_BBB|UDMASS_CBI)
167#define UDMASS_ALL 0xffff0000
168static int umass_debug;
169static int umass_throttle;
171static SYSCTL_NODE(_hw_usb, OID_AUTO, umass, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
174 &umass_debug, 0,
"umass debug level");
175SYSCTL_INT(_hw_usb_umass, OID_AUTO, throttle, CTLFLAG_RWTUN,
176 &umass_throttle, 0,
"Forced delay between commands in milliseconds");
178#define DIF(...) do { } while (0)
179#define DPRINTF(...) do { } while (0)
182#define UMASS_BULK_SIZE (1 << 17)
183#define UMASS_CBI_DIAGNOSTIC_CMDLEN 12
184#define UMASS_MAX_CMDLEN MAX(12, CAM_MAX_CDBLEN)
188#define UMASS_T_BBB_RESET1 0
189#define UMASS_T_BBB_RESET2 1
190#define UMASS_T_BBB_RESET3 2
191#define UMASS_T_BBB_COMMAND 3
192#define UMASS_T_BBB_DATA_READ 4
193#define UMASS_T_BBB_DATA_RD_CS 5
194#define UMASS_T_BBB_DATA_WRITE 6
195#define UMASS_T_BBB_DATA_WR_CS 7
196#define UMASS_T_BBB_STATUS 8
197#define UMASS_T_BBB_MAX 9
199#define UMASS_T_CBI_RESET1 0
200#define UMASS_T_CBI_RESET2 1
201#define UMASS_T_CBI_RESET3 2
202#define UMASS_T_CBI_COMMAND 3
203#define UMASS_T_CBI_DATA_READ 4
204#define UMASS_T_CBI_DATA_RD_CS 5
205#define UMASS_T_CBI_DATA_WRITE 6
206#define UMASS_T_CBI_DATA_WR_CS 7
207#define UMASS_T_CBI_STATUS 8
208#define UMASS_T_CBI_RESET4 9
209#define UMASS_T_CBI_MAX 10
211#define UMASS_T_MAX MAX(UMASS_T_CBI_MAX, UMASS_T_BBB_MAX)
221#define DEVNAME "umass"
222#define DEVNAME_SIM "umass-sim"
225#define UMASS_FULL_TRANSFER_SPEED 1000
226#define UMASS_HIGH_TRANSFER_SPEED 40000
227#define UMASS_SUPER_TRANSFER_SPEED 400000
228#define UMASS_FLOPPY_TRANSFER_SPEED 20
230#define UMASS_TIMEOUT 5000
234#define UMASS_SCSIID_MAX 1
235#define UMASS_SCSIID_HOST UMASS_SCSIID_MAX
239#define UR_BBB_RESET 0xff
240#define UR_BBB_GET_MAX_LUN 0xfe
245#define CBWSIGNATURE 0x43425355
249#define CBWFLAGS_OUT 0x00
250#define CBWFLAGS_IN 0x80
253#define CBWCDBLENGTH 16
257#define UMASS_BBB_CBW_SIZE 31
262#define CSWSIGNATURE 0x53425355
263#define CSWSIGNATURE_IMAGINATION_DBX1 0x43425355
264#define CSWSIGNATURE_OLYMPUS_C1 0x55425355
268#define CSWSTATUS_GOOD 0x0
269#define CSWSTATUS_FAILED 0x1
270#define CSWSTATUS_PHASE 0x2
273#define UMASS_BBB_CSW_SIZE 13
277#define UR_CBI_ADSC 0x00
282#define IDB_TYPE_CCI 0x00
284#define IDB_VALUE_PASS 0x00
285#define IDB_VALUE_FAIL 0x01
286#define IDB_VALUE_PHASE 0x02
287#define IDB_VALUE_PERSISTENT 0x03
288#define IDB_VALUE_STATUS_MASK 0x03
300 uint32_t residue, uint8_t
status);
302#define STATUS_CMD_OK 0
303#define STATUS_CMD_UNKNOWN 1
304#define STATUS_CMD_FAILED 2
305#define STATUS_WIRE_FAILED 3
311#define UMASS_PROTO_BBB 0x0001
312#define UMASS_PROTO_CBI 0x0002
313#define UMASS_PROTO_CBI_I 0x0004
314#define UMASS_PROTO_WIRE 0x00ff
315#define UMASS_PROTO_SCSI 0x0100
316#define UMASS_PROTO_ATAPI 0x0200
317#define UMASS_PROTO_UFI 0x0400
318#define UMASS_PROTO_RBC 0x0800
319#define UMASS_PROTO_COMMAND 0xff00
322#define NO_QUIRKS 0x0000
326#define NO_TEST_UNIT_READY 0x0001
333#define RS_NO_CLEAR_UA 0x0002
335#define NO_START_STOP 0x0004
337#define FORCE_SHORT_INQUIRY 0x0008
339#define SHUTTLE_INIT 0x0010
341#define ALT_IFACE_1 0x0020
343#define FLOPPY_SPEED 0x0040
345#define IGNORE_RESIDUE 0x0080
347#define NO_GETMAXLUN 0x0100
349#define WRONG_CSWSIG 0x0200
351#define NO_INQUIRY 0x0400
353#define NO_INQUIRY_EVPD 0x0800
355#define RBC_PAD_TO_12 0x1000
360#define READ_CAPACITY_OFFBY1 0x2000
368#define NO_SYNCHRONIZE_CACHE 0x4000
370#define NO_PREVENT_ALLOW 0x8000
487static void umass_bbb_dump_cbw(
struct umass_softc *, umass_bbb_cbw_t *);
488static void umass_bbb_dump_csw(
struct umass_softc *, umass_bbb_csw_t *);
489static void umass_cbi_dump_cmd(
struct umass_softc *,
void *, uint8_t);
490static void umass_dump_buffer(
struct umass_softc *, uint8_t *, uint32_t,
529 .bufsize =
sizeof(umass_bbb_cbw_t),
539 .flags = {.proxy_buffer = 1,.short_xfer_ok = 1,.ext_buffer=1,},
558 .flags = {.proxy_buffer = 1,.short_xfer_ok = 1,.ext_buffer=1,},
576 .bufsize =
sizeof(umass_bbb_csw_t),
577 .flags = {.short_xfer_ok = 1,},
630 .flags = {.proxy_buffer = 1,.short_xfer_ok = 1,.ext_buffer=1,},
649 .flags = {.proxy_buffer = 1,.short_xfer_ok = 1,.ext_buffer=1,},
667 .flags = {.short_xfer_ok = 1,.no_pipe_ok = 1,},
668 .bufsize =
sizeof(umass_cbi_sbl_t),
685 0, 0x80, SCSI_REV_2, SCSI_REV_2,
689#define UFI_COMMAND_LENGTH 12
690#define ATAPI_COMMAND_LENGTH 12
738 switch (
id->bInterfaceSubClass) {
756 switch (
id->bInterfaceProtocol) {
784 memset(&ret, 0,
sizeof(ret));
785 ret.
error = BUS_PROBE_GENERIC;
796 proto &= ~UMASS_PROTO_WIRE;
799 proto &= ~UMASS_PROTO_WIRE;
802 proto &= ~UMASS_PROTO_WIRE;
807 proto &= ~UMASS_PROTO_COMMAND;
810 proto &= ~UMASS_PROTO_COMMAND;
813 proto &= ~UMASS_PROTO_COMMAND;
816 proto &= ~UMASS_PROTO_COMMAND;
909 "%s", device_get_nameunit(
dev));
913 mtx_init(&sc->
sc_mtx, device_get_nameunit(
dev),
914 NULL, MTX_DEF | MTX_RECURSE);
920 device_printf(
dev,
"failed to get "
921 "interface number\n");
927 device_printf(
dev,
" ");
934 printf(
"8070i (ATAPI)");
943 printf(
"(unknown 0x%02x)",
958 printf(
"CBI with CCI");
961 printf(
"(unknown 0x%02x)",
965 printf(
"; quirks = 0x%04x\n", sc->
sc_quirks);
973 DPRINTF(sc, UDMASS_USB,
"could not switch to "
974 "Alt Interface 1\n");
1001 device_printf(
dev,
"could not setup required "
1006 if (umass_throttle > 0) {
1010 iv = umass_throttle;
1055 DPRINTF(sc, UDMASS_GEN,
"Attach finished\n");
1069 DPRINTF(sc, UDMASS_USB,
"\n");
1085 mtx_destroy(&sc->
sc_mtx);
1094 uint8_t
status[2] = {0, 0};
1108 DPRINTF(sc, UDMASS_GEN,
"Shuttle init returned 0x%02x%02x\n",
1119 DPRINTF(sc, UDMASS_GEN,
"transfer index = "
1120 "%d\n", xfer_index);
1122 if (sc->
sc_xfer[xfer_index]) {
1133 DPRINTF(sc, UDMASS_GEN,
"resetting device\n");
1166 DPRINTF(sc, UDMASS_GEN,
"transfer error, %s -> "
1203 DPRINTF(sc, UDMASS_BBB,
"BBB reset!\n");
1254 goto tr_transferred;
1320 DPRINTF(sc, UDMASS_BBB,
"Truncating long command!\n");
1329 memset(sc->
cbw.CBWCDB +
1331 sizeof(sc->
cbw.CBWCDB) -
1334 DIF(UDMASS_BBB, umass_bbb_dump_cbw(sc, &sc->
cbw));
1370 DPRINTF(sc, UDMASS_BBB,
"max_bulk=%d, data_rem=%d\n",
1425 DPRINTF(sc, UDMASS_BBB,
"max_bulk=%d, data_rem=%d\n",
1481 if (actlen < (
int)
sizeof(sc->
csw))
1482 memset(&sc->
csw, 0,
sizeof(sc->
csw));
1487 DIF(UDMASS_BBB, umass_bbb_dump_csw(sc, &sc->
csw));
1489 residue =
UGETDW(sc->
csw.dCSWDataResidue);
1496 DPRINTF(sc, UDMASS_BBB,
"truncating residue from %d "
1502 uint32_t temp =
UGETDW(sc->
csw.dCSWSignature);
1511 DPRINTF(sc, UDMASS_BBB,
"bad CSW signature 0x%08x != 0x%08x\n",
1520 DPRINTF(sc, UDMASS_BBB,
"Invalid CSW: tag 0x%08x should be "
1525 DPRINTF(sc, UDMASS_BBB,
"Invalid CSW: status %d > %d\n",
1529 DPRINTF(sc, UDMASS_BBB,
"Phase error, residue = "
1533 DPRINTF(sc, UDMASS_BBB,
"Buffer overrun %d > %d\n",
1537 DPRINTF(sc, UDMASS_BBB,
"Command failed, residue = "
1563 DPRINTF(sc, UDMASS_BBB,
"Failed to read CSW: %s, try %d\n",
1579 void *data_ptr, uint32_t data_len,
1628 printf(
"%s: Get Max Lun not supported (%s)\n",
1685 DPRINTF(sc, UDMASS_CBI,
"CBI reset!\n");
1771 goto tr_transferred;
1831 umass_cbi_dump_cmd(sc,
1881 DPRINTF(sc, UDMASS_CBI,
"max_bulk=%d, data_rem=%d\n",
1937 DPRINTF(sc, UDMASS_CBI,
"max_bulk=%d, data_rem=%d\n",
1988 if (actlen < (
int)
sizeof(sc->
sbl)) {
2006 DPRINTF(sc, UDMASS_CBI,
"UFI CCI, ASC = 0x%02x, "
2007 "ASCQ = 0x%02x\n", sc->
sbl.ufi.asc,
2011 (sc->
sbl.ufi.ascq == 0)) ?
2019 (sc, ccb, residue,
status);
2026 DPRINTF(sc, UDMASS_CBI,
"type=0x%02x, value=0x%02x\n",
2027 sc->
sbl.common.type, sc->
sbl.common.value);
2042 (sc, ccb, residue,
status);
2057 DPRINTF(sc, UDMASS_CBI,
"Failed to read CSW: %s\n",
2071 struct cam_devq *devq;
2081 devq = cam_simq_alloc(1 );
2085 sc->
sc_sim = cam_sim_alloc
2095 if (sc->
sc_sim == NULL) {
2096 cam_simq_free(devq);
2102 if (
status != CAM_SUCCESS) {
2103 cam_sim_free(sc->
sc_sim, TRUE);
2105 printf(
"%s: xpt_bus_register failed with status %#x\n",
2120 printf(
"%s:%d:%d: Attached to scbus%d\n",
2134 if (sc->
sc_sim != NULL) {
2135 error = xpt_bus_deregister(cam_sim_path(sc->
sc_sim));
2138 sc->
sc_sim->softc = NULL;
2139 DPRINTF(sc, UDMASS_SCSI,
"%s: %s:%d:%d caling "
2140 "cam_sim_free sim %p refc %u mtx %p\n",
2144 cam_sim_free(sc->
sc_sim, TRUE);
2146 panic(
"%s: %s: CAM layer is busy: errno %d\n",
2163 ccb->ccb_h.status = CAM_SEL_TIMEOUT;
2169 switch (
ccb->ccb_h.func_code) {
2175 if (
ccb->csio.ccb_h.flags & CAM_CDB_POINTER) {
2176 cmd = (uint8_t *)(
ccb->csio.cdb_io.cdb_ptr);
2178 cmd = (uint8_t *)(
ccb->csio.cdb_io.cdb_bytes);
2181 DPRINTF(sc, UDMASS_SCSI,
"%d:%d:%jx:XPT_SCSI_IO: "
2182 "cmd: 0x%02x, flags: 0x%02x, "
2183 "%db cmd/%db data/%db sense\n",
2184 cam_sim_path(sc->
sc_sim),
ccb->ccb_h.target_id,
2185 (uintmax_t)
ccb->ccb_h.target_lun, cmd[0],
2186 ccb->ccb_h.flags & CAM_DIR_MASK,
ccb->csio.cdb_len,
2187 ccb->csio.dxfer_len,
ccb->csio.sense_len);
2190 DPRINTF(sc, UDMASS_SCSI,
"%d:%d:%jx:XPT_SCSI_IO: "
2191 "I/O in progress, deferring\n",
2192 cam_sim_path(sc->
sc_sim),
ccb->ccb_h.target_id,
2193 (uintmax_t)
ccb->ccb_h.target_lun);
2194 ccb->ccb_h.status = CAM_SCSI_BUSY;
2198 switch (
ccb->ccb_h.flags & CAM_DIR_MASK) {
2205 umass_dump_buffer(sc,
ccb->csio.data_ptr,
2206 ccb->csio.dxfer_len, 48));
2212 ccb->ccb_h.status = CAM_REQ_INPROG | CAM_SIM_QUEUED;
2222 const char *pserial;
2232 (pserial[0] !=
'\0')) {
2233 struct scsi_vpd_unit_serial_number *vpd_serial;
2235 vpd_serial = (
struct scsi_vpd_unit_serial_number *)ccb->csio.data_ptr;
2236 vpd_serial->length = strlen(pserial);
2237 if (vpd_serial->length >
sizeof(vpd_serial->serial_num))
2238 vpd_serial->length =
sizeof(vpd_serial->serial_num);
2239 memcpy(vpd_serial->serial_num, pserial, vpd_serial->length);
2240 ccb->csio.scsi_status = SCSI_STATUS_OK;
2241 ccb->ccb_h.status = CAM_REQ_CMP;
2252 scsi_set_sense_data(&ccb->csio.sense_data,
2255 SSD_KEY_ILLEGAL_REQUEST,
2259 ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
2261 CAM_SCSI_STATUS_ERROR |
2264 xpt_freeze_devq(ccb->ccb_h.path, 1);
2275 ccb->csio.scsi_status = SCSI_STATUS_OK;
2276 ccb->ccb_h.status = CAM_REQ_CMP;
2281 ccb->csio.dxfer_len = SHORT_INQUIRY_LENGTH;
2285 ccb->csio.scsi_status = SCSI_STATUS_OK;
2286 ccb->ccb_h.status = CAM_REQ_CMP;
2292 ccb->csio.scsi_status = SCSI_STATUS_OK;
2293 ccb->ccb_h.status = CAM_REQ_CMP;
2299 ccb->csio.scsi_status = SCSI_STATUS_OK;
2300 ccb->ccb_h.status = CAM_REQ_CMP;
2306 ccb->csio.dxfer_len,
2314 struct ccb_pathinq *cpi = &ccb->cpi;
2316 DPRINTF(sc, UDMASS_SCSI,
"%d:%d:%jx:XPT_PATH_INQ:.\n",
2317 sc ? cam_sim_path(sc->
sc_sim) : -1, ccb->ccb_h.target_id,
2318 (uintmax_t)ccb->ccb_h.target_lun);
2321 cpi->version_num = 1;
2322 cpi->hba_inquiry = 0;
2323 cpi->target_sprt = 0;
2324 cpi->hba_misc = PIM_NO_6_BYTE;
2325 cpi->hba_eng_cnt = 0;
2328 strlcpy(cpi->sim_vid,
"FreeBSD", SIM_IDLEN);
2329 strlcpy(cpi->hba_vid,
"USB SCSI", HBA_IDLEN);
2330 strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
2331 cpi->unit_number = cam_sim_unit(sim);
2333 cpi->protocol = PROTO_SCSI;
2334 cpi->protocol_version = SCSI_REV_2;
2335 cpi->transport = XPORT_USB;
2336 cpi->transport_version = 0;
2339 cpi->base_transfer_speed = 0;
2343 cpi->base_transfer_speed =
2348 cpi->base_transfer_speed =
2350 cpi->maxio = maxphys;
2353 cpi->base_transfer_speed =
2357 cpi->base_transfer_speed =
2365 cpi->ccb_h.status = CAM_REQ_CMP;
2371 DPRINTF(sc, UDMASS_SCSI,
"%d:%d:%jx:XPT_RESET_DEV:.\n",
2372 cam_sim_path(sc->
sc_sim), ccb->ccb_h.target_id,
2373 (uintmax_t)ccb->ccb_h.target_lun);
2377 ccb->ccb_h.status = CAM_REQ_CMP;
2381 case XPT_GET_TRAN_SETTINGS:
2383 struct ccb_trans_settings *cts = &ccb->cts;
2385 DPRINTF(sc, UDMASS_SCSI,
"%d:%d:%jx:XPT_GET_TRAN_SETTINGS:.\n",
2386 cam_sim_path(sc->
sc_sim), ccb->ccb_h.target_id,
2387 (uintmax_t)ccb->ccb_h.target_lun);
2389 cts->protocol = PROTO_SCSI;
2390 cts->protocol_version = SCSI_REV_2;
2391 cts->transport = XPORT_USB;
2392 cts->transport_version = 0;
2393 cts->xport_specific.valid = 0;
2395 ccb->ccb_h.status = CAM_REQ_CMP;
2399 case XPT_SET_TRAN_SETTINGS:
2401 DPRINTF(sc, UDMASS_SCSI,
"%d:%d:%jx:XPT_SET_TRAN_SETTINGS:.\n",
2402 cam_sim_path(sc->
sc_sim), ccb->ccb_h.target_id,
2403 (uintmax_t)ccb->ccb_h.target_lun);
2405 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
2409 case XPT_CALC_GEOMETRY:
2411 cam_calc_geometry(&ccb->ccg, 1);
2417 DPRINTF(sc, UDMASS_SCSI,
"%d:%d:%jx:XPT_NOOP:.\n",
2418 sc ? cam_sim_path(sc->
sc_sim) : -1, ccb->ccb_h.target_id,
2419 (uintmax_t)ccb->ccb_h.target_lun);
2421 ccb->ccb_h.status = CAM_REQ_CMP;
2426 DPRINTF(sc, UDMASS_SCSI,
"%d:%d:%jx:func_code 0x%04x: "
2427 "Not implemented\n",
2428 sc ? cam_sim_path(sc->
sc_sim) : -1, ccb->ccb_h.target_id,
2429 (uintmax_t)ccb->ccb_h.target_lun, ccb->ccb_h.func_code);
2431 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
2448 DPRINTF(sc, UDMASS_SCSI,
"CAM poll\n");
2461 ccb->csio.resid = residue;
2465 ccb->ccb_h.status = CAM_REQ_CMP;
2467 (
ccb->ccb_h.func_code == XPT_SCSI_IO) &&
2468 (
ccb->csio.cdb_io.cdb_bytes[0] == READ_CAPACITY)) {
2469 struct scsi_read_capacity_data *rcap;
2472 rcap = (
void *)(ccb->csio.data_ptr);
2473 maxsector = scsi_4btoul(rcap->addr) - 1;
2474 scsi_ulto4b(maxsector, rcap->addr);
2482 if (ccb->ccb_h.func_code == XPT_SCSI_IO &&
2487 struct ccb_scsiio *csio;
2488 struct scsi_vpd_supported_page_list *page_list;
2491 page_list = (
struct scsi_vpd_supported_page_list *)csio->data_ptr;
2492 if (page_list->length + 1 < SVPD_SUPPORTED_PAGES_SIZE) {
2493 page_list->list[page_list->length] = SVPD_UNIT_SERIAL_NUMBER;
2494 page_list->length++;
2508 DPRINTF(sc, UDMASS_SCSI,
"Fetching %d bytes of "
2509 "sense data\n", ccb->csio.sense_len);
2515 ccb->csio.sense_len = SHORT_INQUIRY_LENGTH;
2518 ccb->csio.sense_len, ccb->ccb_h.timeout,
2529 xpt_freeze_devq(ccb->ccb_h.path, 1);
2530 ccb->ccb_h.status = CAM_REQ_CMP_ERR | CAM_DEV_QFRZN;
2551 ccb->csio.sense_resid = residue;
2552 sense_len = ccb->csio.sense_len - ccb->csio.sense_resid;
2553 key = scsi_get_sense_key(&ccb->csio.sense_data, sense_len,
2556 if (ccb->csio.ccb_h.flags & CAM_CDB_POINTER) {
2557 cmd = (uint8_t *)(ccb->csio.cdb_io.cdb_ptr);
2559 cmd = (uint8_t *)(ccb->csio.cdb_io.cdb_bytes);
2567 (cmd[0] == INQUIRY) &&
2568 (key == SSD_KEY_UNIT_ATTENTION)) {
2575 ccb->ccb_h.status = CAM_REQ_CMP;
2576 }
else if (key == SSD_KEY_NO_SENSE) {
2581 ccb->ccb_h.status = CAM_REQ_CMP;
2583 (cmd[0] == READ_CAPACITY) &&
2584 (key == SSD_KEY_UNIT_ATTENTION)) {
2593 xpt_freeze_devq(ccb->ccb_h.path, 1);
2594 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR
2595 | CAM_AUTOSNS_VALID | CAM_DEV_QFRZN;
2596 ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
2601 DPRINTF(sc, UDMASS_SCSI,
"Doing a sneaky"
2602 "TEST_UNIT_READY\n");
2615 xpt_freeze_devq(ccb->ccb_h.path, 1);
2617 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR
2618 | CAM_AUTOSNS_VALID | CAM_DEV_QFRZN;
2619 ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
2621 ccb->ccb_h.status = CAM_AUTOSENSE_FAIL
2628 DPRINTF(sc, UDMASS_SCSI,
"Autosense failed, "
2630 xpt_freeze_devq(ccb->ccb_h.path, 1);
2631 ccb->ccb_h.status = CAM_AUTOSENSE_FAIL | CAM_DEV_QFRZN;
2645 DPRINTF(sc, UDMASS_SCSI,
"Test unit ready "
2646 "returned status %d\n",
status);
2659 if ((cmd_len == 0) ||
2661 DPRINTF(sc, UDMASS_SCSI,
"Invalid command "
2662 "length: %d bytes\n", cmd_len);
2667 switch (cmd_ptr[0]) {
2668 case TEST_UNIT_READY:
2670 DPRINTF(sc, UDMASS_SCSI,
"Converted TEST_UNIT_READY "
2699 if ((cmd_len == 0) ||
2701 DPRINTF(sc, UDMASS_SCSI,
"Invalid command "
2702 "length: %d bytes\n", cmd_len);
2705 switch (cmd_ptr[0]) {
2709 case START_STOP_UNIT:
2710 case SYNCHRONIZE_CACHE:
2714 case MODE_SELECT_10:
2716 case TEST_UNIT_READY:
2738 DPRINTF(sc, UDMASS_SCSI,
"Unsupported RBC "
2739 "command 0x%02x\n", cmd_ptr[0]);
2748 if ((cmd_len == 0) ||
2750 DPRINTF(sc, UDMASS_SCSI,
"Invalid command "
2751 "length: %d bytes\n", cmd_len);
2760 switch (cmd_ptr[0]) {
2766 case TEST_UNIT_READY:
2772 DPRINTF(sc, UDMASS_UFI,
"Converted TEST_UNIT_READY "
2785 case START_STOP_UNIT:
2786 case SEND_DIAGNOSTIC:
2791 case POSITION_TO_ELEMENT:
2792 case WRITE_AND_VERIFY:
2794 case MODE_SELECT_10:
2798 case READ_FORMAT_CAPACITIES:
2806 case SYNCHRONIZE_CACHE:
2810 DPRINTF(sc, UDMASS_SCSI,
"Unsupported UFI "
2811 "command 0x%02x\n", cmd_ptr[0]);
2826 if ((cmd_len == 0) ||
2828 DPRINTF(sc, UDMASS_SCSI,
"Invalid command "
2829 "length: %d bytes\n", cmd_len);
2838 switch (cmd_ptr[0]) {
2857 case TEST_UNIT_READY:
2859 DPRINTF(sc, UDMASS_SCSI,
"Converted TEST_UNIT_READY "
2869 case START_STOP_UNIT:
2870 case SEND_DIAGNOSTIC:
2875 case POSITION_TO_ELEMENT:
2876 case SYNCHRONIZE_CACHE:
2877 case MODE_SELECT_10:
2905 DPRINTF(sc, UDMASS_SCSI,
"Unsupported ATAPI "
2906 "command 0x%02x - trying anyway\n",
2924 uint8_t *cmd, uint8_t cmdlen)
2931 ccb->ccb_h.status = CAM_REQ_CMP;
2934 }
else if (retval == 0) {
2935 xpt_freeze_devq(ccb->ccb_h.path, 1);
2936 ccb->ccb_h.status = CAM_REQ_INVALID | CAM_DEV_QFRZN;
2946umass_bbb_dump_cbw(
struct umass_softc *sc, umass_bbb_cbw_t *cbw)
2948 uint8_t *c = cbw->CBWCDB;
2950 uint32_t dlen =
UGETDW(cbw->dCBWDataTransferLength);
2951 uint32_t tag =
UGETDW(cbw->dCBWTag);
2953 uint8_t clen = cbw->bCDBLength;
2954 uint8_t flags = cbw->bCBWFlags;
2955 uint8_t lun = cbw->bCBWLUN;
2957 DPRINTF(sc, UDMASS_BBB,
"CBW %d: cmd = %db "
2958 "(0x%02x%02x%02x%02x%02x%02x%s), "
2959 "data = %db, lun = %d, dir = %s\n",
2961 c[0], c[1], c[2], c[3], c[4], c[5], (clen > 6 ?
"..." :
""),
2967umass_bbb_dump_csw(
struct umass_softc *sc, umass_bbb_csw_t *csw)
2969 uint32_t sig =
UGETDW(csw->dCSWSignature);
2970 uint32_t tag =
UGETDW(csw->dCSWTag);
2971 uint32_t res =
UGETDW(csw->dCSWDataResidue);
2972 uint8_t
status = csw->bCSWStatus;
2974 DPRINTF(sc, UDMASS_BBB,
"CSW %d: sig = 0x%08x (%s), tag = 0x%08x, "
2975 "res = %d, status = 0x%02x (%s)\n",
2984umass_cbi_dump_cmd(
struct umass_softc *sc,
void *cmd, uint8_t cmdlen)
2989 DPRINTF(sc, UDMASS_BBB,
"cmd = %db "
2990 "(0x%02x%02x%02x%02x%02x%02x%s), "
2991 "data = %db, dir = %s\n",
2993 c[0], c[1], c[2], c[3], c[4], c[5], (cmdlen > 6 ?
"..." :
""),
2997 (dir ==
DIR_NONE ?
"no data phase" :
"<invalid>"))));
3001umass_dump_buffer(
struct umass_softc *sc, uint8_t *buffer, uint32_t buflen,
3012 sprintf(s2,
" buffer=%p, buflen=%d", buffer, buflen);
3013 for (i = 0; (i < buflen) && (i < printlen); i++) {
3015 if (j == 0 && i != 0) {
3016 DPRINTF(sc, UDMASS_GEN,
"0x %s%s\n",
3020 sprintf(&s1[j * 2],
"%02x", buffer[i] & 0xff);
3022 if (buflen > printlen)
3023 sprintf(s3,
" ...");
3024 DPRINTF(sc, UDMASS_GEN,
"0x %s%s%s\n",
static SYSCTL_NODE(_hw_usb, OID_AUTO, dwc_otg, CTLFLAG_RW|CTLFLAG_MPSAFE, 0, "USB DWC OTG")
SYSCTL_INT(_hw_usb_dwc_otg, OID_AUTO, phy_type, CTLFLAG_RDTUN, &dwc_otg_phy_type, 0, "DWC OTG PHY TYPE - 0/1/2/3 - ULPI/HSIC/INTERNAL/UTMI+")
uDWord dCBWDataTransferLength
uint8_t cmd_data[UMASS_MAX_CMDLEN]
struct scsi_sense cam_scsi_sense
struct usb_xfer * sc_xfer[UMASS_T_MAX]
struct umass_softc::@71 sc_transfer
umass_callback_t * callback
struct scsi_test_unit_ready cam_scsi_test_unit_ready
uint8_t sc_last_xfer_index
umass_transform_t * sc_transform
struct usb_device * sc_udev
enum usb_hc_mode usb_mode
struct usbd_lookup_info info
struct usb_interface * iface
struct usb_device * device
static usb_callback_t umass_t_bbb_command_callback
static void umass_t_cbi_data_clear_stall_callback(struct usb_xfer *, uint8_t, uint8_t, usb_error_t)
static void umass_cam_quirk_cb(struct umass_softc *, union ccb *, uint32_t, uint8_t)
#define IDB_VALUE_STATUS_MASK
static void umass_t_bbb_data_clear_stall_callback(struct usb_xfer *, uint8_t, uint8_t, usb_error_t)
#define UMASS_T_BBB_RESET1
static uint8_t umass_bbb_get_max_lun(struct umass_softc *)
static devclass_t umass_devclass
static usb_callback_t umass_t_cbi_command_callback
static void umass_cam_action(struct cam_sim *, union ccb *)
#define UMASS_PROTO_CBI_I
uint8_t() umass_transform_t(struct umass_softc *sc, uint8_t *cmd_ptr, uint8_t cmd_len)
USB_PNP_HOST_INFO(umass_devs)
static void umass_reset(struct umass_softc *)
static uint8_t umass_rbc_transform(struct umass_softc *, uint8_t *, uint8_t)
#define UMASS_T_CBI_DATA_WRITE
static void umass_init_shuttle(struct umass_softc *)
static device_probe_t umass_probe
static usb_callback_t umass_t_cbi_reset2_callback
#define UMASS_T_BBB_DATA_READ
#define STATUS_CMD_FAILED
static void umass_cam_sense_cb(struct umass_softc *, union ccb *, uint32_t, uint8_t)
static usb_callback_t umass_t_cbi_data_write_callback
#define CSWSIGNATURE_IMAGINATION_DBX1
static const STRUCT_USB_HOST_ID __used umass_devs[]
static usb_callback_t umass_t_cbi_data_read_callback
static void umass_cam_attach(struct umass_softc *)
#define UMASS_T_CBI_STATUS
static driver_t umass_driver
static usb_callback_t umass_t_cbi_status_callback
#define NO_TEST_UNIT_READY
static void umass_cbi_start_status(struct umass_softc *)
static usb_callback_t umass_t_bbb_data_write_callback
#define UMASS_T_CBI_DATA_RD_CS
static usb_callback_t umass_t_bbb_data_rd_cs_callback
static usb_callback_t umass_t_bbb_reset2_callback
#define UMASS_FULL_TRANSFER_SPEED
MODULE_DEPEND(umass, usb, 1, 1, 1)
#define NO_SYNCHRONIZE_CACHE
#define UMASS_T_CBI_RESET4
static uint8_t umass_atapi_transform(struct umass_softc *, uint8_t *, uint8_t)
#define UR_BBB_GET_MAX_LUN
static usb_callback_t umass_t_cbi_data_wr_cs_callback
#define UMASS_T_CBI_RESET1
#define FORCE_SHORT_INQUIRY
static void umass_transfer_start(struct umass_softc *sc, uint8_t xfer_index)
static uint8_t umass_no_transform(struct umass_softc *, uint8_t *, uint8_t)
#define UMASS_FLOPPY_TRANSFER_SPEED
#define UMASS_T_BBB_RESET2
static void umass_cam_poll(struct cam_sim *)
static struct usb_config umass_cbi_config[UMASS_T_CBI_MAX]
static struct umass_probe_proto umass_probe_proto(device_t dev, struct usb_attach_arg *uaa)
static usb_callback_t umass_tr_error
static uint8_t umass_ufi_transform(struct umass_softc *, uint8_t *, uint8_t)
#define READ_CAPACITY_OFFBY1
#define UFI_COMMAND_LENGTH
static void umass_cam_detach_sim(struct umass_softc *)
static uint16_t umass_get_proto(struct usb_interface *iface)
static uint8_t umass_std_transform(struct umass_softc *, union ccb *, uint8_t *, uint8_t)
#define UMASS_T_BBB_STATUS
static void umass_command_start(struct umass_softc *, uint8_t, void *, uint32_t, uint32_t, umass_callback_t *, union ccb *)
#define UMASS_T_BBB_DATA_WR_CS
static usb_callback_t umass_t_bbb_data_read_callback
static const uint8_t fake_inq_data[SHORT_INQUIRY_LENGTH]
static usb_callback_t umass_t_cbi_reset3_callback
#define UMASS_T_BBB_DATA_RD_CS
static struct usb_config umass_bbb_config[UMASS_T_BBB_MAX]
static usb_callback_t umass_t_cbi_reset1_callback
#define UMASS_T_CBI_RESET3
#define UMASS_SUPER_TRANSFER_SPEED
static uint8_t umass_scsi_transform(struct umass_softc *, uint8_t *, uint8_t)
static usb_callback_t umass_t_cbi_reset4_callback
#define ATAPI_COMMAND_LENGTH
#define UMASS_T_BBB_COMMAND
static device_detach_t umass_detach
#define UMASS_HIGH_TRANSFER_SPEED
#define UMASS_PROTO_ATAPI
static usb_callback_t umass_t_bbb_reset1_callback
DRIVER_MODULE(umass, uhub, umass_driver, umass_devclass, NULL, 0)
#define UMASS_T_CBI_RESET2
#define STATUS_CMD_UNKNOWN
#define UMASS_CBI_DIAGNOSTIC_CMDLEN
static usb_callback_t umass_t_bbb_status_callback
#define CSWSIGNATURE_OLYMPUS_C1
#define UMASS_T_BBB_DATA_WRITE
static device_method_t umass_methods[]
void() umass_callback_t(struct umass_softc *sc, union ccb *ccb, uint32_t residue, uint8_t status)
#define UMASS_PROTO_COMMAND
#define UMASS_T_CBI_DATA_READ
static usb_callback_t umass_t_cbi_data_rd_cs_callback
static int umass_cam_attach_sim(struct umass_softc *)
static usb_callback_t umass_t_bbb_data_wr_cs_callback
#define UMASS_T_CBI_DATA_WR_CS
#define IDB_VALUE_PERSISTENT
#define UMASS_T_CBI_COMMAND
static void umass_cancel_ccb(struct umass_softc *)
static void umass_cam_cb(struct umass_softc *, union ccb *, uint32_t, uint8_t)
#define STATUS_WIRE_FAILED
#define UMASS_T_BBB_RESET3
#define UMASS_SCSIID_HOST
static usb_callback_t umass_t_bbb_reset3_callback
static device_attach_t umass_attach
#define UT_READ_CLASS_INTERFACE
#define UISUBCLASS_SFF8070I
#define UT_READ_VENDOR_DEVICE
#define UISUBCLASS_SFF8020I
#define UT_WRITE_CLASS_INTERFACE
#define UIPROTO_MASS_BBB_OLD
#define UIPROTO_MASS_CBI_I
void usbd_copy_in(struct usb_page_cache *cache, usb_frlength_t offset, const void *ptr, usb_frlength_t len)
void usbd_copy_out(struct usb_page_cache *cache, usb_frlength_t offset, void *ptr, usb_frlength_t len)
usb_error_t usbd_set_alt_interface_index(struct usb_device *udev, uint8_t iface_index, uint8_t alt_index)
struct usb_interface_descriptor * usbd_get_interface_descriptor(struct usb_interface *iface)
const char * usb_get_serial(struct usb_device *udev)
enum usb_dev_speed usbd_get_speed(struct usb_device *udev)
const char * usbd_errstr(usb_error_t err)
static uint8_t scsi_test_unit_ready[]
@ UQ_MSC_FORCE_PROTO_ATAPI
@ UQ_MSC_NO_TEST_UNIT_READY
@ UQ_MSC_FORCE_PROTO_SCSI
@ UQ_MSC_NO_PREVENT_ALLOW
@ UQ_MSC_FORCE_WIRE_CBI_I
uint8_t usb_test_quirk(const struct usb_attach_arg *uaa, uint16_t quirk)
void usbd_xfer_set_timeout(struct usb_xfer *xfer, int t)
void usbd_transfer_submit(struct usb_xfer *xfer)
void usbd_xfer_set_frames(struct usb_xfer *xfer, usb_frcount_t n)
void usbd_transfer_unsetup(struct usb_xfer **pxfer, uint16_t n_setup)
void usbd_xfer_set_frame_data(struct usb_xfer *xfer, usb_frcount_t frindex, void *ptr, usb_frlength_t len)
void usbd_xfer_set_frame_len(struct usb_xfer *xfer, usb_frcount_t frindex, usb_frlength_t len)
uint8_t usbd_clear_stall_callback(struct usb_xfer *xfer1, struct usb_xfer *xfer2)
struct usb_page_cache * usbd_xfer_get_frame(struct usb_xfer *xfer, usb_frcount_t frindex)
usb_error_t usbd_transfer_setup(struct usb_device *udev, const uint8_t *ifaces, struct usb_xfer **ppxfer, const struct usb_config *setup_start, uint16_t n_setup, void *priv_sc, struct mtx *xfer_mtx)
void usbd_transfer_start(struct usb_xfer *xfer)
void usbd_transfer_poll(struct usb_xfer **ppxfer, uint16_t max)
void * usbd_xfer_softc(struct usb_xfer *xfer)
void usbd_xfer_set_interval(struct usb_xfer *xfer, int i)
void usbd_transfer_stop(struct usb_xfer *xfer)
void usbd_xfer_status(struct usb_xfer *xfer, int *actlen, int *sumlen, int *aframes, int *nframes)
usb_frlength_t usbd_xfer_max_len(struct usb_xfer *xfer)
void device_set_usb_desc(device_t dev)
#define USB_MTX_ASSERT(_m, _t)
#define USB_IFACE_CLASS(ic)
#define USB_ST_TRANSFERRED
void() usb_callback_t(struct usb_xfer *, usb_error_t)
#define STRUCT_USB_HOST_ID
#define USB_GET_STATE(xfer)
#define usbd_do_request(u, m, r, d)