41#ifdef USB_GLOBAL_INCLUDE_FILE
42#include USB_GLOBAL_INCLUDE_FILE
44#include <sys/stdint.h>
45#include <sys/stddef.h>
50#include <sys/kernel.h>
52#include <sys/module.h>
55#include <sys/condvar.h>
56#include <sys/sysctl.h>
58#include <sys/unistd.h>
59#include <sys/callout.h>
60#include <sys/malloc.h>
68#define USB_DEBUG_VAR ustorage_fs_debug
73static int ustorage_fs_debug = 0;
75SYSCTL_NODE(_hw_usb, OID_AUTO, ustorage_fs, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
78 &ustorage_fs_debug, 0,
"ustorage_fs debug level");
83#ifndef USTORAGE_FS_BULK_SIZE
84#define USTORAGE_FS_BULK_SIZE (1U << 17)
87#ifndef USTORAGE_FS_MAX_LUN
88#define USTORAGE_FS_MAX_LUN 8
91#ifndef USTORAGE_QDATA_MAX
92#define USTORAGE_QDATA_MAX 40
99#ifndef USTORAGE_FS_ID_STRING
100#define USTORAGE_FS_ID_STRING \
110#ifndef USTORAGE_FS_RAM_SECT
111#define USTORAGE_FS_RAM_SECT (1UL << 13)
118#define USTORAGE_FS_T_BBB_COMMAND 0
119#define USTORAGE_FS_T_BBB_DATA_DUMP 1
120#define USTORAGE_FS_T_BBB_DATA_READ 2
121#define USTORAGE_FS_T_BBB_DATA_WRITE 3
122#define USTORAGE_FS_T_BBB_STATUS 4
123#define USTORAGE_FS_T_BBB_MAX 5
133#define UR_BBB_RESET 0xff
134#define UR_BBB_GET_MAX_LUN 0xfe
139#define CBWSIGNATURE 0x43425355
141 uDWord dCBWDataTransferLength;
143#define CBWFLAGS_OUT 0x00
144#define CBWFLAGS_IN 0x80
147#define CBWCDBLENGTH 16
151#define USTORAGE_FS_BBB_CBW_SIZE 31
156#define CSWSIGNATURE 0x53425355
160#define CSWSTATUS_GOOD 0x0
161#define CSWSTATUS_FAILED 0x1
162#define CSWSTATUS_PHASE 0x2
165#define USTORAGE_FS_BBB_CSW_SIZE 13
264 .name =
"ustorage_fs",
280 .bufsize =
sizeof(ustorage_fs_bbb_cbw_t),
290 .flags = {.proxy_buffer = 1,.short_xfer_ok = 1,},
300 .flags = {.proxy_buffer = 1,.short_xfer_ok = 1},
310 .flags = {.proxy_buffer = 1,.short_xfer_ok = 1,.ext_buffer = 1},
319 .bufsize =
sizeof(ustorage_fs_bbb_csw_t),
347 return (BUS_PROBE_GENERIC);
367 unit = device_get_unit(
dev);
389 mtx_init(&sc->
sc_mtx,
"USTORAGE_FS lock",
390 NULL, (MTX_DEF | MTX_RECURSE));
396 device_printf(
dev,
"failed to get "
397 "interface number\n");
406 device_printf(
dev,
"could not setup required "
448 device_printf(
dev,
"suspending\n");
455 device_printf(
dev,
"resuming\n");
483 const void *preq,
void **
pptr, uint16_t *
plen,
488 uint8_t is_complete = *
pstate;
531 DPRINTF(
"invalid signature 0x%08x\n", tag);
540 sc->
sc_csw->bCSWStatus = 0;
567 DPRINTF(
"invalid command length %d bytes\n",
582 DPRINTF(
"data direction mismatch\n");
607 sizeof(ustorage_fs_bbb_cbw_t));
624 if (sc->
sc_csw->bCSWStatus == 0) {
833 sizeof(ustorage_fs_bbb_csw_t));
851#define SC_FORMAT_UNIT 0x04
852#define SC_INQUIRY 0x12
853#define SC_MODE_SELECT_6 0x15
854#define SC_MODE_SELECT_10 0x55
855#define SC_MODE_SENSE_6 0x1a
856#define SC_MODE_SENSE_10 0x5a
857#define SC_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e
858#define SC_READ_6 0x08
859#define SC_READ_10 0x28
860#define SC_READ_12 0xa8
861#define SC_READ_CAPACITY 0x25
862#define SC_READ_FORMAT_CAPACITIES 0x23
863#define SC_RELEASE 0x17
864#define SC_REQUEST_SENSE 0x03
865#define SC_RESERVE 0x16
866#define SC_SEND_DIAGNOSTIC 0x1d
867#define SC_START_STOP_UNIT 0x1b
868#define SC_SYNCHRONIZE_CACHE 0x35
869#define SC_TEST_UNIT_READY 0x00
870#define SC_VERIFY 0x2f
871#define SC_WRITE_6 0x0a
872#define SC_WRITE_10 0x2a
873#define SC_WRITE_12 0xaa
877#define SS_COMMUNICATION_FAILURE 0x040800
878#define SS_INVALID_COMMAND 0x052000
879#define SS_INVALID_FIELD_IN_CDB 0x052400
880#define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x052100
881#define SS_LOGICAL_UNIT_NOT_SUPPORTED 0x052500
882#define SS_MEDIUM_NOT_PRESENT 0x023a00
883#define SS_MEDIUM_REMOVAL_PREVENTED 0x055302
884#define SS_NOT_READY_TO_READY_TRANSITION 0x062800
885#define SS_RESET_OCCURRED 0x062900
886#define SS_SAVING_PARAMETERS_NOT_SUPPORTED 0x053900
887#define SS_UNRECOVERED_READ_ERROR 0x031100
888#define SS_WRITE_ERROR 0x030c02
889#define SS_WRITE_PROTECTED 0x072700
891#define SK(x) ((uint8_t) ((x) >> 16))
892#define ASC(x) ((uint8_t) ((x) >> 8))
893#define ASCQ(x) ((uint8_t) (x))
900 return ((uint16_t)buf[0] << 8) | ((uint16_t)buf[1]);
906 return ((uint32_t)buf[0] << 24) | ((uint32_t)buf[1] << 16) |
907 ((uint32_t)buf[2] << 8) | ((uint32_t)buf[3]);
939 uint64_t file_offset;
940 uint64_t amount_left;
951 if ((sc->
sc_cbw->CBWCDB[1] & ~0x10) != 0) {
1016#if (USTORAGE_QDATA_MAX < 36)
1017#error "(USTORAGE_QDATA_MAX < 36)"
1075 buf[0] = valid | 0x70;
1085#if (USTORAGE_QDATA_MAX < 18)
1086#error "(USTORAGE_QDATA_MAX < 18)"
1104 uint8_t pmi = sc->
sc_cbw->CBWCDB[8];
1107 if ((pmi > 1) || ((pmi == 0) && (lba != 0))) {
1116#if (USTORAGE_QDATA_MAX < 8)
1117#error "(USTORAGE_QDATA_MAX < 8)"
1137 uint8_t mscmnd = sc->
sc_cbw->CBWCDB[0];
1140 uint8_t changeable_values;
1145 if ((sc->
sc_cbw->CBWCDB[1] & ~0x08) != 0) {
1150 pc = sc->
sc_cbw->CBWCDB[2] >> 6;
1151 page_code = sc->
sc_cbw->CBWCDB[2] & 0x3f;
1156 changeable_values = (pc == 1);
1157 all_pages = (page_code == 0x3f);
1167 buf[2] = (currlun->
read_only ? 0x80 : 0x00);
1173 buf[3] = (currlun->
read_only ? 0x80 : 0x00);
1185 if ((page_code == 0x08) || all_pages) {
1190 memset(buf + 2, 0, 10);
1193 if (!changeable_values) {
1223#if (USTORAGE_QDATA_MAX < 24)
1224#error "(USTORAGE_QDATA_MAX < 24)"
1248 immed = sc->
sc_cbw->CBWCDB[1] & 0x01;
1249 loej = sc->
sc_cbw->CBWCDB[4] & 0x02;
1252 if (immed || loej ||
start) {
1275 prevent = sc->
sc_cbw->CBWCDB[4] & 0x01;
1276 if ((sc->
sc_cbw->CBWCDB[4] & ~0x01) != 0) {
1301 buf[0] = buf[1] = buf[2] = 0;
1313#if (USTORAGE_QDATA_MAX < 12)
1314#error "(USTORAGE_QDATA_MAX < 12)"
1372 uint64_t file_offset;
1381 lba = (((uint32_t)sc->
sc_cbw->CBWCDB[1]) << 16) |
1391 if ((sc->
sc_cbw->CBWCDB[1] & ~0x18) != 0) {
1424 uint64_t file_offset;
1439 lba = (((uint32_t)sc->
sc_cbw->CBWCDB[1]) << 16) |
1450 if ((sc->
sc_cbw->CBWCDB[1] & ~0x18) != 0) {
1454 if (sc->
sc_cbw->CBWCDB[1] & 0x08) {
1526 uint16_t mask, uint8_t needs_medium)
1529 uint8_t lun = (sc->
sc_cbw->CBWCDB[1] >> 5);
1540 sc->
sc_cbw->CBWCDB[1] &= 0x1f;
1583 for (i = 0; i != min_cmd_size; i++) {
1584 if (sc->
sc_cbw->CBWCDB[i] && !(mask & (1UL << i))) {
1596 if (currlun && (!currlun->
memory_image) && needs_medium) {
1616 const uint32_t mask9 = (0xFFFFFFFFUL >> 9) << 9;
1621 DPRINTF(
"cmd_data[0]=0x%02x, data_rem=0x%08x\n",
1624 switch (sc->
sc_cbw->CBWCDB[0]) {
1647 (1UL << 1) | (1UL << 4) | 1, 0);
1663 (1UL << 1) | (3UL << 7) | 1, 0);
1678 (1UL << 1) | (1UL << 2) | (1UL << 4) | 1, 0);
1694 (1UL << 1) | (1UL << 2) | (3UL << 7) | 1, 0);
1717 i = sc->
sc_cbw->CBWCDB[4];
1719 temp = ((i == 0) ? 256UL : i);
1725 (7UL << 1) | (1UL << 4) | 1, 1);
1741 (1UL << 1) | (0xfUL << 2) | (3UL << 7) | 1, 1);
1752 if (temp >= (1UL << (32 - 9))) {
1763 (1UL << 1) | (0xfUL << 2) | (0xfUL << 6) | 1, 1);
1774 (0xfUL << 2) | (1UL << 8) | 1, 1);
1819 (1UL << 1) | (1UL << 4) | 1, 0);
1833 (0xfUL << 2) | (3UL << 7) | 1, 1);
1860 (1UL << 1) | (0xfUL << 2) | (3UL << 7) | 1, 1);
1869 i = sc->
sc_cbw->CBWCDB[4];
1871 temp = ((i == 0) ? 256UL : i);
1877 (7UL << 1) | (1UL << 4) | 1, 1);
1893 (1UL << 1) | (0xfUL << 2) | (3UL << 7) | 1, 1);
1904 if (temp > (mask9 >> 9)) {
1915 (1UL << 1) | (0xfUL << 2) | (0xfUL << 6) | 1, 1);
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+")
enum usb_hc_mode usb_mode
struct usbd_lookup_info info
struct usb_interface * iface
struct usb_device * device
struct usb_xfer_flags flags
enum usb_hc_mode usb_mode
usb_callback_t * callback
uint32_t unit_attention_data
uint8_t prevent_medium_removal
ustorage_fs_bbb_cbw_t * sc_cbw
struct ustorage_fs_softc::@72 sc_transfer
struct usb_device * sc_udev
uint8_t sc_last_xfer_index
struct ustorage_fs_lun sc_lun[USTORAGE_FS_MAX_LUN]
ustorage_fs_bbb_csw_t * sc_csw
struct ustorage_fs_lun * currlun
uint8_t sc_qdata[USTORAGE_QDATA_MAX]
struct usb_xfer * sc_xfer[USTORAGE_FS_T_BBB_MAX]
#define UT_READ_CLASS_INTERFACE
#define USB_POWER_MODE_SAVE
#define UT_WRITE_CLASS_INTERFACE
struct usb_interface_descriptor * usbd_get_interface_descriptor(struct usb_interface *iface)
const char * usbd_errstr(usb_error_t err)
static usb_error_t usb_handle_request(struct usb_xfer *)
void usbd_set_power_mode(struct usb_device *udev, uint8_t power_mode)
void usbd_xfer_set_flag(struct usb_xfer *xfer, int flag)
void usbd_transfer_submit(struct usb_xfer *xfer)
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)
void * usbd_xfer_get_frame_buffer(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)
int usbd_xfer_is_stalled(struct usb_xfer *xfer)
void usbd_transfer_drain(struct usb_xfer *xfer)
void usbd_xfer_clr_flag(struct usb_xfer *xfer, int flag)
void * usbd_xfer_softc(struct usb_xfer *xfer)
void usbd_xfer_set_stall(struct usb_xfer *xfer)
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_FORCE_SHORT_XFER
#define USB_ST_TRANSFERRED
void() usb_callback_t(struct usb_xfer *, usb_error_t)
#define USB_GET_STATE(xfer)
static device_method_t ustorage_fs_methods[]
#define USTORAGE_FS_T_BBB_STATUS
static device_attach_t ustorage_fs_attach
static driver_t ustorage_fs_driver
#define SS_INVALID_COMMAND
#define SC_TEST_UNIT_READY
static uint8_t ustorage_fs_read_capacity(struct ustorage_fs_softc *sc)
static uint8_t ustorage_fs_start_stop(struct ustorage_fs_softc *sc)
static devclass_t ustorage_fs_devclass
static struct usb_config ustorage_fs_bbb_config[USTORAGE_FS_T_BBB_MAX]
#define USTORAGE_FS_T_BBB_DATA_DUMP
#define USTORAGE_FS_MAX_LUN
static void ustorage_fs_transfer_start(struct ustorage_fs_softc *sc, uint8_t xfer_index)
static uint8_t ustorage_fs_write(struct ustorage_fs_softc *sc)
static void put_be32(uint8_t *buf, uint32_t val)
static usb_handle_request_t ustorage_fs_handle_request
static uint8_t ustorage_fs_do_cmd(struct ustorage_fs_softc *sc)
#define SS_SAVING_PARAMETERS_NOT_SUPPORTED
static uint8_t ustorage_fs_request_sense(struct ustorage_fs_softc *sc)
#define USTORAGE_FS_T_BBB_DATA_WRITE
static uint8_t ustorage_fs_inquiry(struct ustorage_fs_softc *sc)
static uint8_t ustorage_fs_read_format_capacities(struct ustorage_fs_softc *sc)
#define USTORAGE_FS_ID_STRING
MODULE_VERSION(ustorage_fs, 0)
MODULE_DEPEND(ustorage_fs, usb, 1, 1, 1)
static void ustorage_fs_transfer_stop(struct ustorage_fs_softc *sc)
static void put_be16(uint8_t *buf, uint16_t val)
static uint8_t ustorage_fs_read(struct ustorage_fs_softc *sc)
static uint8_t ustorage_fs_synchronize_cache(struct ustorage_fs_softc *sc)
#define USTORAGE_QDATA_MAX
#define SC_READ_FORMAT_CAPACITIES
#define SC_PREVENT_ALLOW_MEDIUM_REMOVAL
#define UR_BBB_GET_MAX_LUN
static uint8_t ustorage_fs_prevent_allow(struct ustorage_fs_softc *sc)
static usb_callback_t ustorage_fs_t_bbb_command_callback
static uint8_t ustorage_fs_check_cmd(struct ustorage_fs_softc *sc, uint8_t cmd_size, uint16_t mask, uint8_t needs_medium)
DRIVER_MODULE(ustorage_fs, uhub, ustorage_fs_driver, ustorage_fs_devclass, NULL, 0)
#define SS_WRITE_PROTECTED
#define USTORAGE_FS_RAM_SECT
static device_probe_t ustorage_fs_probe
static uint16_t get_be16(uint8_t *buf)
#define SC_MODE_SELECT_10
#define USTORAGE_FS_T_BBB_MAX
#define USTORAGE_FS_BULK_SIZE
#define SS_LOGICAL_UNIT_NOT_SUPPORTED
static device_detach_t ustorage_fs_detach
static device_suspend_t ustorage_fs_suspend
static usb_callback_t ustorage_fs_t_bbb_data_write_callback
#define USTORAGE_FS_T_BBB_COMMAND
static uint8_t * ustorage_fs_ramdisk
#define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE
#define SC_START_STOP_UNIT
#define USTORAGE_FS_T_BBB_DATA_READ
static uint8_t ustorage_fs_mode_sense(struct ustorage_fs_softc *sc)
static uint8_t ustorage_fs_min_len(struct ustorage_fs_softc *sc, uint32_t len, uint32_t mask)
#define SS_INVALID_FIELD_IN_CDB
static uint32_t get_be32(uint8_t *buf)
#define SS_MEDIUM_NOT_PRESENT
static uint8_t ustorage_fs_mode_select(struct ustorage_fs_softc *sc)
static usb_callback_t ustorage_fs_t_bbb_data_dump_callback
static uint8_t ustorage_fs_verify(struct ustorage_fs_softc *sc)
static usb_callback_t ustorage_fs_t_bbb_data_read_callback
#define SC_SYNCHRONIZE_CACHE
static usb_callback_t ustorage_fs_t_bbb_status_callback
static device_resume_t ustorage_fs_resume
#define SC_SEND_DIAGNOSTIC