/******************************************************************************* * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * PolarFire SoC MSS USB Host logical driver layer Implementation. * * PolarFire SoC MSS USB Driver Stack * USB Logical Layer (USB-LL) * USBH-MSC class driver. * * USBH-MSC driver public API. * */ /*=========================================================================*//** @mainpage PolarFire SoC MSS USB driver (USBH-MSC) ============================================================================== Introduction ============================================================================== The Mass Storage Class host driver implements the USB host controller as per the USB MSC class specified by the USB-IF. This driver enables easy detection and data transfers with the attached USB mass storage devices. This driver implements the MSC class using Bulk Only transport (BOT). One BULK IN and one BULK OUT endpoints are used to implement BOT. This MSC class host supports one LUN. This driver uses the USBH driver interface functions to implement the USB MSC host. This host controller will be able to work with all the USB flash drives which fall in "Memory stick" category. ============================================================================== Theory of Operation ============================================================================== The following steps are involved in the operation of USBH-MSC driver: - Configuration - Initialization - Enumeration - Class Specific requests - Data transfer -------------------------------- Configuration -------------------------------- The MSS USB driver must first be configured in the USB Host mode using the MSS_USB_HOST_MODE to use this driver. No other configuration is necessary. -------------------------------- Initialization -------------------------------- The MSC class driver must be initialized using the MSS_USBH_MSC_init() function. A pointer to the structure of type mss_usbh_msc_user_cb_t must be provided as parameter with this function. This pointer is used to call the application call-back functions by the USBH-MSC driver. These call-back functions can be used by the application to provide error/status messages to the user or for performing application specific handling of the events. -------------------------------- Class Specific requests -------------------------------- The class specific requests are handled internally by this driver. Both the GET_MAX_LUN and the RESET_RECOVERY requests are supported. The GET_MAX_LUN request is executed after the enumeration process to find out the number of LUNs on the attached device. This driver supports one LUN (index 0). -------------------------------- Application call-back interface -------------------------------- After the USBH-Class driver is assigned to the attached device by the USBH driver, as indicated by usbh_class_allocate call-back, this driver can take over the communication with the attached device. This driver will then extend the enumeration process by requesting the class specific information from the device. During this process it will also call the call-back functions to indicate the progress of the enumeration process. These call-back functions must be implemented by application. These call-back functions can be used to take application specific action on specific event or can be used to provide error/status messages to the user. A type mss_usbh_msc_user_cb_t is provided by this driver which has all these call-back functions as its elements. Implementing these call-back functions is optional. | Element | Call-back Event | |----------------------------------------|-----------------------------------| | void (*msch_valid_config)(void) | Called to indicate that a valid | | | MSC class configuration was found | | | on the attached device and the | | | device is configured for this | | | configuration. | | | | | void (*msch_tdev_ready)(void) | Called when this driver is able | | | to retrieve all the MSC class | | | specific info (including sector | | | size and sector number) from the | | | attached device and is ready to | | | perform data transfers. | | | | | void (*msch_driver_released)(void) | Called to indicate to the | | | application that this driver is | | | released by the USBH driver | | | | | void (*msch_error)(int8_t error_code) | Called to indicate that there was | | | an error while retrieving the | | | class specific descriptor | | | information from the attached MSC | | | class device. | -------------------------------- Data transfer -------------------------------- The MSC class driver performs the data transfers using one BULK IN endpoint and one BULK OUT endpoint. The data transfers use transparent SCSI commands and follow the BoT specification. The BoT read/write operations happen on logical units of fixed block size. During initialization this driver takes care of finding all information about the attached device. The MSS_USBH_MSC_get_sector_count() and MSS_USBH_MSC_get_sector_size() functions can be used to find out the sector count and the sector size on the attached MSC class device. Most of the times the read (READ_10) and write (WRITE_10) are the only SCSI operations that the application needs to do. The MSS_USBH_MSC_read() and MSS_USBH_MSC_write() functions are provided for this purpose. The application can use the MSS_USBH_MSC_scsi_req() function if it needs to perform any other SCSI operation. This function can be used for READ_10 and WRITE_10 commands as well. Once the SCSI request is initiated using any of the above functions, the MSS_USBH_MSC_is_scsi_req_complete() function can be used to find out when the operation is complete. The USBH driver supports multi-packet Bulk transfers. The USBH-MSC driver makes full use of this feature by passing on the multi-sector transfers from the application to the USBH driver. To free up the application from transferring data to/from MSS USB FIFO, this driver can configure USBH driver to use the MSS USB internal DMA. The MSS_USBH_MSC_construct_cbw_cb10byte() and MSS_USBH_MSC_construct_cbw_cb6byte() functions are provided so that the user can easily prepare the CBW format buffer by providing appropriate parameters instead of manually creating the CBW command buffer. *//*=========================================================================*/ #ifndef __MSS_USB_HOST_MSC_H_ #define __MSS_USB_HOST_MSC_H_ #include #include "mss_usb_config.h" #ifdef __cplusplus extern "C" { #endif #ifdef MSS_USB_HOST_ENABLED /*-------------------------------------------------------------------------*//** Types exported from USBH-MSC driver ============================ */ /*-------------------------------------------------------------------------*//** The mss_usbh_msc_err_code_t provides a type to identify the error occurred during retrieving configuration and other class specific descriptors from the attached MSC class device. This type can be used with msch_error call-back function element of mss_usbh_msc_user_cb_t type to identify the exact cause of the error. The meaning of the constants is as described below | Value | Description | |----------------------------- |----------------------------------------------| | USBH_MSC_EP_NOT_VALID | Indicates that the endpoint information | | | retrieved from the attached device was not | | | consistent with the MSC class. | | | | | USBH_MSC_CLR_CEP_STALL_ERROR | Indicates that the host controller was not | | | able to clear the stall condition on the | | | attached device even after multiple retries. | | | | | USBH_MSC_SECTOR_SIZE_NOT_ | Indicates that the attached device sector | | SUPPORTED | size is not supported by this driver. | */ typedef enum { USBH_MSC_NO_ERROR = 0, USBH_MSC_EP_NOT_VALID = -1, USBH_MSC_CLR_CEP_STALL_ERROR = -2, USBH_MSC_SECTOR_SIZE_NOT_SUPPORTED = -3, USBH_MSC_WRONG_DESCR = -4, } mss_usbh_msc_err_code_t; /*-------------------------------------------------------------------------*//** The mss_usbh_msc_state_t provides a type for the states of operation of the USBH-MSC driver. Most of the states are internally used by the USBH-MSC driver during the enumeration process. The USBH-MSC driver is ready to perform data transfers with the attached device when the driver is in state USBH_MSC_DEVICE_READY. The USBH_MSC_ERROR state indicates that the error was detected either during enumeration or during the normal data transfer operations with the attached device even after retries. */ typedef enum { USBH_MSC_IDLE, USBH_MSC_GET_CLASS_DESCR, USBH_MSC_WAIT_GET_CLASS_DESCR, USBH_MSC_SET_CONFIG, USBH_MSC_WAIT_SET_CONFIG, USBH_MSC_WAIT_DEV_SETTLE, USBH_MSC_GET_MAX_LUN, USBH_MSC_WAIT_GET_MAX_LUN, USBH_MSC_CLR_CEP_STALL, USBH_MSC_WAIT_CLR_CEP_STALL, USBH_MSC_CONFIG_BULK_ENDPOINTS, USBH_MSC_TEST_UNIT_READY_CPHASE, USBH_MSC_TEST_UNIT_READY_SPHASE, USBH_MSC_TEST_UNIT_READY_WAITCOMPLETE, USBH_MSC_SCSI_INQUIRY_CPHASE, USBH_MSC_SCSI_INQUIRY_DPHASE, USBH_MSC_SCSI_INQUIRY_SPHASE, USBH_MSC_SCSI_INQUIRY_WAITCOMPLETE, USBH_MSC_SCSI_REQSENSE_CPHASE, USBH_MSC_SCSI_REQSENSE_DPHASE, USBH_MSC_SCSI_REQSENSE_SPHASE, USBH_MSC_SCSI_REQSENSE_WAITCOMPLETE, USBH_MSC_SCSI_READ_CAPACITY_CPHASE, USBH_MSC_SCSI_READ_CAPACITY_DPHASE, USBH_MSC_SCSI_READ_CAPACITY_SPHASE, USBH_MSC_SCSI_READ_CAPACITY_WAITCOMPLETE, USBH_MSC_DEVICE_READY, USBH_MSC_BOT_RETRY, USBH_MSC_ERROR } mss_usbh_msc_state_t; /*----------------------------------------------------------------------------*/ /*---------------Data structures exported by USBH-MSC driver ---------------*/ /*----------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*//** The mss_usbh_msc_user_cb_t provides the prototype for all the call-back functions which must be implemented by the user application. The user application must define and initialize a structure of this type and provide the address of that structure as parameter to the MSS_USBH_MSC_init() function. msch_valid_config The function pointed by the msch_valid_config function pointer will be called to indicate that a valid MSC class configuration was found on the attached device and the device is configured for this configuration. msch_tdev_ready The function pointed by the msch_tdev_ready function pointer is called when this driver is able to retrieve all the MSC class specific information (including sector size and sector number) from the attached device and is ready to perform the data transfers. msch_driver_released The function pointed by the msch_driver_released function pointer is called to indicate to the application that this driver is released by the USBH driver. This could be either because the MSC class device is now detached or there is permanent error with the USBH driver. msch_error The function pointed by the msch_error function pointer is called to indicate that there was an error while retrieving the class specific descriptor information from the attached MSC class device. The error_code parameter indicates the exact cause of the error. */ typedef struct mss_usbh_msc_user_cb { void (*msch_valid_config)(void); void (*msch_tdev_ready)(void); void (*msch_driver_released)(void); void (*msch_error)(int8_t error_code); } mss_usbh_msc_user_cb_t; /*-------------------------------------------------------------------------*//** The msd_cbw_t type provides the prototype for the Command Block Wrapper (CBW) as defined in Universal Serial Bus Mass Storage Class Bulk-Only Transport Revision 1.0. This type can be used by the application to create buffer of this type for creating the CBW which can then be passed on to functions provided by this driver as parameter. dCBWSignature Signature that helps identify this data packet as a CBW. The signature field shall contain the value 43425355h (little endian), indicating a CBW. dCBWTag A Command Block Tag sent by the host. The device shall echo the contents of this field back to the host in the dCSWTagfield of the associated CSW. The dCSWTagpositively associates a CSW with the corresponding CBW. dCBWDataTransferLength The number of bytes of data that the host expects to transfer on the Bulk-In or Bulk-Out endpoint (as indicated by the Direction-bit) during the execution of this command. If this field is zero, the device and the host shall transfer no data between the CBW and the associated CSW, and the device shall ignore the value of the Direction-bit in bmCBWFlags. bCBWFlags The bits of this field are defined as follows: | Bit | Description | |------------|-------------------------------------------------------------| | Bit 7 | Direction- the device shall ignore this bit if the | | | dCBWDataTransferLengthfield is zero, otherwise: | | | 0 = Data-Out from host to the device, | | | 1 = Data-In from the device to the host. | | | | | Bit 6 | Obsolete. The host shall set this bit to zero. | | Bits 5..0 | Reserved - the host shall set these bits to zero. | bCBWLUN The device Logical Unit Number (LUN) to which the command block is being sent. For devices that support multiple LUNs, the host shall place into this field the LUN to which this command block is addressed. Otherwise, the host shall set this field to zero. bCBWCBLength The valid length of the CBWCBin bytes. This defines the valid length of the command block. The only legal values are 1 through 16 (01h through 10h). All other values are reserved. CBWCB[16] The command block to be executed by the device. The device shall interpret the first bCBWCBLength bytes in this field as a command block as defined by the command set identified by bInterfaceSubClass. If the command set supported by the device uses command blocks of fewer than 16 (10h) bytes in length, the significant bytes shall be transferred first, beginning with the byte at offset 15 (0Fh). The device shall ignore the content of the CBWCBfield past the byte at offset (15 + bCBWCBLength- 1) */ typedef struct { uint32_t dCBWSignature; uint32_t dCBWTag; uint32_t dCBWDataTransferLength; uint8_t bCBWFlags; uint8_t bCBWLUN; uint8_t bCBWCBLength; uint8_t CBWCB[16]; } msd_cbw_t; /*-------------------------------------------------------------------------*//** The msd_csw_t type provides the prototype for the Command Status Wrapper (CSW) as defined in Universal Serial Bus Mass Storage Class Bulk-Only Transport Revision 1.0. This type can be used by application to create buffer of this type for creating CSW which can then be passed on to APIs provided by this driver as parameter. dCSWSignature Signature that helps identify this data packet as a CSW. The signature field shall contain the value 53425355h (little endian), indicating CSW. dCSWTag The device shall set this field to the value received in the dCBWTag of the associated CBW. dCSWDataResidue For Data-Out the device shall report in the dCSWDataResiduethe difference between the amount of data expected as stated in the dCBWDataTransferLength, and the actual amount of data processed by the device. For Data-In the device shall report in the dCSWDataResiduethe difference between the amount of data expected as stated in the dCBWDataTransferLengthand the actual amount of relevant data sent by the device. The dCSWDataResidueshall not exceed the value sent in the dCBWDataTransferLength. dCSWStatus bCSWStatusindicates the success or failure of the command. The device shall set this byte to zero if the command completed successfully. A non-zero value shall indicate a failure during command execution according to the following table: | Value | Description | |----------------------|---------------------------------------| | 00h | Command Passed ("good status") | | 01h | Command Failed | | 02h | Phase Error | | 03h and 04h | Reserved (Obsolete) | | 05h to FFh | Reserved */ typedef struct { uint32_t dCSWSignature; uint32_t dCSWTag; uint32_t dCSWDataResidue; uint32_t dCSWStatus; } msd_csw_t; /*-------------------------------------------------------------------------*//** EXPORTED APIs from USBH-MSC driver ============================ */ /*-------------------------------------------------------------------------*//** The MSS_USBH_MSC_init() function must be used by the application to initialize the USBH-MSC driver. This function must be called before any other function of the USBH-MSC driver. @param user_cb The user_cb parameter provides a pointer to the structure of type mss_usbh_msc_user_cb_t. This pointer is used to call the application call-back functions by the USBH-MSC driver. These call-back functions can be used by the application to provide error/status messages to the user or for performing the application specific handling of the events. @return This function does not return a value. Example: @code Initialize the USBH driver MSS_USBH_init(&MSS_USBH_user_cb); Initialize the USBH-MSC driver MSS_USBH_MSC_init(&MSS_USBH_MSC_user_cb); Get Class driver handle from the USBH-MSC class driver and register it with the USBH driver. On Device attachment, USBH driver will look for Device information through Descriptors and if match it with the Class driver using this Handle. MSS_USBH_register_class_driver(MSS_USBH_MSC_get_handle()); @endcode */ void MSS_USBH_MSC_init ( mss_usbh_msc_user_cb_t* user_sb ); /*-------------------------------------------------------------------------*//** The MSS_USBH_MSC_task() function is the main task of the USBH-MSC driver. This function monitors the events from the USBH driver as well as the user application and makes decisions. This function must be called repeatedly by the application to allow the USBH-MSC driver to perform the housekeeping tasks. A timer/scheduler can be used to call this function at regular intervals or it can be called from the main continuous foreground loop of the application. @param This function does not take any parameters. @return This function does not return a value. Example: @code #define SYS_TICK_LOAD_VALUE 48000u int main() { Initialize SysTick SysTick_Config(SYS_TICK_LOAD_VALUE); NVIC_EnableIRQ(SysTick_IRQn); } void SysTick_Handler(void) { MSS_USBH_MSC_task(); } @endcode */ void MSS_USBH_MSC_task ( void ); /*-------------------------------------------------------------------------*//** The MSS_USBH_MSC_get_handle() function must be used by the application to get the handle from the USBH-MSC driver. This handle must then be used to register this driver with the USBH driver. @param This function does not take any parameters. @return This function returns a pointer to the class-handle structure. Example: @code MSS_USBH_init(&MSS_USBH_user_cb); MSS_USBH_MSC_init(&MSS_USBH_MSC_user_cb); MSS_USBH_register_class_driver(MSS_USBH_MSC_get_handle()); @endcode */ void* MSS_USBH_MSC_get_handle ( void ); /*-------------------------------------------------------------------------*//** The MSS_USBH_MSC_get_state() function can be used to find out the current state of the USBH-MSC driver. This information can be used by the application to check the readiness of the USBH-MSC driver to start the data transfers. The USBH-MSC driver can perform data transfers only when it is in the USBH_MSC_DEVICE_READY state. @param This function does not take any parameters. @return This function returns a value of type mss_usbh_msc_state_t indicating the current state of the USBH-MSC driver. Example: @code if(USBH_MSC_DEVICE_READY == MSS_USBH_MSC_get_state()) { *result = MSS_USBH_MSC_get_sector_count(); return RES_OK; } else if(USBH_MSC_DEVICE_READY < MSS_USBH_MSC_get_state()) { *result = 0u; return RES_NOTRDY; } @endcode */ mss_usbh_msc_state_t MSS_USBH_MSC_get_state ( void ); /*-------------------------------------------------------------------------*//** The MSS_USBH_MSC_read() function can be used to read data from the attached mass storage device. This is a non-blocking function. The function prepares the MSS USB for the USB IN transfer. Once prepared, the MSS USB will start this IN transfer depending on the configuration of the IN pipe on which this transfer is occurring. The USBH-MSC driver takes care of the allocation and configuration of the IN pipe during enumeration process depending on the attached mass storage device. After preparing the IN pipe for the IN transfer, the MSS_USBH_MSC_is_scsi_req_complete() function can be used to find out the completion of the transfer. @param buf The buf parameter is a pointer to the buffer where the data received in the IN transfer from the attached MSC class device is stored. @param sector The sector parameter indicates the sector number (logical block address) on the mass storage device starting from which the data is to be read. @param count The count parameter indicates the number of sectors to be read. @return This function returns a zero value when execution was successful. Example: @code DRESULT disk_read (BYTE drv, BYTE *buff, DWORD sector, BYTE count) { if (0u != drv) return(RES_ERROR); if (USBH_MSC_DEVICE_READY < MSS_USBH_MSC_get_state()) { return(RES_NOTRDY); } else if (USBH_MSC_DEVICE_READY == MSS_USBH_MSC_get_state()) { MSS_USBH_MSC_read(buff, sector, count); while (MSS_USBH_MSC_is_scsi_req_complete()); return (RES_OK); } else return (RES_ERROR); } @endcode */ int8_t MSS_USBH_MSC_read ( uint8_t* buf, uint32_t sector, uint32_t count ); /*-------------------------------------------------------------------------*//** The MSS_USBH_MSC_write() function can be used to write data to the attached mass storage device. This is a non-blocking function. The function readies the MSS USB for the USB OUT transfer. Once ready, the MSS USB will start this OUT transfer depending on the configuration of the OUT pipe on which this transfer is occurring. The USBH-MSC driver takes care of the allocation and configuration of the OUT pipe during enumeration process depending on the attached mass storage device. After starting the OUT transfer on the specified OUT pipe, the MSS_USBH_MSC_is_scsi_req_complete() function can be used to find out the completion of the transfer. @param buf The buf parameter is a pointer to the buffer from which data need to be transmitted to the attached MSC class device. @param sector The sector parameter indicates the sector number (logical block address) on the mass storage device starting from which the data is to be written. @param count The count parameter indicates the number of sectors to be written. @return This function returns a zero value when execution was successful. Example: @code DRESULT disk_write (BYTE pdrv, const BYTE *buff, DWORD sector, BYTE count) { if (0u != pdrv) return(RES_ERROR); if (USBH_MSC_DEVICE_READY < MSS_USBH_MSC_get_state()) { return(RES_NOTRDY); } else if (USBH_MSC_DEVICE_READY == MSS_USBH_MSC_get_state()) { MSS_USBH_MSC_write((uint8_t*)buff, sector, count); while (MSS_USBH_MSC_is_scsi_req_complete()); return (RES_OK); } else return (RES_ERROR); } @endcode */ int8_t MSS_USBH_MSC_write ( uint8_t* buf, uint32_t sector, uint32_t count ); /*-------------------------------------------------------------------------*//** The MSS_USBH_MSC_get_sector_count() function can be used to find out the number of sectors (logical blocks) available on the attached MSC class device. @param This function does not take any parameters. @return This function returns a value of type uint32_t indicating the number of sectors (logical blocks) available on the attached MSC class device. Example: @code DRESULT disk_ioctl ( BYTE pdrv, BYTE ctrl, void *buff) ) { UINT *result = (UINT *)buff; switch (ctrl) { case GET_SECTOR_COUNT: if (USBH_MSC_DEVICE_READY == MSS_USBH_MSC_get_state()) { *result = MSS_USBH_MSC_get_sector_count(); return RES_OK; } else if (USBH_MSC_DEVICE_READY < MSS_USBH_MSC_get_state()) { *result = 0u; return RES_NOTRDY; } else { *result = 0u; return RES_ERROR; } break; default: return RES_NOTRDY; } } @endcode */ uint32_t MSS_USBH_MSC_get_sector_count ( void ); /*-------------------------------------------------------------------------*//** The MSS_USBH_MSC_get_sector_size() function can be used to find out the size of a sector (in bytes) on the attached MSC class device. @param This function does not take any parameters. @return This function returns a value of type uint32_t indicating the sector size (in bytes) on the attached MSC class device. Example: @code DRESULT disk_ioctl ( BYTE pdrv, BYTE ctrl, void *buff ) { UINT *result = (UINT *)buff; switch (ctrl) { case GET_SECTOR_SIZE: if(USBH_MSC_DEVICE_READY == MSS_USBH_MSC_get_state()) { *result = MSS_USBH_MSC_get_sector_size(); return RES_OK; } else if(USBH_MSC_DEVICE_READY < MSS_USBH_MSC_get_state()) { *result = 0u; return RES_NOTRDY; } else { *result = 0u; return RES_ERROR; } break; default: return RES_NOTRDY; } } @endcode */ uint32_t MSS_USBH_MSC_get_sector_size ( void ); /*-------------------------------------------------------------------------*//** The MSS_USBH_MSC_construct_cbw_cb10byte() function can be used to create the SCSI request command block wrapper (CBW) as per MSC class which has command block(CB) of length 10bytes. @param command_opcode The command_opcode parameter provides the transparent SCSI command code. @param lun The lun parameter indicates the logical unit number on the attached MSC class device. @param lb_addr The lb_addr parameter provides the logical block address on which the operation indicated by the command_opcode parameter is applicable. For the commands where logical block address is not applicable, a zero value must be provided. @param num_of_lb The num_of_addr parameter provides the number of logical blocks on which the operation indicated by the command_opcode parameter is applicable. For the commands where logical block address is not applicable, a zero value must be provided. @param lb_size The lb_size parameter provides the size of the logical block on the attached MSC class device. @param buf The buf parameter provides the pointer to the buffer where the formatted SCSI command is to be stored. @return This function does not return any value. Example: @code int8_t MSS_USBH_MSC_read(uint8_t* buf, uint32_t sector, uint32_t count) { MSS_USBH_MSC_construct_cbw_cb10byte(USB_MSC_SCSI_READ_10, 0u, sector, count, 512u, &g_bot_cbw); MSS_USBH_MSC_scsi_req((uint8_t*)&g_bot_cbw, buf, (count*512u), (uint8_t*)&g_bot_csw); return(0); } @endcode */ void MSS_USBH_MSC_construct_cbw_cb10byte ( uint8_t command_opcode, uint8_t lun, uint32_t lb_addr, uint16_t num_of_lb, uint16_t lb_size, msd_cbw_t* buf ); /*-------------------------------------------------------------------------*//** The MSS_USBH_MSC_construct_cbw_cb6byte() function can be used to create the SCSI request command block wrapper (CBW) as per MSC class which has command block(CB) of length 6 bytes. @param command_opcode The command_opcode parameter provides the transparent SCSI command code. @param xfr_length The xfr_length parameter provides the number of bytes to be transferred in the data phase of the command. @param buf The buf parameter provides the pointer to the buffer where the formatted SCSI command is to be stored. @return This function does not return any value. Example: @code MSS_USBH_MSC_construct_cbw_cb6byte(USB_MSC_SCSI_TEST_UNIT_READY, 0u, &g_bot_cbw); MSS_USBH_write_out_pipe(g_msd_tdev_addr, USBH_MSC_BULK_TX_PIPE, g_tdev_out_ep.num, g_tdev_out_ep.maxpktsz, (uint8_t*)&g_bot_cbw, 31u); @endcode */ void MSS_USBH_MSC_construct_cbw_cb6byte ( uint8_t command_opcode, uint32_t data_xfr_len, msd_cbw_t* buf ); /*-------------------------------------------------------------------------*//** The MSS_USBH_MSC_scsi_req() function can be used to execute any SCSI command required by the MSC class on the attached MSC device. In most cases using the MSS_USBH_MSC_write() and MSS_USBH_MSC_read() functions is enough for the application. However, if the application wants to execute other SCSI commands it can use the MSS_USBH_MSC_scsi_req() function. This function can be used as alternative to MSS_USBH_MSC_write() and MSS_USBH_MSC_read() functions. The MSS_USBH_MSC_is_scsi_req_complete() function can be used to find out when the transfer started using this function is complete. @param command_buf The command_buf parameter provides the pointer to the buffer where the SCSI command (CBW format) to be executed is stored. @param data_buf The data_buf parameter provides the pointer to the data buffer which is to be used in the data phase of the command. This parameter is the source of the data when the data direction is from the host to the device. This parameter is the destination for the data when the data direction is from the device to the host. This function extracts the data direction from the CBW format command provided using command_buf parameter. @param data_buf_len The data_buf_len parameter indicates the number of bytes to be transferred in the data phase of the current command. @param status_buf The status_buf parameter provides the pointer to the buffer where the status (CSW format) received from the attached MSC device for the current SCSI operation is to be stored. @return This function returns zero value when successfully executed. Example: @code int8_t MSS_USBH_MSC_read ( uint8_t* buf, uint32_t sector, uint32_t count ) { MSS_USBH_MSC_construct_cbw_cb10byte(USB_MSC_SCSI_READ_10, 0u, sector, count, 512u, &g_bot_cbw); MSS_USBH_MSC_scsi_req((uint8_t*)&g_bot_cbw, buf, (count*512u), (uint8_t*)&g_bot_csw); return(0); } @endcode */ uint8_t MSS_USBH_MSC_scsi_req ( uint8_t* command_buf, /* always31bytes */ uint8_t* data_buf, uint32_t data_buf_len, uint8_t* status_buf /* status always 13bytes */ ); /*-------------------------------------------------------------------------*//** The MSS_USBH_MSC_is_scsi_req_complete() function must be used to find out whether the SCSI request initiated using MSS_USBH_MSC_scsi_req() or MSS_USBH_MSC_read() or MSS_USBH_MSC_write() function is complete. @param This function does not take any parameters. @return This function returns zero value when the current command is completed. Example: @code MSS_USBH_MSC_write((uint8_t*)buff, sector, count); while (MSS_USBH_MSC_is_scsi_req_complete()); return (RES_OK); @endcode */ uint8_t MSS_USBH_MSC_is_scsi_req_complete ( void ); #endif /* MSS_USB_HOST_ENABLED */ #ifdef __cplusplus } #endif #endif /* __MSS_USB_HOST_MSC_H_ */