libopencm3
A free/libre/open-source firmware library for various ARM Cortex-M3 microcontrollers.
usb_msc.c File Reference
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <libopencm3/cm3/common.h>
#include <libopencm3/usb/usbd.h>
#include <libopencm3/usb/msc.h>
#include "usb_private.h"
Include dependency graph for usb_msc.c:

Go to the source code of this file.

Data Structures

struct  usb_msc_cbw
 
struct  usb_msc_csw
 
struct  sbc_sense_info
 
struct  usb_msc_trans
 
struct  _usbd_mass_storage
 

Macros

#define CBW_SIGNATURE   0x43425355
 
#define CBW_STATUS_SUCCESS   0
 
#define CBW_STATUS_FAILED   1
 
#define CBW_STATUS_PHASE_ERROR   2
 
#define CSW_SIGNATURE   0x53425355
 
#define CSW_STATUS_SUCCESS   0
 
#define CSW_STATUS_FAILED   1
 
#define CSW_STATUS_PHASE_ERROR   2
 
#define SCSI_TEST_UNIT_READY   0x00
 
#define SCSI_REQUEST_SENSE   0x03
 
#define SCSI_FORMAT_UNIT   0x04
 
#define SCSI_READ_6   0x08
 
#define SCSI_WRITE_6   0x0A
 
#define SCSI_INQUIRY   0x12
 
#define SCSI_MODE_SENSE_6   0x1A
 
#define SCSI_SEND_DIAGNOSTIC   0x1D
 
#define SCSI_READ_CAPACITY   0x25
 
#define SCSI_READ_10   0x28
 
#define SCSI_REPORT_LUNS   0xA0
 
#define SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL   0x1E
 
#define SCSI_MODE_SELECT_6   0x15
 
#define SCSI_MODE_SELECT_10   0x55
 
#define SCSI_MODE_SENSE_10   0x5A
 
#define SCSI_READ_12   0xA8
 
#define SCSI_READ_FORMAT_CAPACITIES   0x23
 
#define SCSI_READ_TOC_PMA_ATIP   0x43
 
#define SCSI_START_STOP_UNIT   0x1B
 
#define SCSI_SYNCHRONIZE_CACHE   0x35
 
#define SCSI_VERIFY   0x2F
 
#define SCSI_WRITE_10   0x2A
 
#define SCSI_WRITE_12   0xAA
 

Enumerations

enum  sbc_sense_key {
  SBC_SENSE_KEY_NO_SENSE = 0x00 , SBC_SENSE_KEY_RECOVERED_ERROR = 0x01 , SBC_SENSE_KEY_NOT_READY = 0x02 , SBC_SENSE_KEY_MEDIUM_ERROR = 0x03 ,
  SBC_SENSE_KEY_HARDWARE_ERROR = 0x04 , SBC_SENSE_KEY_ILLEGAL_REQUEST = 0x05 , SBC_SENSE_KEY_UNIT_ATTENTION = 0x06 , SBC_SENSE_KEY_DATA_PROTECT = 0x07 ,
  SBC_SENSE_KEY_BLANK_CHECK = 0x08 , SBC_SENSE_KEY_VENDOR_SPECIFIC = 0x09 , SBC_SENSE_KEY_COPY_ABORTED = 0x0A , SBC_SENSE_KEY_ABORTED_COMMAND = 0x0B ,
  SBC_SENSE_KEY_VOLUME_OVERFLOW = 0x0D , SBC_SENSE_KEY_MISCOMPARE = 0x0E
}
 
enum  sbc_asc {
  SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION = 0x00 , SBC_ASC_PERIPHERAL_DEVICE_WRITE_FAULT = 0x03 , SBC_ASC_LOGICAL_UNIT_NOT_READY = 0x04 , SBC_ASC_UNRECOVERED_READ_ERROR = 0x11 ,
  SBC_ASC_INVALID_COMMAND_OPERATION_CODE = 0x20 , SBC_ASC_LBA_OUT_OF_RANGE = 0x21 , SBC_ASC_INVALID_FIELD_IN_CDB = 0x24 , SBC_ASC_WRITE_PROTECTED = 0x27 ,
  SBC_ASC_NOT_READY_TO_READY_CHANGE = 0x28 , SBC_ASC_FORMAT_ERROR = 0x31 , SBC_ASC_MEDIUM_NOT_PRESENT = 0x3A
}
 
enum  sbc_ascq { SBC_ASCQ_NA = 0x00 , SBC_ASCQ_FORMAT_COMMAND_FAILED = 0x01 , SBC_ASCQ_INITIALIZING_COMMAND_REQUIRED = 0x02 , SBC_ASCQ_OPERATION_IN_PROGRESS = 0x07 }
 
enum  trans_event { EVENT_CBW_VALID , EVENT_NEED_STATUS }
 

Functions

static void set_sbc_status (usbd_mass_storage *ms, enum sbc_sense_key key, enum sbc_asc asc, enum sbc_ascq ascq)
 
static void set_sbc_status_good (usbd_mass_storage *ms)
 
static uint8_t * get_cbw_buf (struct usb_msc_trans *trans)
 
static void scsi_read_6 (usbd_mass_storage *ms, struct usb_msc_trans *trans, enum trans_event event)
 
static void scsi_write_6 (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 void scsi_read_10 (usbd_mass_storage *ms, struct usb_msc_trans *trans, enum trans_event event)
 
static void scsi_read_capacity (usbd_mass_storage *ms, struct usb_msc_trans *trans, enum trans_event event)
 
static void scsi_format_unit (usbd_mass_storage *ms, struct usb_msc_trans *trans, enum trans_event event)
 
static void scsi_request_sense (usbd_mass_storage *ms, struct usb_msc_trans *trans, enum trans_event event)
 
static void scsi_mode_sense_6 (usbd_mass_storage *ms, struct usb_msc_trans *trans, enum trans_event event)
 
static void scsi_inquiry (usbd_mass_storage *ms, struct usb_msc_trans *trans, enum trans_event event)
 
static void scsi_command (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. More...
 
static void msc_data_tx_cb (usbd_device *usbd_dev, uint8_t ep)
 Handle the USB 'IN' requests. More...
 
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. More...
 
static void msc_set_config (usbd_device *usbd_dev, uint16_t wValue)
 Setup the endpoints to be bulk & register the callbacks. More...
 
usbd_mass_storageusb_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. More...
 

Variables

static usbd_mass_storage _mass_storage
 
static const uint8_t _spc3_inquiry_response [36]
 
static const uint8_t _spc3_request_sense [18]
 

Macro Definition Documentation

◆ CBW_SIGNATURE

#define CBW_SIGNATURE   0x43425355

Definition at line 39 of file usb_msc.c.

◆ CBW_STATUS_FAILED

#define CBW_STATUS_FAILED   1

Definition at line 41 of file usb_msc.c.

◆ CBW_STATUS_PHASE_ERROR

#define CBW_STATUS_PHASE_ERROR   2

Definition at line 42 of file usb_msc.c.

◆ CBW_STATUS_SUCCESS

#define CBW_STATUS_SUCCESS   0

Definition at line 40 of file usb_msc.c.

◆ CSW_SIGNATURE

#define CSW_SIGNATURE   0x53425355

Definition at line 45 of file usb_msc.c.

◆ CSW_STATUS_FAILED

#define CSW_STATUS_FAILED   1

Definition at line 47 of file usb_msc.c.

◆ CSW_STATUS_PHASE_ERROR

#define CSW_STATUS_PHASE_ERROR   2

Definition at line 48 of file usb_msc.c.

◆ CSW_STATUS_SUCCESS

#define CSW_STATUS_SUCCESS   0

Definition at line 46 of file usb_msc.c.

◆ SCSI_FORMAT_UNIT

#define SCSI_FORMAT_UNIT   0x04

Definition at line 53 of file usb_msc.c.

◆ SCSI_INQUIRY

#define SCSI_INQUIRY   0x12

Definition at line 56 of file usb_msc.c.

◆ SCSI_MODE_SELECT_10

#define SCSI_MODE_SELECT_10   0x55

Definition at line 69 of file usb_msc.c.

◆ SCSI_MODE_SELECT_6

#define SCSI_MODE_SELECT_6   0x15

Definition at line 68 of file usb_msc.c.

◆ SCSI_MODE_SENSE_10

#define SCSI_MODE_SENSE_10   0x5A

Definition at line 70 of file usb_msc.c.

◆ SCSI_MODE_SENSE_6

#define SCSI_MODE_SENSE_6   0x1A

Definition at line 57 of file usb_msc.c.

◆ SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL

#define SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL   0x1E

Definition at line 67 of file usb_msc.c.

◆ SCSI_READ_10

#define SCSI_READ_10   0x28

Definition at line 60 of file usb_msc.c.

◆ SCSI_READ_12

#define SCSI_READ_12   0xA8

Definition at line 71 of file usb_msc.c.

◆ SCSI_READ_6

#define SCSI_READ_6   0x08

Definition at line 54 of file usb_msc.c.

◆ SCSI_READ_CAPACITY

#define SCSI_READ_CAPACITY   0x25

Definition at line 59 of file usb_msc.c.

◆ SCSI_READ_FORMAT_CAPACITIES

#define SCSI_READ_FORMAT_CAPACITIES   0x23

Definition at line 72 of file usb_msc.c.

◆ SCSI_READ_TOC_PMA_ATIP

#define SCSI_READ_TOC_PMA_ATIP   0x43

Definition at line 73 of file usb_msc.c.

◆ SCSI_REPORT_LUNS

#define SCSI_REPORT_LUNS   0xA0

Definition at line 66 of file usb_msc.c.

◆ SCSI_REQUEST_SENSE

#define SCSI_REQUEST_SENSE   0x03

Definition at line 52 of file usb_msc.c.

◆ SCSI_SEND_DIAGNOSTIC

#define SCSI_SEND_DIAGNOSTIC   0x1D

Definition at line 58 of file usb_msc.c.

◆ SCSI_START_STOP_UNIT

#define SCSI_START_STOP_UNIT   0x1B

Definition at line 74 of file usb_msc.c.

◆ SCSI_SYNCHRONIZE_CACHE

#define SCSI_SYNCHRONIZE_CACHE   0x35

Definition at line 75 of file usb_msc.c.

◆ SCSI_TEST_UNIT_READY

#define SCSI_TEST_UNIT_READY   0x00

Definition at line 51 of file usb_msc.c.

◆ SCSI_VERIFY

#define SCSI_VERIFY   0x2F

Definition at line 76 of file usb_msc.c.

◆ SCSI_WRITE_10

#define SCSI_WRITE_10   0x2A

Definition at line 77 of file usb_msc.c.

◆ SCSI_WRITE_12

#define SCSI_WRITE_12   0xAA

Definition at line 78 of file usb_msc.c.

◆ SCSI_WRITE_6

#define SCSI_WRITE_6   0x0A

Definition at line 55 of file usb_msc.c.

Enumeration Type Documentation

◆ sbc_asc

enum sbc_asc
Enumerator
SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION 
SBC_ASC_PERIPHERAL_DEVICE_WRITE_FAULT 
SBC_ASC_LOGICAL_UNIT_NOT_READY 
SBC_ASC_UNRECOVERED_READ_ERROR 
SBC_ASC_INVALID_COMMAND_OPERATION_CODE 
SBC_ASC_LBA_OUT_OF_RANGE 
SBC_ASC_INVALID_FIELD_IN_CDB 
SBC_ASC_WRITE_PROTECTED 
SBC_ASC_NOT_READY_TO_READY_CHANGE 
SBC_ASC_FORMAT_ERROR 
SBC_ASC_MEDIUM_NOT_PRESENT 

Definition at line 98 of file usb_msc.c.

◆ sbc_ascq

enum sbc_ascq
Enumerator
SBC_ASCQ_NA 
SBC_ASCQ_FORMAT_COMMAND_FAILED 
SBC_ASCQ_INITIALIZING_COMMAND_REQUIRED 
SBC_ASCQ_OPERATION_IN_PROGRESS 

Definition at line 112 of file usb_msc.c.

◆ sbc_sense_key

Enumerator
SBC_SENSE_KEY_NO_SENSE 
SBC_SENSE_KEY_RECOVERED_ERROR 
SBC_SENSE_KEY_NOT_READY 
SBC_SENSE_KEY_MEDIUM_ERROR 
SBC_SENSE_KEY_HARDWARE_ERROR 
SBC_SENSE_KEY_ILLEGAL_REQUEST 
SBC_SENSE_KEY_UNIT_ATTENTION 
SBC_SENSE_KEY_DATA_PROTECT 
SBC_SENSE_KEY_BLANK_CHECK 
SBC_SENSE_KEY_VENDOR_SPECIFIC 
SBC_SENSE_KEY_COPY_ABORTED 
SBC_SENSE_KEY_ABORTED_COMMAND 
SBC_SENSE_KEY_VOLUME_OVERFLOW 
SBC_SENSE_KEY_MISCOMPARE 

Definition at line 81 of file usb_msc.c.

◆ trans_event

Enumerator
EVENT_CBW_VALID 
EVENT_NEED_STATUS 

Definition at line 119 of file usb_msc.c.

Function Documentation

◆ get_cbw_buf()

static uint8_t * get_cbw_buf ( struct usb_msc_trans trans)
static

Definition at line 254 of file usb_msc.c.

References usb_msc_trans::cbw, and usb_msc_cbw::CBWCB.

Referenced by scsi_inquiry(), scsi_read_10(), scsi_read_6(), scsi_write_10(), and scsi_write_6().

Here is the caller graph for this function:

◆ msc_control_request()

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 
)
static

Handle various control requests related to the msc storage interface.

Definition at line 737 of file usb_msc.c.

References usb_setup_data::bRequest, USB_MSC_REQ_BULK_ONLY_RESET, USB_MSC_REQ_GET_MAX_LUN, USBD_REQ_HANDLED, and USBD_REQ_NOTSUPP.

Referenced by msc_set_config().

Here is the caller graph for this function:

◆ msc_data_rx_cb()

◆ msc_data_tx_cb()

static void msc_data_tx_cb ( usbd_device usbd_dev,
uint8_t  ep 
)
static

◆ msc_set_config()

static void msc_set_config ( usbd_device usbd_dev,
uint16_t  wValue 
)
static

Setup the endpoints to be bulk & register the callbacks.

Definition at line 759 of file usb_msc.c.

References _mass_storage, _usbd_mass_storage::ep_in, _usbd_mass_storage::ep_in_size, _usbd_mass_storage::ep_out, _usbd_mass_storage::ep_out_size, msc_control_request(), msc_data_rx_cb(), msc_data_tx_cb(), USB_ENDPOINT_ATTR_BULK, USB_REQ_TYPE_CLASS, USB_REQ_TYPE_INTERFACE, USB_REQ_TYPE_RECIPIENT, USB_REQ_TYPE_TYPE, usbd_ep_setup(), and usbd_register_control_callback().

Referenced by usb_msc_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ scsi_command()

◆ scsi_format_unit()

static void scsi_format_unit ( usbd_mass_storage ms,
struct usb_msc_trans trans,
enum trans_event  event 
)
static

Definition at line 363 of file usb_msc.c.

References _usbd_mass_storage::block_count, EVENT_CBW_VALID, usb_msc_trans::msd_buf, set_sbc_status_good(), and _usbd_mass_storage::write_block.

Referenced by scsi_command().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ scsi_inquiry()

static void scsi_inquiry ( usbd_mass_storage ms,
struct usb_msc_trans trans,
enum trans_event  event 
)
static

◆ scsi_mode_sense_6()

static void scsi_mode_sense_6 ( usbd_mass_storage ms,
struct usb_msc_trans trans,
enum trans_event  event 
)
static

◆ scsi_read_10()

static void scsi_read_10 ( usbd_mass_storage ms,
struct usb_msc_trans trans,
enum trans_event  event 
)
static

Definition at line 321 of file usb_msc.c.

References usb_msc_trans::block_count, usb_msc_trans::bytes_to_write, EVENT_CBW_VALID, get_cbw_buf(), usb_msc_trans::lba_start, and set_sbc_status_good().

Referenced by scsi_command().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ scsi_read_6()

static void scsi_read_6 ( usbd_mass_storage ms,
struct usb_msc_trans trans,
enum trans_event  event 
)
static

Definition at line 259 of file usb_msc.c.

References usb_msc_trans::block_count, usb_msc_trans::bytes_to_write, usb_msc_trans::current_block, EVENT_CBW_VALID, get_cbw_buf(), usb_msc_trans::lba_start, and set_sbc_status_good().

Referenced by scsi_command().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ scsi_read_capacity()

static void scsi_read_capacity ( usbd_mass_storage ms,
struct usb_msc_trans trans,
enum trans_event  event 
)
static

Definition at line 343 of file usb_msc.c.

References _usbd_mass_storage::block_count, usb_msc_trans::bytes_to_write, EVENT_CBW_VALID, usb_msc_trans::msd_buf, and set_sbc_status_good().

Referenced by scsi_command().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ scsi_request_sense()

static void scsi_request_sense ( usbd_mass_storage ms,
struct usb_msc_trans trans,
enum trans_event  event 
)
static

◆ scsi_write_10()

static void scsi_write_10 ( usbd_mass_storage ms,
struct usb_msc_trans trans,
enum trans_event  event 
)
static

Definition at line 301 of file usb_msc.c.

References usb_msc_trans::block_count, usb_msc_trans::bytes_to_read, usb_msc_trans::current_block, EVENT_CBW_VALID, get_cbw_buf(), and usb_msc_trans::lba_start.

Referenced by scsi_command().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ scsi_write_6()

static void scsi_write_6 ( usbd_mass_storage ms,
struct usb_msc_trans trans,
enum trans_event  event 
)
static

Definition at line 281 of file usb_msc.c.

References usb_msc_trans::block_count, usb_msc_trans::bytes_to_read, usb_msc_trans::current_block, EVENT_CBW_VALID, get_cbw_buf(), and usb_msc_trans::lba_start.

Referenced by scsi_command().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_sbc_status()

static void set_sbc_status ( usbd_mass_storage ms,
enum sbc_sense_key  key,
enum sbc_asc  asc,
enum sbc_ascq  ascq 
)
static

Definition at line 236 of file usb_msc.c.

References sbc_sense_info::asc, sbc_sense_info::ascq, sbc_sense_info::key, and _usbd_mass_storage::sense.

Referenced by scsi_command(), scsi_mode_sense_6(), and set_sbc_status_good().

Here is the caller graph for this function:

◆ set_sbc_status_good()

static void set_sbc_status_good ( usbd_mass_storage ms)
static

Definition at line 246 of file usb_msc.c.

References SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION, SBC_ASCQ_NA, SBC_SENSE_KEY_NO_SENSE, and set_sbc_status().

Referenced by scsi_command(), scsi_format_unit(), scsi_inquiry(), scsi_read_10(), scsi_read_6(), scsi_read_capacity(), and usb_msc_init().

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ _mass_storage

usbd_mass_storage _mass_storage
static

Definition at line 195 of file usb_msc.c.

Referenced by msc_data_rx_cb(), msc_data_tx_cb(), msc_set_config(), and usb_msc_init().

◆ _spc3_inquiry_response

const uint8_t _spc3_inquiry_response[36]
static
Initial value:
= {
0x00,
0x80,
0x04,
0x02,
0x20,
0x00,
0x00,
0x00,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20
}

Definition at line 199 of file usb_msc.c.

Referenced by scsi_inquiry().

◆ _spc3_request_sense

const uint8_t _spc3_request_sense[18]
static
Initial value:
= {
0x70,
0x00,
0x00,
0, 0, 0, 0,
0x0a,
0, 0, 0, 0,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00
}

Definition at line 217 of file usb_msc.c.

Referenced by scsi_request_sense().