Data Structures | Typedefs | Enumerations | Functions

USB MSC Class Enumerations and Descriptors
[Public API]

Packet structs, constants, and callback functions implementing the "Universal Serial Bus Mass Storage Class", revision 1.4, and the "Universal Serial Bus Mass Storage Class Bulk-Only Transport", revision 1.0. More...

Data Structures

struct  msc_command_block_wrapper
 MSC Bulk-Only Data Command Block Wrapper. More...
struct  msc_command_status_wrapper
 MSC Bulk-Only Data Command Block Wrapper. More...
struct  msc_scsi_inquiry_command
struct  msc_scsi_request_sense_command
struct  msc_scsi_mode_sense_6_command
struct  msc_scsi_start_stop_unit
struct  msc_scsi_read_10_command
struct  msc_scsi_write_10_command
struct  scsi_inquiry_response
struct  scsi_capacity_response
struct  scsi_mode_sense_response
struct  scsi_sense_response
class  msc_application_data
 MSC Applicaiton Data. More...

Typedefs

typedef uint8_t msc_lun_mask_t
typedef void(* msc_completion_callback )(struct msc_application_data *app_data, bool transfer_ok)
 MSC Transmission Complete Callback.

Enumerations

enum  MSCRequests { MSC_GET_MAX_LUN = 0xfe, MSC_BULK_ONLY_MASS_STORAGE_RESET = 0xff }
 

MSC Class Requests.

More...
enum  MSCStatus { MSC_STATUS_PASSED = 0, MSC_STATUS_FAILED = 1, MSC_STATUS_PHASE_ERROR = 2 }
 

MSC Command Block Status Values.

More...
enum  MSCDirection { MSC_DIRECTION_OUT = 0x0, MSC_DIRECTION_IN_BIT = 0x80 }
 

MSC Command Block Flags (Direction is the only used bit)

More...
enum  MSCSCSICommands {
  MSC_SCSI_FORMAT_UNIT = 0x04, MSC_SCSI_INQUIRY = 0x12, MSC_SCSI_MODE_SELECT_6 = 0x15, MSC_SCSI_MODE_SELECT_10 = 0x55,
  MSC_SCSI_MODE_SENSE_6 = 0x1a, MSC_SCSI_MODE_SENSE_10 = 0x5a, MSC_SCSI_START_STOP_UNIT = 0x1b, MSC_SCSI_READ_6 = 0x08,
  MSC_SCSI_READ_10 = 0x28, MSC_SCSI_READ_CAPACITY_10 = 0x25, MSC_SCSI_REPORT_LUNS = 0xa0, MSC_SCSI_REQUEST_SENSE = 0x03,
  MSC_SCSI_SEND_DIAGNOSTIC = 0x1d, MSC_SCSI_TEST_UNIT_READY = 0x00, MSC_SCSI_VERIFY = 0x2f, MSC_SCSI_WRITE_6 = 0x0a,
  MSC_SCSI_WRITE_10 = 0x2a
}
enum  MSCSCSIVersion { MSC_SCSI_SPC_VERSION_2 = 4, MSC_SCSI_SPC_VERSION_3 = 5 }
enum  SCSISenseResponseCode { SCSI_SENSE_CURRENT_ERRORS = 0x70, SCSI_SENSE_DEFERRED_ERRORS = 0x71, SCSI_SENSE_INFORMATION_VALID = 0x80 }
enum  SCSISenseFlags { SCSI_SENSE_FILEMARK = 0x80, SCSI_SENSE_EOM = 0x40, SCSI_SENSE_ILI = 0x20, SCSI_SENSE_KEY_MASK = 0x0f }
enum  SCSISenseKeys {
  SCSI_SENSE_KEY_NOT_READY = 0x2, SCSI_SENSE_KEY_MEDIUM_ERROR = 0x3, SCSI_SENSE_KEY_ILLEGAL_REQUEST = 0x5, SCSI_SENSE_KEY_UNIT_ATTENTION = 0x6,
  SCSI_SENSE_KEY_DATA_PROTECT = 0x7
}
enum  SCSIAdditionalSenseCodes {
  SCSI_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE = 0x21, SCSI_ASC_INVALID_COMMAND_OPERATION_CODE = 0x20, SCSI_ASC_INVALID_FIELD_IN_COMMAND_PACKET = 0x24, SCSI_ASC_LOGICAL_UNIT_NOT_SUPPORTED = 0x25,
  SCSI_ASC_PERIPHERAL_DEVICE_WRITE_FAULT = 0x03, SCSI_ASC_UNRECOVERED_READ_ERROR = 0x11, SCSI_ASC_WRITE_ERROR = 0x0c, SCSI_ASC_MEDIUM_NOT_PRESENT = 0x3a,
  SCSI_ASC_WRITE_PROTECTED = 0x27
}
enum  MSCApplicationStates {
  MSC_IDLE, MSC_DATA_TRANSPORT_IN, MSC_DATA_TRANSPORT_OUT, MSC_STALL,
  MSC_CSW, MSC_NEEDS_RESET_RECOVERY
}
 

MSC Application States.

More...
enum  MSCReturnCodes {
  MSC_SUCCESS = 0, MSC_ERROR_MEDIUM_NOT_PRESENT = -1, MSC_ERROR_INVALID_LUN = -2, MSC_ERROR_INVALID_ADDRESS = -3,
  MSC_ERROR_WRITE_PROTECTED = -4, MSC_ERROR_READ = -5, MSC_ERROR_WRITE = -6, MSC_ERROR_MEDIUM = -7
}
 

Return codes used by application callbacks.

More...

Functions

uint8_t msc_init (struct msc_application_data *app_data, uint8_t count)
int8_t process_msc_setup_request (const struct setup_packet *setup)
 Process MSC Setup Request.
void msc_clear_halt (uint8_t endpoint_num, uint8_t direction)
 Clear Halt on MSC Endpoint.
void msc_in_transaction_complete (uint8_t endpoint_num)
 Notify of a transaction completing on the Data-IN endpoint.
void msc_out_transaction_complete (uint8_t endpoint_num)
 Notify of a transaction completing on the Data-OUT endpoint.
uint8_t msc_start_send_to_host (struct msc_application_data *app_data, const uint8_t *data, uint16_t len, msc_completion_callback completion_callback)
 Send data read from the medium to the host.
void msc_notify_read_operation_complete (struct msc_application_data *app_data, bool passed)
 Notify the MSC class that a Read Operation has Completed.
void msc_notify_write_data_handled (struct msc_application_data *app_data)
 Notify Write Data Handled.
void msc_notify_write_operation_complete (struct msc_application_data *app_data, bool passed, uint32_t bytes_processed)
 Notify Write Operation Complete.
int8_t MSC_BULK_ONLY_MASS_STORAGE_RESET_CALLBACK (uint8_t interface)
 MSC Bulk-Only Mass Storage Reset callback.
int8_t MSC_GET_STORAGE_INFORMATION (const struct msc_application_data *app_data, uint8_t lun, uint32_t *block_size, uint32_t *num_blocks, bool *write_protect)
 MSC Get Storage Information Callback.
int8_t MSC_UNIT_READY (const struct msc_application_data *app_data, uint8_t lun)
 MSC Check if Medium is Ready Callback.
int8_t MSC_START_STOP_UNIT (const struct msc_application_data *app_data, uint8_t lun, bool start, bool load_eject)
 Start or Stop an MSC Unit.
int8_t MSC_START_READ (struct msc_application_data *app_data, uint8_t lun, uint32_t lba_address, uint16_t num_blocks)
 MSC Read Callback.
int8_t MSC_START_WRITE (struct msc_application_data *app_data, uint8_t lun, uint32_t lba_address, uint16_t num_blocks, uint8_t **buffer, size_t *buffer_len, msc_completion_callback *callback)
 MSC Write Callback.

Detailed Description

Packet structs, constants, and callback functions implementing the "Universal Serial Bus Mass Storage Class", revision 1.4, and the "Universal Serial Bus Mass Storage Class Bulk-Only Transport", revision 1.0.

An indespensible reference is Jan Axelson's "USB Mass Storage" book. The major value in this book is the real-life perspective regarding which parts of the SCSI standards are actually used in USB devices, what they are used for, and how the SCSI commands and terminology map onto USB devices.

Document sections listed in the comments are prefixed with the document they reference as follows:
MSCO: USB Mass Storage Class, revision 1.4
BOT: USB Mass Storage Class Bulk-Only Transport, revision 1.0
Axelson: Jan Axelson's "USB Mass Storage" book

For more information, see the above referenced document, available from http://www.usb.org .


Typedef Documentation

typedef void(* msc_completion_callback)(struct msc_application_data *app_data, bool transfer_ok)

MSC Transmission Complete Callback.

This is the callback function type expected to be passed to msc_start_send_to_host(). Callback functions will be called by the stack when the transmission of a block of data has completed.

Parameters:
app_dataPointer to application data for this interface.
transfer_oktrue if transaction completed successfully, or false if there was an error

Enumeration Type Documentation

MSC Application States.

The states the transport goes through.

Enumerator:
MSC_DATA_TRANSPORT_IN 

Next transactions will be data sent.

MSC_DATA_TRANSPORT_OUT 

Next transactions will be data received.

MSC_STALL 

Next transaction needs to stall.

MSC_CSW 

Next transaction will contain the CSW.

MSC_NEEDS_RESET_RECOVERY 

Reset recovery is required.

MSC Command Block Flags (Direction is the only used bit)

See BOT, 5.1

MSC Class Requests.

These are the class requests needed for MSC Bulk-Only Transport (MSCO: sec 4, table 3). Others are omitted. Get in contact with Signal 11 if you need something specific.

Return codes used by application callbacks.

Success is defined to be 0 and all failures are < 0.

Enumerator:
MSC_ERROR_MEDIUM_NOT_PRESENT 

The medium is not physically present.

MSC_ERROR_INVALID_LUN 

The LUN is out of range.

MSC_ERROR_INVALID_ADDRESS 

The LBA address is out of range.

MSC_ERROR_WRITE_PROTECTED 

The medium is write protected.

MSC_ERROR_READ 

Error while reading the medium.

MSC_ERROR_WRITE 

Error while writing the medium.

MSC_ERROR_MEDIUM 

Unspecified medium error.

enum MSCStatus

MSC Command Block Status Values.

See BOT, 5.2


Function Documentation

int8_t MSC_BULK_ONLY_MASS_STORAGE_RESET_CALLBACK ( uint8_t  interface )

MSC Bulk-Only Mass Storage Reset callback.

The MSC class will call this function when a Bulk-Only Mass Storage Reset request has been received from the host. This function should perform a reset of the device indicated by interfce and not return until this has been completed.

Parameters:
interfaceThe interface for which the command is intended
Returns:
Return 0 if the request can be handled or -1 if it cannot. Returning -1 will cause STALL to be returned to the host.
void msc_clear_halt ( uint8_t  endpoint_num,
uint8_t  direction 
)

Clear Halt on MSC Endpoint.

Notify the MSC class that a CLEAR_FEATURE ENDPOINT_HALT has been received for an MSC endpoint.

Parameters:
endpoint_numThe endpoint number affected
directionThe endpoint direction affected. 0=out, 1=in
int8_t MSC_GET_STORAGE_INFORMATION ( const struct msc_application_data app_data,
uint8_t  lun,
uint32_t *  block_size,
uint32_t *  num_blocks,
bool *  write_protect 
)

MSC Get Storage Information Callback.

The USB Stack will call this function when the host requests information about the storage device.

SCSI (and therefore USB) drives are required to support LBA (Logical Block Addressing) which means every block on the drive can be addressed as an array of fixed-sized blocks.

This function may be called more than once as data is requested by the host.

Parameters:
app_dataPointer to application data for this interface.
lunThe Logical Unit Number (LUN) of the medium requested.
block_sizeThe block size for this medium. This block size is used for both reading and writing. It should be a multiple of both the IN and OUT endpoint sizes, but does not strictly have to be. If it is not, the handling of reads and writes on the application side will likely be more complex. The block_size must be below 2^24.
num_blocksThe number of blocks the medium contains.
write_protectWhether write-protection is enabled.
Returns:
Return a code from MSCReturnCodes. Returning non-success will cause an error to be returned to the host.
void msc_in_transaction_complete ( uint8_t  endpoint_num )

Notify of a transaction completing on the Data-IN endpoint.

Notify the MSC class that an IN transaction has completed on the Data-IN endpoint. If using interrupts, call this function from the IN_TRANSACTION_COMPLETE_CALLBACK.

This function will not block.

Parameters:
endpoint_numThe endpoint number affected
void msc_notify_read_operation_complete ( struct msc_application_data app_data,
bool  passed 
)

Notify the MSC class that a Read Operation has Completed.

Tell the MSC class that a read operation has been completed with either success or failure.

In the case of success, pass true to passed, indicating that the data requested by an MSC_READ() callback has all been passed to the MSC class using msc_start_send_to_host(). This will cause the transfer to complete successfully.

If the read failed, pass false to passed. This will cause a SCSI MEDIUM_ERROR to be returned to the host.

Parameters:
app_dataPointer to application data for this interface.
passedWhether the read operation completed successfully
void msc_notify_write_data_handled ( struct msc_application_data app_data )

Notify Write Data Handled.

Tell the MSC class that a block of data provided to a write callback has been handled, and that the buffer is no longer in use by the applicaiton. The MSC stack will now provide the next block to be written into the same buffer and call the callback provided to MSC_START_WRITE().

Note that calling this function does not necessarily indicate that the data was successfully written to the medium. It only indicates that the application has received the buffer and dealt with it, and requests that the MSC stack put the next block of data into the buffer. It is possible the application does not know that a write operation has failed (or will fail) until the end of the write operation.

Note that if there are OUT transfers pending (and waiting because the application is using the buffer), and if the application's buffer is sufficiently small, then the MSC stack could potentially call the msc_completion_callback() from this function. With small buffers, this is a typical case.

If there was an error in handling the data, call msc_notify_write_operation_complete() instead to cancel the transport.

Parameters:
app_dataPointer to application data for this interface.
void msc_notify_write_operation_complete ( struct msc_application_data app_data,
bool  passed,
uint32_t  bytes_processed 
)

Notify Write Operation Complete.

Tell the MSC class that a write operation has completed, either with full success, with partial success, or with failure. The MSC stack can now complete the data transport and report the status to the host.

In the case of a complete success, set passed to true, and set bytes_processed to the number of bytes which were asked for and written.

In the case of a failure or a partial success, set passed to false and set bytes_processed to the number of bytes which were acutally written successfully.

Pass true as passed if the write succeeded or false if it failed.

Parameters:
app_dataPointer to application data for this interface.
passedWhether the write operation fully completed successfully, writing all desired data.
bytes_processedThe number of bytes successfully written. This may be fewer than the number of bytes asked for by the host.
void msc_out_transaction_complete ( uint8_t  endpoint_num )

Notify of a transaction completing on the Data-OUT endpoint.

Notify the MSC class that an OUT transaction has completed on the Data-OUT endpoint. This function will process the data which is available on endpoint endpoint_num and will re-arm the endpoint when appropriate.

If using interrupts, call this function from the OUT_TRANSACTION_CALLBACK.

This function will not block.

Parameters:
endpoint_numThe endpoint number affected
int8_t MSC_START_READ ( struct msc_application_data app_data,
uint8_t  lun,
uint32_t  lba_address,
uint16_t  num_blocks 
)

MSC Read Callback.

The USB Stack will call this function when the host requests a read operation from the device. This callback will initiate reading data from the medium. The application will then call msc_start_send_to_host() repeatedly until all data has been given to the MSC class. At that point, the application must call msc_notify_read_operation_complete() to indicate that the Data-Transport is complete.

See the documentation for msc_start_send_to_host() for additional restrictions.

Note that this funciton must simply kick-off the reading/sending of the data and return quickly. In other words, this function must not block.

Parameters:
app_dataPointer to application data for this interface.
lunThe Logical Unit Number (LUN) of the medium requested.
lba_addressLogical Block Address to start reading from.
num_blocksNumber of blocks to read.
Returns:
Return a code from MSCReturnCodes. Returning non-success will cause an error to be returned to the host.
uint8_t msc_start_send_to_host ( struct msc_application_data app_data,
const uint8_t *  data,
uint16_t  len,
msc_completion_callback  completion_callback 
)

Send data read from the medium to the host.

Start transmission of data that has been read from the storage medium to the host. This function simply starts the transmission and returns control immediately to the caller without blocking. When the transmission has completed, the completion_callback will be called. The application should call this function as soon as data is available from the storage medium, and should not call it again until the completion_callback has been called. For example, if 8 blocks are requested by the host, the application could read a single block, call msc_start_send_to_host(), wait for the completion_callback to be called, then call msc_start_send_to_host() with the second block, and so on..

This function does not block.

completion_callback will be called from interrupt context and must not block.

len needs to be multiple of the IN endpoint size for all calls to this function except the last in response to an MSC_READ() callback.

Parameters:
app_dataPointer to application data for this interface.
dataPointer to the data to send.
lenData length in bytes. Must be a multiple of the IN endpoint size.
completion_callbackPointer to a function which is called when the transmission has completed.
Returns:
Returns 0 if the transmission could be started or -1 if it could not.
int8_t MSC_START_STOP_UNIT ( const struct msc_application_data app_data,
uint8_t  lun,
bool  start,
bool  load_eject 
)

Start or Stop an MSC Unit.

The USB Stack will call this function when the host requests that a logical unit start or stop. This is mostly used for stopping and ejecting the medium.

Parameters:
app_dataPointer to application data for this interface.
lunThe Logical Unit Number (LUN) of the medium requested.
startWhether to start or stop the medium. true means to start, and false means to stop the medium.
load_ejectWhether to load or eject the medium. The desired behavior depends on the value of start. When load_eject is true, then the application should load media if start is true, or eject media if start is false.

The four cases for start and load_eject: if (start && load_eject): load the medium if (start && !load_eject): neither load nor eject if (!start && load_eject): eject the medium if (!start && !load_eject): neither load nor eject

Returns:
Return a code from MSCReturnCodes. Returning non-success will cause an error to be returned to the host.
int8_t MSC_START_WRITE ( struct msc_application_data app_data,
uint8_t  lun,
uint32_t  lba_address,
uint16_t  num_blocks,
uint8_t **  buffer,
size_t *  buffer_len,
msc_completion_callback callback 
)

MSC Write Callback.

The USB Stack will call this function when the host requests to write data to the device. The application's implementation of this function will provide a buffer (buffer) where the USB stack will place the data as it is received. Once the buffer is full, the USB stack will call the provided callback function (callback), notifying the application that it can begin processing the data (ie: writing it to the medium). Once the buffer has been processed (and the application is done with the buffer), the application must then call msc_notify_block_write_complete() to notify the USB stack that it is ready for the next buffer-full of data.

Note that this funciton must simply set any necessary state on the appliction side and return the requested data quickly. In other words, this function must not block.

Parameters:
app_dataPointer to application data for this interface.
lunThe Logical Unit Number (LUN) of the medium requested.
lba_addressLogical Block Address the data is intended for.
num_blocksNumber of blocks which will eventually be written.
bufferThe place to put the data from the USB bus
buffer_lenThe size of the buffer in bytes. It must be a multiple of the OUT endpoint size.
callbackA function to be called when the data has been received from the host. It will be called from interrupt context and must not block.
Returns:
Return a code from MSCReturnCodes. Returning non-success will cause an error to be returned to the host.
int8_t MSC_UNIT_READY ( const struct msc_application_data app_data,
uint8_t  lun 
)

MSC Check if Medium is Ready Callback.

The USB Stack will call this function when the host requests information regarding whether the medium is ready or not.

This function may be called more than once as data is requested by the host.

Parameters:
app_dataPointer to application data for this interface.
lunThe Logical Unit Number (LUN) of the medium requested.
Returns:
Return a code from MSCReturnCodes. Returning non-success will cause an error to be returned to the host.
int8_t process_msc_setup_request ( const struct setup_packet setup )

Process MSC Setup Request.

Process a setup request which has been unhandled as if it is potentially an MSC setup request. This function will then call appropriate callbacks into the appliction if the setup packet is one recognized by the MSC specification.

Parameters:
setupA setup packet to handle
Returns:
Returns 0 if the setup packet could be processed or -1 if it could not.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator