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) |
Enable the interface. More... | |
void | uhi_msc_uninstall (uhc_device_t *dev) |
Uninstall the interface (if installed). More... | |
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. More... | |
uint8_t | uhi_msc_get_lun (void) |
Gives the number of LUN available. More... | |
uhi_msc_lun_t * | uhi_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. 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. 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_t * | uhi_msc_lun_sel |
Current LUN selected in USB MSC device by the UHI MSC. More... | |
#define UHI_MSC_NOTIFY_NEW_LUN_EXT |
UHC_BSS | ( | 4 | ) |
Structure to send a CBW packet.
|
static |
Manages the end of setup request RESET ENDPOINT after a CBW packet.
add | USB address of the setup request |
status | Transfer status |
payload_trans | Number of data transfered during DATA phase |
References uhi_msc_scsi_sub_callback, and UNUSED.
Referenced by uhi_msc_cbw_sent().
|
static |
Checks the CBW packet transfer and launch the next step The next step can be a DATA phase or a CSW packet.
add | USB address used by the transfer |
status | Transfer status |
nb_transfered | Number 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 |
Checks the CSW packet transfer.
add | USB address used by the transfer |
status | Transfer status |
nb_transfered | Number 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 |
Start the transfer of the CSW packet.
References uhi_msc_dev_t::ep_in, uhi_msc_csw_received(), and uhi_msc_transfer().
Referenced by uhi_msc_cbw_sent(), uhi_msc_data_csw_rst_stall(), and uhi_msc_data_transfered().
|
static |
Manages the end of RESET ENDPOINT request after a DATA or CSW packet.
add | USB address of the setup request |
status | Transfer status |
payload_trans | Number 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 |
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.
add | USB address used by the transfer |
status | Transfer status |
nb_transfered | Number 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 |
Step 1 of the initialization of a USB MSC device Sends the setup request GET_MAX_LUN.
References uhc_device_t::address, usb_setup_req_t::bmRequestType, usb_setup_req_t::bRequest, uhi_msc_dev_t::dev, uhi_msc_dev_t::iface_num, uhi_msc_dev_t::nb_lun, NULL, uhd_setup_request(), uhi_msc_enable_step2(), USB_REQ_DIR_IN, USB_REQ_MSC_GET_MAX_LUN, USB_REQ_RECIP_INTERFACE, USB_REQ_TYPE_CLASS, usb_setup_req_t::wIndex, usb_setup_req_t::wLength, and usb_setup_req_t::wValue.
Referenced by uhi_msc_enable().
|
static |
Step 2 of the initialization of a USB MSC device Decode the setup request GET_MAX_LUN and allocs LUN structures.
add | USB address of the setup request |
status | Transfer status |
payload_trans | Number of data transfered during DATA phase |
References Assert, b_uhi_msc_free, uhi_msc_dev_t::lun, uhi_msc_dev_t::nb_lun, NULL, UHD_TRANS_NOERROR, UHD_TRANS_STALL, uhi_msc_enable_step3(), uhi_msc_lun_num_sel, and UNUSED.
Referenced by uhi_msc_enable_step1().
|
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 |
Step 4 of the initialization of a USB MSC device Sends the SCSI READ CAPACITY request on the current LUN.
b_success | true, 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 |
Step 5 of the initialization of a USB MSC device Go to the initialization of the next LUN.
b_success | true, if the scsi command is successful |
References uhi_msc_enable_step3(), and UNUSED.
Referenced by uhi_msc_enable_step4().
|
static |
Sends a setup request RESET ENDPOINT Used after a STALL received during a scsi command.
endp | Endpoint to reset |
callback_end | Callback to call at the end of request |
References uhc_device_t::address, usb_setup_req_t::bmRequestType, usb_setup_req_t::bRequest, callback, uhi_msc_dev_t::dev, NULL, uhd_setup_request(), UHD_TRANS_DISCONNECT, USB_EP_FEATURE_HALT, USB_REQ_CLEAR_FEATURE, USB_REQ_DIR_OUT, USB_REQ_RECIP_ENDPOINT, USB_REQ_TYPE_STANDARD, usb_setup_req_t::wIndex, usb_setup_req_t::wLength, and usb_setup_req_t::wValue.
Referenced by uhi_msc_cbw_sent(), uhi_msc_csw_received(), and uhi_msc_data_transfered().
|
static |
Sends the CBW packet.
callback | Callback to call at the end of scsi protocol |
payload | Pointer on the data to transfer (Optional) |
References callback, 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 |
Sends the CBW packet of the scsi INQUIRY command.
callback | Callback to call at the end of scsi command |
References callback, 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 |
Call the callback at the end of scsi INQUIRY command.
b_cbw_succes | true, if the scsi command is successful |
References uhi_msc_scsi_callback.
Referenced by uhi_msc_scsi_inquiry().
|
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.
callback | Callback to call at the end of scsi command |
References callback, 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 |
Decodes the result of scsi MODE SENSE 6 command.
b_cbw_succes | true, 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 |
Decodes the result of scsi READ 10 command.
b_cbw_succes | true, 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 |
Sends the CBW packet of the scsi READ CAPACITY command.
callback | Callback to call at the end of scsi command |
References callback, 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 |
Decodes the result of scsi READ CAPACITY command Launches MODE SENSE 6 command.
b_cbw_succes | true, if the scsi command is successful |
References be32_to_cpu, sbc_read_capacity10_data::block_len, uhi_msc_lun_t::capacity, LUN_FAIL, sbc_read_capacity10_data::max_lba, uhi_msc_lun_t::status, uhi_msc_capacity, uhi_msc_scsi_callback, uhi_msc_scsi_mode_sense6(), uhi_msc_scsi_read_capacity_sense(), uhi_msc_scsi_request_sense(), and USB_CSW_STATUS_PASS.
Referenced by uhi_msc_scsi_read_capacity().
|
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 |
Sends the CBW packet of the scsi REQUESRT SENSE command Called by TEST UNIT READY and READ CAPACITY command in case of error.
callback | Callback to call at the end of scsi command |
References callback, 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 |
Decodes the result of scsi REQUEST SENSE command.
b_cbw_succes | true, 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 |
Decodes the result of scsi TEST UNIT READY command Launches READ CAPACITY command, if a new LUN has been detected.
b_cbw_succes | true, 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 |
Decodes the scsi sense code after an error on TEST UNIT READY command.
References scsi_request_sense_data::AddSenseCode, scsi_request_sense_data::AddSnsCodeQlfr, if(), LUN_BUSY, LUN_NOT_PRESENT, SCSI_ASC_MEDIUM_NOT_PRESENT, SCSI_ASC_NOT_READY_TO_READY_CHANGE, SCSI_SENSE_CURRENT, SCSI_SENSE_RESPONSE_CODE_MASK, SCSI_SK_NOT_READY, SCSI_SK_UNIT_ATTENTION, scsi_request_sense_data::sense_flag_key, uhi_msc_lun_t::status, uhi_msc_scsi_callback, uhi_msc_sense, and scsi_request_sense_data::valid_reponse_code.
Referenced by uhi_msc_scsi_test_unit_ready_done().
|
static |
Decodes the result of scsi WRITE 10 command.
b_cbw_succes | true, 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 |
Selects a LUN.
lun | LUN number to select |
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 |
Start a transfer on an endpoint of current USB MSC device Used to send a CBW packet, DATA packet, or a CSW packet.
endp | Endpoint to use for this transfer |
payload | Pointer on the data to transfer |
payload_size | Size of the data to transfer |
callback_end | Callback 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 |
Referenced by _eeprom_emulator_move_data_to_spare(), _rww_eeprom_emulator_move_data_to_spare(), appCmdHandle(), appCmdUartProcess(), main_extra_string(), MQTTDeserialize_ack(), MQTTDeserialize_connack(), MQTTDeserialize_connect(), MQTTDeserialize_publish(), MQTTDeserialize_suback(), MQTTDeserialize_subscribe(), MQTTDeserialize_unsubscribe(), MQTTFormat_toClientString(), MQTTFormat_toServerString(), MQTTPacket_read(), MQTTPacket_readnb(), MQTTSerialize_ack(), MQTTSerialize_connack(), MQTTSerialize_connect(), MQTTSerialize_publish(), MQTTSerialize_suback(), MQTTSerialize_subscribe(), MQTTSerialize_unsuback(), MQTTSerialize_unsubscribe(), MQTTSerialize_zero(), nwkRxHandleReceivedFrame(), nwkRxIndicateFrame(), nwkTxFrame(), platform_interface_callback(), readPacket(), and serial_bridge_process_frame().
struct spc_control_page_info_execpt sense_data |