Microchip® Advanced Software Framework

uhi_msc.c File Reference

USB host Mass Storage Class interface.

Copyright (c) 2011-2018 Microchip Technology Inc. and its subsidiaries.

#include "conf_usb_host.h"
#include "usb_protocol.h"
#include "uhd.h"
#include "uhc.h"
#include "uhi_msc.h"
#include <string.h>

Data Structures

struct  uhi_msc_dev_t
 USB MSC device information. More...
 

Macros

#define UHI_MSC_NOTIFY_NEW_LUN_EXT
 
#define UHI_MSC_SCSI_TIMEOUT   20000
 Timeout on SCSI commands. More...
 

Typedefs

typedef void(* uhi_msc_scsi_sense_callback_t )(void)
 Callback type used by scsi sense command. More...
 

Functions

Variables to manage SCSI requests
 UHC_BSS (4)
 Structure to send a CBW packet. More...
 
Interface used by UHC module

Structure to receive a CSW packet

void uhi_msc_enable (uhc_device_t *dev)
 
void uhi_msc_uninstall (uhc_device_t *dev)
 
Routines to initialize the MSC devices
static void uhi_msc_enable_step1 (void)
 Step 1 of the initialization of a USB MSC device Sends the setup request GET_MAX_LUN. More...
 
static void uhi_msc_enable_step2 (usb_add_t add, uhd_trans_status_t status, uint16_t payload_trans)
 Step 2 of the initialization of a USB MSC device Decode the setup request GET_MAX_LUN and allocs LUN structures. More...
 
static void uhi_msc_enable_step3 (void)
 Step 3 of the initialization of a USB MSC device Selects the next LUN. More...
 
static void uhi_msc_enable_step4 (bool b_success)
 Step 4 of the initialization of a USB MSC device Sends the SCSI READ CAPACITY request on the current LUN. More...
 
static void uhi_msc_enable_step5 (bool b_success)
 Step 5 of the initialization of a USB MSC device Go to the initialization of the next LUN. More...
 
External SCSI commands
bool uhi_msc_is_available (void)
 Tests if the interface UHI Mass Storage is available The UHI Mass Storage can be busy during the enumeration of a USB Device MSC. More...
 
uint8_t uhi_msc_get_lun (void)
 Gives the number of LUN available Note: A LUN can be available, but with a status LUN_NOT_PRESENT. More...
 
uhi_msc_lun_tuhi_msc_get_lun_desc (uint8_t lun)
 Gives information about a LUN. More...
 
bool uhi_msc_scsi_test_unit_ready (uint8_t lun, uhi_msc_scsi_callback_t callback)
 Checks and update the status of the LUN. More...
 
bool uhi_msc_scsi_read_10 (uint8_t lun, uint32_t addr, uint8_t *ram, uint8_t nb_sector, uhi_msc_scsi_callback_t callback)
 Reads a LUN data section to RAM buffer Note: The sector size used to define the data section is the sector size returned by LUN in field. More...
 
bool uhi_msc_scsi_write_10 (uint8_t lun, uint32_t addr, const uint8_t *ram, uint8_t nb_sector, uhi_msc_scsi_callback_t callback)
 Writes a RAM buffer in a LUN data section Note: The sector size used to define the data section is the sector size returned by LUN in field. More...
 
Internal SCSI commands and sub routines
static bool uhi_msc_select_lun (uint8_t lun)
 Selects a LUN. More...
 
static void uhi_msc_scsi_inquiry (uhi_msc_scsi_callback_t callback)
 Sends the CBW packet of the scsi INQUIRY command. More...
 
static void uhi_msc_scsi_inquiry_done (bool b_cbw_succes)
 Call the callback at the end of scsi INQUIRY command. More...
 
static void uhi_msc_scsi_test_unit_ready_done (bool b_cbw_succes)
 Decodes the result of scsi TEST UNIT READY command Launches READ CAPACITY command, if a new LUN has been detected. More...
 
static void uhi_msc_scsi_test_unit_ready_sense (void)
 Decodes the scsi sense code after an error on TEST UNIT READY command. More...
 
static void uhi_msc_scsi_read_capacity (uhi_msc_scsi_callback_t callback)
 Sends the CBW packet of the scsi READ CAPACITY command. More...
 
static void uhi_msc_scsi_read_capacity_done (bool b_cbw_succes)
 Decodes the result of scsi READ CAPACITY command Launches MODE SENSE 6 command. More...
 
static void uhi_msc_scsi_read_capacity_sense (void)
 Decodes the scsi sense code after a scsi READ CAPACITY command failed. More...
 
static void uhi_msc_scsi_mode_sense6 (uhi_msc_scsi_callback_t callback)
 Sends the CBW packet of the scsi MODE SENSE 6 command This function returns the write-protected mode. More...
 
static void uhi_msc_scsi_mode_sense6_done (bool b_cbw_succes)
 Decodes the result of scsi MODE SENSE 6 command. More...
 
static void uhi_msc_scsi_read_10_done (bool b_cbw_succes)
 Decodes the result of scsi READ 10 command. More...
 
static void uhi_msc_scsi_write_10_done (bool b_cbw_succes)
 Decodes the result of scsi WRITE 10 command. More...
 
static void uhi_msc_scsi_request_sense (uhi_msc_scsi_sense_callback_t callback)
 Sends the CBW packet of the scsi REQUESRT SENSE command Called by TEST UNIT READY and READ CAPACITY command in case of error. More...
 
static void uhi_msc_scsi_request_sense_done (bool b_cbw_succes)
 Decodes the result of scsi REQUEST SENSE command. More...
 
Internal SCSI protocol routines
static void uhi_msc_scsi (uhi_msc_scsi_callback_t callback, uint8_t *payload)
 Sends the CBW packet. More...
 
static void uhi_msc_cbw_sent (usb_add_t add, usb_ep_t ep, uhd_trans_status_t status, iram_size_t nb_transfered)
 Checks the CBW packet transfer and launch the next step The next step can be a DATA phase or a CSW packet. More...
 
static void uhi_msc_data_transfered (usb_add_t add, usb_ep_t ep, uhd_trans_status_t status, iram_size_t nb_transfered)
 Checks the DATA phase transfer and launch the next step The next step can be a CSW packet or a endpoint reset in case of STALL. More...
 
static void uhi_msc_csw_wait (void)
 Start the transfer of the CSW packet. More...
 
static void uhi_msc_csw_received (usb_add_t add, usb_ep_t ep, uhd_trans_status_t status, iram_size_t nb_transfered)
 Checks the CSW packet transfer. More...
 
static void uhi_msc_cbw_rst_stall (usb_add_t add, uhd_trans_status_t status, uint16_t payload_trans)
 Manages the end of setup request RESET ENDPOINT after a CBW packet. More...
 
static void uhi_msc_data_csw_rst_stall (usb_add_t add, uhd_trans_status_t status, uint16_t payload_trans)
 Manages the end of RESET ENDPOINT request after a DATA or CSW packet. More...
 
static void uhi_msc_transfer (usb_ep_t endp, uint8_t *payload, uint16_t payload_size, uhd_callback_trans_t callback_end)
 Start a transfer on an endpoint of current USB MSC device Used to send a CBW packet, DATA packet, or a CSW packet. More...
 
static void uhi_msc_reset_endpoint (usb_ep_t endp, uhd_callback_setup_end_t callback)
 Sends a setup request RESET ENDPOINT Used after a STALL received during a scsi command. More...
 

Variables

static struct
sbc_read_capacity10_data 
uhi_msc_capacity
 Temporary structures used to read LUN information via a SCSI command. More...
 
static struct scsi_inquiry_data uhi_msc_inquiry
 
static struct
scsi_request_sense_data 
uhi_msc_sense
 
struct {
   struct scsi_mode_param_header6   header
 
   struct spc_control_page_info_execpt   sense_data
 
uhi_msc_sense6
 
static uhi_msc_scsi_callback_t uhi_msc_scsi_sub_callback
 Internal callbacks. More...
 
static uhi_msc_scsi_callback_t uhi_msc_scsi_callback
 
static
uhi_msc_scsi_sense_callback_t 
uhi_msc_scsi_sense_callback
 

Internal defines and variables to manage MSC unit

#define uhi_msc_dev_sel   (&uhi_msc_dev)
 Current USB MSC device selected by the UHI MSC. More...
 
static volatile bool b_uhi_msc_free = true
 Flag to secure the UHI MSC resources. More...
 
static uhi_msc_dev_t uhi_msc_dev
 Information about the enumerated USB MSC device. More...
 
#define uhi_msc_lun_num_sel   uhi_msc_cbw.bCBWLUN
 
static uhi_msc_lun_tuhi_msc_lun_sel
 Current LUN selected in USB MSC device by the UHI MSC. More...
 

#define UHI_MSC_NOTIFY_NEW_LUN_EXT

UHC_BSS ( )

Structure to send a CBW packet.

static void uhi_msc_cbw_rst_stall ( usb_add_t  add,
uhd_trans_status_t  status,
uint16_t  payload_trans 
)
static

Manages the end of setup request RESET ENDPOINT after a CBW packet.

Parameters
addUSB address of the setup request
statusTransfer status
payload_transNumber of data transfered during DATA phase

References uhi_msc_scsi_sub_callback, and UNUSED.

Referenced by uhi_msc_cbw_sent().

static void uhi_msc_cbw_sent ( usb_add_t  add,
usb_ep_t  ep,
uhd_trans_status_t  status,
iram_size_t  nb_transfered 
)
static

Checks the CBW packet transfer and launch the next step The next step can be a DATA phase or a CSW packet.

Parameters
addUSB address used by the transfer
statusTransfer status
nb_transferedNumber of data transfered

References Assert, cpu_to_le32, uhi_msc_dev_t::ep_in, uhi_msc_dev_t::ep_out, UHD_TRANS_NOERROR, UHD_TRANS_STALL, uhi_msc_cbw_rst_stall(), uhi_msc_csw_wait(), uhi_msc_data_transfered(), uhi_msc_reset_endpoint(), uhi_msc_scsi_sub_callback, uhi_msc_transfer(), UNUSED, and USB_CBW_DIRECTION_IN.

Referenced by uhi_msc_scsi().

static void uhi_msc_csw_received ( usb_add_t  add,
usb_ep_t  ep,
uhd_trans_status_t  status,
iram_size_t  nb_transfered 
)
static

Checks the CSW packet transfer.

Parameters
addUSB address used by the transfer
statusTransfer status
nb_transferedNumber of data transfered

References CPU_TO_BE32, uhi_msc_dev_t::ep_in, le32_to_cpu, UHD_TRANS_NOERROR, UHD_TRANS_STALL, uhi_msc_data_csw_rst_stall(), uhi_msc_reset_endpoint(), uhi_msc_scsi_sub_callback, UNUSED, and USB_CSW_SIGNATURE.

Referenced by uhi_msc_csw_wait().

static void uhi_msc_csw_wait ( void  )
static
static void uhi_msc_data_csw_rst_stall ( usb_add_t  add,
uhd_trans_status_t  status,
uint16_t  payload_trans 
)
static

Manages the end of RESET ENDPOINT request after a DATA or CSW packet.

Parameters
addUSB address of the setup request
statusTransfer status
payload_transNumber of data transfered during DATA phase

References UHD_TRANS_NOERROR, uhi_msc_csw_wait(), uhi_msc_scsi_sub_callback, and UNUSED.

Referenced by uhi_msc_csw_received(), and uhi_msc_data_transfered().

static void uhi_msc_data_transfered ( usb_add_t  add,
usb_ep_t  ep,
uhd_trans_status_t  status,
iram_size_t  nb_transfered 
)
static

Checks the DATA phase transfer and launch the next step The next step can be a CSW packet or a endpoint reset in case of STALL.

Parameters
addUSB address used by the transfer
statusTransfer status
nb_transferedNumber of data transfered

References uhi_msc_dev_t::ep_in, uhi_msc_dev_t::ep_out, UHD_TRANS_NOERROR, UHD_TRANS_STALL, uhi_msc_csw_wait(), uhi_msc_data_csw_rst_stall(), uhi_msc_reset_endpoint(), uhi_msc_scsi_sub_callback, UNUSED, and USB_CBW_DIRECTION_IN.

Referenced by uhi_msc_cbw_sent().

static void uhi_msc_enable_step2 ( usb_add_t  add,
uhd_trans_status_t  status,
uint16_t  payload_trans 
)
static

Step 2 of the initialization of a USB MSC device Decode the setup request GET_MAX_LUN and allocs LUN structures.

Parameters
addUSB address of the setup request
statusTransfer status
payload_transNumber of data transfered during DATA phase

References Assert, b_uhi_msc_free, uhi_msc_dev_t::lun, uhi_msc_dev_t::nb_lun, UHD_TRANS_NOERROR, UHD_TRANS_STALL, uhi_msc_enable_step3(), uhi_msc_lun_num_sel, and UNUSED.

Referenced by uhi_msc_enable_step1().

static void uhi_msc_enable_step3 ( void  )
static

Step 3 of the initialization of a USB MSC device Selects the next LUN.

Sends the SCSI INQUIRY request on the LUN.

References b_uhi_msc_free, uhi_msc_dev_t::dev, LUN_NOT_PRESENT, uhi_msc_lun_t::status, UHI_MSC_CHANGE, uhi_msc_enable_step4(), uhi_msc_lun_num_sel, uhi_msc_scsi_inquiry(), and uhi_msc_select_lun().

Referenced by uhi_msc_enable_step2(), uhi_msc_enable_step4(), and uhi_msc_enable_step5().

static void uhi_msc_enable_step4 ( bool  b_success)
static

Step 4 of the initialization of a USB MSC device Sends the SCSI READ CAPACITY request on the current LUN.

Parameters
b_successtrue, if the scsi command is successful

References uhi_msc_enable_step3(), uhi_msc_enable_step5(), and uhi_msc_scsi_read_capacity().

Referenced by uhi_msc_enable_step3().

static void uhi_msc_enable_step5 ( bool  b_success)
static

Step 5 of the initialization of a USB MSC device Go to the initialization of the next LUN.

Parameters
b_successtrue, if the scsi command is successful

References uhi_msc_enable_step3(), and UNUSED.

Referenced by uhi_msc_enable_step4().

static void uhi_msc_reset_endpoint ( usb_ep_t  endp,
uhd_callback_setup_end_t  callback 
)
static
static void uhi_msc_scsi ( uhi_msc_scsi_callback_t  callback,
uint8_t *  payload 
)
static

Sends the CBW packet.

Parameters
callbackCallback to call at the end of scsi protocol
payloadPointer on the data to transfer (Optional)

References cpu_to_le32, uhi_msc_dev_t::ep_out, uhi_msc_cbw_sent(), uhi_msc_scsi_sub_callback, and uhi_msc_transfer().

Referenced by uhi_msc_scsi_inquiry(), uhi_msc_scsi_mode_sense6(), uhi_msc_scsi_read_10(), uhi_msc_scsi_read_capacity(), uhi_msc_scsi_request_sense(), uhi_msc_scsi_test_unit_ready(), and uhi_msc_scsi_write_10().

static void uhi_msc_scsi_inquiry ( uhi_msc_scsi_callback_t  callback)
static

Sends the CBW packet of the scsi INQUIRY command.

Parameters
callbackCallback to call at the end of scsi command

References SPC_INQUIRY, uhi_msc_inquiry, uhi_msc_scsi(), uhi_msc_scsi_callback, uhi_msc_scsi_inquiry_done(), and USB_CBW_DIRECTION_IN.

Referenced by uhi_msc_enable_step3().

static void uhi_msc_scsi_inquiry_done ( bool  b_cbw_succes)
static

Call the callback at the end of scsi INQUIRY command.

Parameters
b_cbw_succestrue, if the scsi command is successful

References uhi_msc_scsi_callback.

Referenced by uhi_msc_scsi_inquiry().

static void uhi_msc_scsi_mode_sense6 ( uhi_msc_scsi_callback_t  callback)
static

Sends the CBW packet of the scsi MODE SENSE 6 command This function returns the write-protected mode.

Field optional provided only by the LUN with a write protection feature.

Parameters
callbackCallback to call at the end of scsi command

References SCSI_MS_MODE_INFEXP, SPC_MODE_SENSE6, uhi_msc_scsi(), uhi_msc_scsi_callback, uhi_msc_scsi_mode_sense6_done(), uhi_msc_sense6, and USB_CBW_DIRECTION_IN.

Referenced by uhi_msc_scsi_read_capacity_done().

static void uhi_msc_scsi_mode_sense6_done ( bool  b_cbw_succes)
static

Decodes the result of scsi MODE SENSE 6 command.

Parameters
b_cbw_succestrue, if the scsi command is successful

References uhi_msc_lun_t::b_write_protected, SCSI_MS_SBC_WP, uhi_msc_scsi_callback, uhi_msc_sense6, and USB_CSW_STATUS_PASS.

Referenced by uhi_msc_scsi_mode_sense6().

static void uhi_msc_scsi_read_10_done ( bool  b_cbw_succes)
static

Decodes the result of scsi READ 10 command.

Parameters
b_cbw_succestrue, if the scsi command is successful

References LUN_FAIL, uhi_msc_lun_t::status, uhi_msc_scsi_callback, and USB_CSW_STATUS_PASS.

Referenced by uhi_msc_scsi_read_10().

static void uhi_msc_scsi_read_capacity ( uhi_msc_scsi_callback_t  callback)
static

Sends the CBW packet of the scsi READ CAPACITY command.

Parameters
callbackCallback to call at the end of scsi command

References SBC_READ_CAPACITY10, uhi_msc_capacity, uhi_msc_scsi(), uhi_msc_scsi_callback, uhi_msc_scsi_read_capacity_done(), and USB_CBW_DIRECTION_IN.

Referenced by uhi_msc_enable_step4(), and uhi_msc_scsi_test_unit_ready_done().

static void uhi_msc_scsi_read_capacity_done ( bool  b_cbw_succes)
static
static void uhi_msc_scsi_read_capacity_sense ( void  )
static

Decodes the scsi sense code after a scsi READ CAPACITY command failed.

References uhi_msc_scsi_callback.

Referenced by uhi_msc_scsi_read_capacity_done().

static void uhi_msc_scsi_request_sense ( uhi_msc_scsi_sense_callback_t  callback)
static

Sends the CBW packet of the scsi REQUESRT SENSE command Called by TEST UNIT READY and READ CAPACITY command in case of error.

Parameters
callbackCallback to call at the end of scsi command

References SPC_REQUEST_SENSE, uhi_msc_scsi(), uhi_msc_scsi_request_sense_done(), uhi_msc_scsi_sense_callback, uhi_msc_sense, and USB_CBW_DIRECTION_IN.

Referenced by uhi_msc_scsi_read_capacity_done(), and uhi_msc_scsi_test_unit_ready_done().

static void uhi_msc_scsi_request_sense_done ( bool  b_cbw_succes)
static

Decodes the result of scsi REQUEST SENSE command.

Parameters
b_cbw_succestrue, if the scsi command is successful

References uhi_msc_scsi_callback, and uhi_msc_scsi_sense_callback.

Referenced by uhi_msc_scsi_request_sense().

static void uhi_msc_scsi_test_unit_ready_done ( bool  b_cbw_succes)
static

Decodes the result of scsi TEST UNIT READY command Launches READ CAPACITY command, if a new LUN has been detected.

Parameters
b_cbw_succestrue, if the scsi command is successful

References LUN_BUSY, LUN_FAIL, LUN_GOOD, uhi_msc_lun_t::status, uhi_msc_scsi_callback, uhi_msc_scsi_read_capacity(), uhi_msc_scsi_request_sense(), uhi_msc_scsi_test_unit_ready_sense(), and USB_CSW_STATUS_PASS.

Referenced by uhi_msc_scsi_test_unit_ready().

static void uhi_msc_scsi_write_10_done ( bool  b_cbw_succes)
static

Decodes the result of scsi WRITE 10 command.

Parameters
b_cbw_succestrue, if the scsi command is successful

References LUN_FAIL, uhi_msc_lun_t::status, uhi_msc_scsi_callback, and USB_CSW_STATUS_PASS.

Referenced by uhi_msc_scsi_write_10().

static bool uhi_msc_select_lun ( uint8_t  lun)
static

Selects a LUN.

Parameters
lunLUN number to select
Returns
true, if the LUN number is correct

References uhi_msc_dev_t::lun, uhi_msc_dev_t::nb_lun, and uhi_msc_lun_num_sel.

Referenced by uhi_msc_enable_step3(), uhi_msc_scsi_read_10(), uhi_msc_scsi_test_unit_ready(), and uhi_msc_scsi_write_10().

static void uhi_msc_transfer ( usb_ep_t  endp,
uint8_t *  payload,
uint16_t  payload_size,
uhd_callback_trans_t  callback_end 
)
static

Start a transfer on an endpoint of current USB MSC device Used to send a CBW packet, DATA packet, or a CSW packet.

Parameters
endpEndpoint to use for this transfer
payloadPointer on the data to transfer
payload_sizeSize of the data to transfer
callback_endCallback to call at the end of transfer

References uhc_device_t::address, uhi_msc_dev_t::dev, uhd_ep_run(), uhi_msc_scsi_sub_callback, and UHI_MSC_SCSI_TIMEOUT.

Referenced by uhi_msc_cbw_sent(), uhi_msc_csw_wait(), and uhi_msc_scsi().

struct scsi_mode_param_header6 header
struct spc_control_page_info_execpt sense_data