27#include "usb_private.h"
39#define CBW_SIGNATURE 0x43425355
40#define CBW_STATUS_SUCCESS 0
41#define CBW_STATUS_FAILED 1
42#define CBW_STATUS_PHASE_ERROR 2
45#define CSW_SIGNATURE 0x53425355
46#define CSW_STATUS_SUCCESS 0
47#define CSW_STATUS_FAILED 1
48#define CSW_STATUS_PHASE_ERROR 2
51#define SCSI_TEST_UNIT_READY 0x00
52#define SCSI_REQUEST_SENSE 0x03
53#define SCSI_FORMAT_UNIT 0x04
54#define SCSI_READ_6 0x08
55#define SCSI_WRITE_6 0x0A
56#define SCSI_INQUIRY 0x12
57#define SCSI_MODE_SENSE_6 0x1A
58#define SCSI_SEND_DIAGNOSTIC 0x1D
59#define SCSI_READ_CAPACITY 0x25
60#define SCSI_READ_10 0x28
66#define SCSI_REPORT_LUNS 0xA0
67#define SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1E
68#define SCSI_MODE_SELECT_6 0x15
69#define SCSI_MODE_SELECT_10 0x55
70#define SCSI_MODE_SENSE_10 0x5A
71#define SCSI_READ_12 0xA8
72#define SCSI_READ_FORMAT_CAPACITIES 0x23
73#define SCSI_READ_TOC_PMA_ATIP 0x43
74#define SCSI_START_STOP_UNIT 0x1B
75#define SCSI_SYNCHRONIZE_CACHE 0x35
76#define SCSI_VERIFY 0x2F
77#define SCSI_WRITE_10 0x2A
78#define SCSI_WRITE_12 0xAA
132} __attribute__((packed));
139} __attribute__((packed));
209 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
211 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
212 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
214 0x20, 0x20, 0x20, 0x20
268 trans->
lba_start = (buf[2] << 8) | buf[3];
292 trans->
lba_start = ((0x1f & buf[1]) << 16)
293 | (buf[2] << 8) | buf[3];
312 trans->
lba_start = (buf[2] << 24) | (buf[3] << 16) |
313 (buf[4] << 8) | buf[5];
330 trans->
lba_start = (buf[2] << 24) | (buf[3] << 16)
331 | (buf[4] << 8) | buf[5];
370 memset(trans->
msd_buf, 0, 512);
409 uint8_t allocation_length;
413 allocation_length = buf[4];
415 if (0x1C == page_code) {
424 }
else if (0x01 == page_code) {
425 }
else if (0x3F == page_code) {
548 int len, max_len, left;
555 left =
sizeof(
struct usb_msc_cbw) - trans->cbw_cnt;
603 left =
sizeof(
struct usb_msc_csw) - trans->csw_sent;
606 p = &trans->csw.buf[trans->csw_sent];
609 trans->csw_sent += len;
657 left =
sizeof(
struct usb_msc_csw) - trans->csw_sent;
660 p = &trans->csw.buf[trans->csw_sent];
663 trans->csw_sent += len;
673 int len, max_len, left;
712 left =
sizeof(
struct usb_msc_csw) - trans->csw_sent;
715 p = &trans->csw.buf[trans->csw_sent];
717 trans->csw_sent += len;
718 }
else if (
sizeof(
struct usb_msc_csw) == trans->csw_sent) {
720 trans->lba_start = 0xffffffff;
721 trans->block_count = 0;
722 trans->current_block = 0;
724 trans->bytes_to_read = 0;
725 trans->bytes_to_write = 0;
726 trans->byte_count = 0;
728 trans->csw_valid =
false;
802 uint8_t ep_in, uint8_t ep_in_size,
803 uint8_t ep_out, uint8_t ep_out_size,
804 const char *vendor_id,
805 const char *product_id,
806 const char *product_revision_level,
807 const uint32_t block_count,
808 int (*read_block)(uint32_t lba,
810 int (*write_block)(uint32_t lba,
811 const uint8_t *copy_from))
struct _usbd_device usbd_device
int usbd_register_control_callback(usbd_device *usbd_dev, uint8_t type, uint8_t type_mask, usbd_control_callback callback)
Registers a control callback.
uint16_t usbd_ep_write_packet(usbd_device *usbd_dev, uint8_t addr, const void *buf, uint16_t len)
Write a packet.
void usbd_ep_setup(usbd_device *usbd_dev, uint8_t addr, uint8_t type, uint16_t max_size, usbd_endpoint_callback callback)
Setup an endpoint.
uint16_t usbd_ep_read_packet(usbd_device *usbd_dev, uint8_t addr, void *buf, uint16_t len)
Read a packet.
int usbd_register_set_config_callback(usbd_device *usbd_dev, usbd_set_config_callback callback)
Registers a "Set Config" callback.
usbd_request_return_codes
void(* usbd_control_complete_callback)(usbd_device *usbd_dev, struct usb_setup_data *req)
#define USB_MSC_REQ_BULK_ONLY_RESET
#define USB_MSC_REQ_GET_MAX_LUN
usbd_mass_storage * usb_msc_init(usbd_device *usbd_dev, uint8_t ep_in, uint8_t ep_in_size, uint8_t ep_out, uint8_t ep_out_size, const char *vendor_id, const char *product_id, const char *product_revision_level, const uint32_t block_count, int(*read_block)(uint32_t lba, uint8_t *copy_to), int(*write_block)(uint32_t lba, const uint8_t *copy_from))
Initializes the USB Mass Storage subsystem.
#define USB_ENDPOINT_ATTR_BULK
#define USB_REQ_TYPE_RECIPIENT
#define USB_REQ_TYPE_TYPE
#define USB_REQ_TYPE_INTERFACE
#define USB_REQ_TYPE_CLASS
struct usb_msc_trans trans
struct sbc_sense_info sense
int(* write_block)(uint32_t lba, const uint8_t *copy_from)
const char * product_revision_level
int(* read_block)(uint32_t lba, uint8_t *copy_to)
uint32_t dCBWDataTransferLength
static uint8_t * get_cbw_buf(struct usb_msc_trans *trans)
#define CSW_STATUS_SUCCESS
static void scsi_format_unit(usbd_mass_storage *ms, struct usb_msc_trans *trans, enum trans_event event)
static void msc_set_config(usbd_device *usbd_dev, uint16_t wValue)
Setup the endpoints to be bulk & register the callbacks.
static void set_sbc_status(usbd_mass_storage *ms, enum sbc_sense_key key, enum sbc_asc asc, enum sbc_ascq ascq)
#define SCSI_SEND_DIAGNOSTIC
static void scsi_mode_sense_6(usbd_mass_storage *ms, struct usb_msc_trans *trans, enum trans_event event)
#define SCSI_READ_CAPACITY
static void scsi_read_capacity(usbd_mass_storage *ms, struct usb_msc_trans *trans, enum trans_event event)
static void msc_data_rx_cb(usbd_device *usbd_dev, uint8_t ep)
Handle the USB 'OUT' requests.
static void scsi_request_sense(usbd_mass_storage *ms, struct usb_msc_trans *trans, enum trans_event event)
static void scsi_write_10(usbd_mass_storage *ms, struct usb_msc_trans *trans, enum trans_event event)
static const uint8_t _spc3_inquiry_response[36]
static void scsi_read_6(usbd_mass_storage *ms, struct usb_msc_trans *trans, enum trans_event event)
@ SBC_ASC_NOT_READY_TO_READY_CHANGE
@ SBC_ASC_PERIPHERAL_DEVICE_WRITE_FAULT
@ SBC_ASC_INVALID_COMMAND_OPERATION_CODE
@ SBC_ASC_MEDIUM_NOT_PRESENT
@ SBC_ASC_LBA_OUT_OF_RANGE
@ SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION
@ SBC_ASC_INVALID_FIELD_IN_CDB
@ SBC_ASC_WRITE_PROTECTED
@ SBC_ASC_UNRECOVERED_READ_ERROR
@ SBC_ASC_LOGICAL_UNIT_NOT_READY
static void scsi_inquiry(usbd_mass_storage *ms, struct usb_msc_trans *trans, enum trans_event event)
static void msc_data_tx_cb(usbd_device *usbd_dev, uint8_t ep)
Handle the USB 'IN' requests.
static const uint8_t _spc3_request_sense[18]
static void scsi_read_10(usbd_mass_storage *ms, struct usb_msc_trans *trans, enum trans_event event)
@ SBC_ASCQ_INITIALIZING_COMMAND_REQUIRED
@ SBC_ASCQ_FORMAT_COMMAND_FAILED
@ SBC_ASCQ_OPERATION_IN_PROGRESS
#define SCSI_REQUEST_SENSE
#define CSW_STATUS_FAILED
#define SCSI_MODE_SENSE_6
static void set_sbc_status_good(usbd_mass_storage *ms)
static void scsi_command(usbd_mass_storage *ms, struct usb_msc_trans *trans, enum trans_event event)
#define SCSI_TEST_UNIT_READY
static void scsi_write_6(usbd_mass_storage *ms, struct usb_msc_trans *trans, enum trans_event event)
@ SBC_SENSE_KEY_ABORTED_COMMAND
@ SBC_SENSE_KEY_HARDWARE_ERROR
@ SBC_SENSE_KEY_BLANK_CHECK
@ SBC_SENSE_KEY_MISCOMPARE
@ SBC_SENSE_KEY_UNIT_ATTENTION
@ SBC_SENSE_KEY_RECOVERED_ERROR
@ SBC_SENSE_KEY_VOLUME_OVERFLOW
@ SBC_SENSE_KEY_ILLEGAL_REQUEST
@ SBC_SENSE_KEY_VENDOR_SPECIFIC
@ SBC_SENSE_KEY_MEDIUM_ERROR
@ SBC_SENSE_KEY_DATA_PROTECT
@ SBC_SENSE_KEY_NOT_READY
@ SBC_SENSE_KEY_COPY_ABORTED
static usbd_mass_storage _mass_storage
static enum usbd_request_return_codes msc_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, uint8_t **buf, uint16_t *len, usbd_control_complete_callback *complete)
Handle various control requests related to the msc storage interface.