1 /******************************************************************************* 2 * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions. 3 * 4 * SPDX-License-Identifier: MIT 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to 8 * deal in the Software without restriction, including without limitation the 9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 * sell copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 * IN THE SOFTWARE. 23 * 24 * PolarFire SoC MSS USB Host logical driver layer Implementation. 25 * 26 * PolarFire SoC MSS USB Driver Stack 27 * USB Logical Layer (USB-LL) 28 * USBH-MSC class driver. 29 * 30 * USBH-MSC driver public API. 31 * 32 */ 33 34 /*=========================================================================*//** 35 @mainpage PolarFire SoC MSS USB driver (USBH-MSC) 36 37 ============================================================================== 38 Introduction 39 ============================================================================== 40 The Mass Storage Class host driver implements the USB host controller as per 41 the USB MSC class specified by the USB-IF. This driver enables easy detection 42 and data transfers with the attached USB mass storage devices. 43 44 This driver implements the MSC class using Bulk Only transport (BOT). One 45 BULK IN and one BULK OUT endpoints are used to implement BOT. This MSC class 46 host supports one LUN. 47 48 This driver uses the USBH driver interface functions to implement the USB MSC 49 host. This host controller will be able to work with all the USB flash drives 50 which fall in "Memory stick" category. 51 52 ============================================================================== 53 Theory of Operation 54 ============================================================================== 55 The following steps are involved in the operation of USBH-MSC driver: 56 - Configuration 57 - Initialization 58 - Enumeration 59 - Class Specific requests 60 - Data transfer 61 62 -------------------------------- 63 Configuration 64 -------------------------------- 65 The MSS USB driver must first be configured in the USB Host mode using the 66 MSS_USB_HOST_MODE to use this driver. No other configuration is necessary. 67 68 -------------------------------- 69 Initialization 70 -------------------------------- 71 The MSC class driver must be initialized using the MSS_USBH_MSC_init() function. 72 A pointer to the structure of type mss_usbh_msc_user_cb_t must be provided as 73 parameter with this function. This pointer is used to call the application 74 call-back functions by the USBH-MSC driver. These call-back functions can be 75 used by the application to provide error/status messages to the user or for 76 performing application specific handling of the events. 77 78 -------------------------------- 79 Class Specific requests 80 -------------------------------- 81 The class specific requests are handled internally by this driver. Both the 82 GET_MAX_LUN and the RESET_RECOVERY requests are supported. The GET_MAX_LUN 83 request is executed after the enumeration process to find out the number of 84 LUNs on the attached device. This driver supports one LUN (index 0). 85 86 -------------------------------- 87 Application call-back interface 88 -------------------------------- 89 After the USBH-Class driver is assigned to the attached device by the USBH 90 driver, as indicated by usbh_class_allocate call-back, this driver can take 91 over the communication with the attached device. This driver will then extend 92 the enumeration process by requesting the class specific information from the 93 device. During this process it will also call the call-back functions to 94 indicate the progress of the enumeration process. These call-back functions 95 must be implemented by application. These call-back functions can be used to 96 take application specific action on specific event or can be used to provide 97 error/status messages to the user. A type mss_usbh_msc_user_cb_t is provided 98 by this driver which has all these call-back functions as its elements. 99 Implementing these call-back functions is optional. 100 101 | Element | Call-back Event | 102 |----------------------------------------|-----------------------------------| 103 | void (*msch_valid_config)(void) | Called to indicate that a valid | 104 | | MSC class configuration was found | 105 | | on the attached device and the | 106 | | device is configured for this | 107 | | configuration. | 108 | | | 109 | void (*msch_tdev_ready)(void) | Called when this driver is able | 110 | | to retrieve all the MSC class | 111 | | specific info (including sector | 112 | | size and sector number) from the | 113 | | attached device and is ready to | 114 | | perform data transfers. | 115 | | | 116 | void (*msch_driver_released)(void) | Called to indicate to the | 117 | | application that this driver is | 118 | | released by the USBH driver | 119 | | | 120 | void (*msch_error)(int8_t error_code) | Called to indicate that there was | 121 | | an error while retrieving the | 122 | | class specific descriptor | 123 | | information from the attached MSC | 124 | | class device. | 125 126 -------------------------------- 127 Data transfer 128 -------------------------------- 129 The MSC class driver performs the data transfers using one BULK IN endpoint 130 and one BULK OUT endpoint. The data transfers use transparent SCSI commands 131 and follow the BoT specification. The BoT read/write operations happen on 132 logical units of fixed block size. During initialization this driver takes 133 care of finding all information about the attached device. The 134 MSS_USBH_MSC_get_sector_count() and MSS_USBH_MSC_get_sector_size() functions 135 can be used to find out the sector count and the sector size on the attached 136 MSC class device. 137 138 Most of the times the read (READ_10) and write (WRITE_10) are the only SCSI 139 operations that the application needs to do. The MSS_USBH_MSC_read() and 140 MSS_USBH_MSC_write() functions are provided for this purpose. The application 141 can use the MSS_USBH_MSC_scsi_req() function if it needs to perform any other 142 SCSI operation. This function can be used for READ_10 and WRITE_10 commands as 143 well. Once the SCSI request is initiated using any of the above functions, 144 the MSS_USBH_MSC_is_scsi_req_complete() function can be used to find out when 145 the operation is complete. 146 147 The USBH driver supports multi-packet Bulk transfers. The USBH-MSC driver makes 148 full use of this feature by passing on the multi-sector transfers from the 149 application to the USBH driver. To free up the application from transferring 150 data to/from MSS USB FIFO, this driver can configure USBH driver to use the 151 MSS USB internal DMA. 152 153 The MSS_USBH_MSC_construct_cbw_cb10byte() and MSS_USBH_MSC_construct_cbw_cb6byte() 154 functions are provided so that the user can easily prepare the CBW format 155 buffer by providing appropriate parameters instead of manually creating the 156 CBW command buffer. 157 158 *//*=========================================================================*/ 159 160 #ifndef __MSS_USB_HOST_MSC_H_ 161 #define __MSS_USB_HOST_MSC_H_ 162 163 #include <stdint.h> 164 #include "mss_usb_config.h" 165 166 #ifdef __cplusplus 167 extern "C" { 168 #endif 169 170 #ifdef MSS_USB_HOST_ENABLED 171 172 /*-------------------------------------------------------------------------*//** 173 Types exported from USBH-MSC driver 174 ============================ 175 */ 176 /*-------------------------------------------------------------------------*//** 177 The mss_usbh_msc_err_code_t provides a type to identify the error occurred 178 during retrieving configuration and other class specific descriptors from the 179 attached MSC class device. This type can be used with msch_error call-back 180 function element of mss_usbh_msc_user_cb_t type to identify the exact cause 181 of the error. The meaning of the constants is as described below 182 183 | Value | Description | 184 |----------------------------- |----------------------------------------------| 185 | USBH_MSC_EP_NOT_VALID | Indicates that the endpoint information | 186 | | retrieved from the attached device was not | 187 | | consistent with the MSC class. | 188 | | | 189 | USBH_MSC_CLR_CEP_STALL_ERROR | Indicates that the host controller was not | 190 | | able to clear the stall condition on the | 191 | | attached device even after multiple retries. | 192 | | | 193 | USBH_MSC_SECTOR_SIZE_NOT_ | Indicates that the attached device sector | 194 | SUPPORTED | size is not supported by this driver. | 195 196 */ 197 typedef enum { 198 USBH_MSC_NO_ERROR = 0, 199 USBH_MSC_EP_NOT_VALID = -1, 200 USBH_MSC_CLR_CEP_STALL_ERROR = -2, 201 USBH_MSC_SECTOR_SIZE_NOT_SUPPORTED = -3, 202 USBH_MSC_WRONG_DESCR = -4, 203 } mss_usbh_msc_err_code_t; 204 205 /*-------------------------------------------------------------------------*//** 206 The mss_usbh_msc_state_t provides a type for the states of operation of the 207 USBH-MSC driver. Most of the states are internally used by the USBH-MSC driver 208 during the enumeration process. The USBH-MSC driver is ready to perform data 209 transfers with the attached device when the driver is in state 210 USBH_MSC_DEVICE_READY. The USBH_MSC_ERROR state indicates that the error was 211 detected either during enumeration or during the normal data transfer 212 operations with the attached device even after retries. 213 */ 214 typedef enum { 215 USBH_MSC_IDLE, 216 USBH_MSC_GET_CLASS_DESCR, 217 USBH_MSC_WAIT_GET_CLASS_DESCR, 218 USBH_MSC_SET_CONFIG, 219 USBH_MSC_WAIT_SET_CONFIG, 220 USBH_MSC_WAIT_DEV_SETTLE, 221 USBH_MSC_GET_MAX_LUN, 222 USBH_MSC_WAIT_GET_MAX_LUN, 223 USBH_MSC_CLR_CEP_STALL, 224 USBH_MSC_WAIT_CLR_CEP_STALL, 225 USBH_MSC_CONFIG_BULK_ENDPOINTS, 226 227 USBH_MSC_TEST_UNIT_READY_CPHASE, 228 USBH_MSC_TEST_UNIT_READY_SPHASE, 229 USBH_MSC_TEST_UNIT_READY_WAITCOMPLETE, 230 231 USBH_MSC_SCSI_INQUIRY_CPHASE, 232 USBH_MSC_SCSI_INQUIRY_DPHASE, 233 USBH_MSC_SCSI_INQUIRY_SPHASE, 234 USBH_MSC_SCSI_INQUIRY_WAITCOMPLETE, 235 236 USBH_MSC_SCSI_REQSENSE_CPHASE, 237 USBH_MSC_SCSI_REQSENSE_DPHASE, 238 USBH_MSC_SCSI_REQSENSE_SPHASE, 239 USBH_MSC_SCSI_REQSENSE_WAITCOMPLETE, 240 241 USBH_MSC_SCSI_READ_CAPACITY_CPHASE, 242 USBH_MSC_SCSI_READ_CAPACITY_DPHASE, 243 USBH_MSC_SCSI_READ_CAPACITY_SPHASE, 244 USBH_MSC_SCSI_READ_CAPACITY_WAITCOMPLETE, 245 246 USBH_MSC_DEVICE_READY, 247 USBH_MSC_BOT_RETRY, 248 USBH_MSC_ERROR 249 } mss_usbh_msc_state_t; 250 251 /*----------------------------------------------------------------------------*/ 252 /*---------------Data structures exported by USBH-MSC driver ---------------*/ 253 /*----------------------------------------------------------------------------*/ 254 255 /*-------------------------------------------------------------------------*//** 256 The mss_usbh_msc_user_cb_t provides the prototype for all the call-back 257 functions which must be implemented by the user application. The user 258 application must define and initialize a structure of this type and provide 259 the address of that structure as parameter to the MSS_USBH_MSC_init() function. 260 261 msch_valid_config 262 The function pointed by the msch_valid_config function pointer will be called 263 to indicate that a valid MSC class configuration was found on the attached 264 device and the device is configured for this configuration. 265 266 msch_tdev_ready 267 The function pointed by the msch_tdev_ready function pointer is called when 268 this driver is able to retrieve all the MSC class specific information 269 (including sector size and sector number) from the attached device and is 270 ready to perform the data transfers. 271 272 msch_driver_released 273 The function pointed by the msch_driver_released function pointer is called to 274 indicate to the application that this driver is released by the USBH driver. 275 This could be either because the MSC class device is now detached or there is 276 permanent error with the USBH driver. 277 278 msch_error 279 The function pointed by the msch_error function pointer is called to indicate 280 that there was an error while retrieving the class specific descriptor 281 information from the attached MSC class device. The error_code parameter 282 indicates the exact cause of the error. 283 */ 284 typedef struct mss_usbh_msc_user_cb 285 { 286 void (*msch_valid_config)(void); 287 void (*msch_tdev_ready)(void); 288 void (*msch_driver_released)(void); 289 void (*msch_error)(int8_t error_code); 290 } mss_usbh_msc_user_cb_t; 291 292 /*-------------------------------------------------------------------------*//** 293 The msd_cbw_t type provides the prototype for the Command Block Wrapper (CBW) 294 as defined in Universal Serial Bus Mass Storage Class Bulk-Only Transport 295 Revision 1.0. This type can be used by the application to create buffer of 296 this type for creating the CBW which can then be passed on to functions 297 provided by this driver as parameter. 298 299 dCBWSignature 300 Signature that helps identify this data packet as a CBW. The signature field 301 shall contain the value 43425355h (little endian), indicating a CBW. 302 303 dCBWTag 304 A Command Block Tag sent by the host. The device shall echo the contents of 305 this field back to the host in the dCSWTagfield of the associated CSW. The 306 dCSWTagpositively associates a CSW with the corresponding CBW. 307 308 dCBWDataTransferLength 309 The number of bytes of data that the host expects to transfer on the Bulk-In 310 or Bulk-Out endpoint (as indicated by the Direction-bit) during the execution 311 of this command. If this field is zero, the device and the host shall transfer 312 no data between the CBW and the associated CSW, and the device shall ignore 313 the value of the Direction-bit in bmCBWFlags. 314 315 bCBWFlags 316 The bits of this field are defined as follows: 317 318 | Bit | Description | 319 |------------|-------------------------------------------------------------| 320 | Bit 7 | Direction- the device shall ignore this bit if the | 321 | | dCBWDataTransferLengthfield is zero, otherwise: | 322 | | 0 = Data-Out from host to the device, | 323 | | 1 = Data-In from the device to the host. | 324 | | | 325 | Bit 6 | Obsolete. The host shall set this bit to zero. | 326 | Bits 5..0 | Reserved - the host shall set these bits to zero. | 327 328 bCBWLUN 329 The device Logical Unit Number (LUN) to which the command block is being sent. 330 For devices that support multiple LUNs, the host shall place into this field 331 the LUN to which this command block is addressed. Otherwise, the host shall 332 set this field to zero. 333 334 bCBWCBLength 335 The valid length of the CBWCBin bytes. This defines the valid length of the 336 command block. The only legal values are 1 through 16 (01h through 10h). 337 All other values are reserved. 338 339 CBWCB[16] 340 The command block to be executed by the device. The device shall interpret the 341 first bCBWCBLength bytes in this field as a command block as defined by the 342 command set identified by bInterfaceSubClass. If the command set supported by 343 the device uses command blocks of fewer than 16 (10h) bytes in length, the 344 significant bytes shall be transferred first, beginning with the byte at 345 offset 15 (0Fh). The device shall ignore the content of the CBWCBfield past 346 the byte at offset (15 + bCBWCBLength- 1) 347 */ 348 typedef struct { 349 uint32_t dCBWSignature; 350 uint32_t dCBWTag; 351 uint32_t dCBWDataTransferLength; 352 uint8_t bCBWFlags; 353 uint8_t bCBWLUN; 354 uint8_t bCBWCBLength; 355 uint8_t CBWCB[16]; 356 } msd_cbw_t; 357 358 /*-------------------------------------------------------------------------*//** 359 The msd_csw_t type provides the prototype for the Command Status Wrapper (CSW) 360 as defined in Universal Serial Bus Mass Storage Class Bulk-Only Transport 361 Revision 1.0. This type can be used by application to create buffer of this 362 type for creating CSW which can then be passed on to APIs provided by this 363 driver as parameter. 364 365 dCSWSignature 366 Signature that helps identify this data packet as a CSW. The signature field 367 shall contain the value 53425355h (little endian), indicating CSW. 368 369 dCSWTag 370 The device shall set this field to the value received in the dCBWTag of the 371 associated CBW. 372 373 dCSWDataResidue 374 For Data-Out the device shall report in the dCSWDataResiduethe difference 375 between the amount of data expected as stated in the dCBWDataTransferLength, 376 and the actual amount of data processed by the device. For Data-In the device 377 shall report in the dCSWDataResiduethe difference between the amount of data 378 expected as stated in the dCBWDataTransferLengthand the actual amount of 379 relevant data sent by the device. The dCSWDataResidueshall not exceed the 380 value sent in the dCBWDataTransferLength. 381 382 dCSWStatus 383 bCSWStatusindicates the success or failure of the command. The device shall 384 set this byte to zero if the command completed successfully. A non-zero value 385 shall indicate a failure during command execution according to the following 386 table: 387 | Value | Description | 388 |----------------------|---------------------------------------| 389 | 00h | Command Passed ("good status") | 390 | 01h | Command Failed | 391 | 02h | Phase Error | 392 | 03h and 04h | Reserved (Obsolete) | 393 | 05h to FFh | Reserved 394 */ 395 typedef struct { 396 uint32_t dCSWSignature; 397 uint32_t dCSWTag; 398 uint32_t dCSWDataResidue; 399 uint32_t dCSWStatus; 400 } msd_csw_t; 401 402 /*-------------------------------------------------------------------------*//** 403 EXPORTED APIs from USBH-MSC driver 404 ============================ 405 */ 406 /*-------------------------------------------------------------------------*//** 407 The MSS_USBH_MSC_init() function must be used by the application to initialize 408 the USBH-MSC driver. This function must be called before any other function of 409 the USBH-MSC driver. 410 411 @param user_cb 412 The user_cb parameter provides a pointer to the structure of type 413 mss_usbh_msc_user_cb_t. This pointer is used to call the application 414 call-back functions by the USBH-MSC driver. These call-back functions can be 415 used by the application to provide error/status messages to the user or for 416 performing the application specific handling of the events. 417 418 @return 419 This function does not return a value. 420 421 Example: 422 @code 423 Initialize the USBH driver 424 MSS_USBH_init(&MSS_USBH_user_cb); 425 426 Initialize the USBH-MSC driver 427 MSS_USBH_MSC_init(&MSS_USBH_MSC_user_cb); 428 429 430 Get Class driver handle from the USBH-MSC class driver and register it with 431 the USBH driver. 432 On Device attachment, USBH driver will look for Device information through 433 Descriptors and if match it with the Class driver using this Handle. 434 MSS_USBH_register_class_driver(MSS_USBH_MSC_get_handle()); 435 @endcode 436 */ 437 void 438 MSS_USBH_MSC_init 439 ( 440 mss_usbh_msc_user_cb_t* user_sb 441 ); 442 443 /*-------------------------------------------------------------------------*//** 444 The MSS_USBH_MSC_task() function is the main task of the USBH-MSC driver. 445 This function monitors the events from the USBH driver as well as the user 446 application and makes decisions. This function must be called repeatedly by 447 the application to allow the USBH-MSC driver to perform the housekeeping tasks. 448 A timer/scheduler can be used to call this function at regular intervals or 449 it can be called from the main continuous foreground loop of the application. 450 451 @param 452 This function does not take any parameters. 453 454 @return 455 This function does not return a value. 456 457 Example: 458 @code 459 #define SYS_TICK_LOAD_VALUE 48000u 460 int main() 461 { 462 Initialize SysTick 463 SysTick_Config(SYS_TICK_LOAD_VALUE); 464 NVIC_EnableIRQ(SysTick_IRQn); 465 } 466 void SysTick_Handler(void) 467 { 468 MSS_USBH_MSC_task(); 469 } 470 @endcode 471 */ 472 void 473 MSS_USBH_MSC_task 474 ( 475 void 476 ); 477 478 /*-------------------------------------------------------------------------*//** 479 The MSS_USBH_MSC_get_handle() function must be used by the application to get 480 the handle from the USBH-MSC driver. This handle must then be used to register 481 this driver with the USBH driver. 482 483 @param 484 This function does not take any parameters. 485 486 @return 487 This function returns a pointer to the class-handle structure. 488 489 Example: 490 @code 491 MSS_USBH_init(&MSS_USBH_user_cb); 492 MSS_USBH_MSC_init(&MSS_USBH_MSC_user_cb); 493 MSS_USBH_register_class_driver(MSS_USBH_MSC_get_handle()); 494 @endcode 495 */ 496 void* 497 MSS_USBH_MSC_get_handle 498 ( 499 void 500 ); 501 502 /*-------------------------------------------------------------------------*//** 503 The MSS_USBH_MSC_get_state() function can be used to find out the current state 504 of the USBH-MSC driver. This information can be used by the application to check 505 the readiness of the USBH-MSC driver to start the data transfers. The USBH-MSC 506 driver can perform data transfers only when it is in the USBH_MSC_DEVICE_READY 507 state. 508 509 @param 510 This function does not take any parameters. 511 512 @return 513 This function returns a value of type mss_usbh_msc_state_t indicating the 514 current state of the USBH-MSC driver. 515 516 Example: 517 @code 518 if(USBH_MSC_DEVICE_READY == MSS_USBH_MSC_get_state()) 519 { 520 *result = MSS_USBH_MSC_get_sector_count(); 521 return RES_OK; 522 } 523 else if(USBH_MSC_DEVICE_READY < MSS_USBH_MSC_get_state()) 524 { 525 *result = 0u; 526 return RES_NOTRDY; 527 } 528 @endcode 529 */ 530 mss_usbh_msc_state_t 531 MSS_USBH_MSC_get_state 532 ( 533 void 534 ); 535 536 /*-------------------------------------------------------------------------*//** 537 The MSS_USBH_MSC_read() function can be used to read data from the attached 538 mass storage device. This is a non-blocking function. The function prepares 539 the MSS USB for the USB IN transfer. Once prepared, the MSS USB will start 540 this IN transfer depending on the configuration of the IN pipe on which this 541 transfer is occurring. The USBH-MSC driver takes care of the allocation and 542 configuration of the IN pipe during enumeration process depending on the 543 attached mass storage device. After preparing the IN pipe for the IN transfer, 544 the MSS_USBH_MSC_is_scsi_req_complete() function can be used to find out the 545 completion of the transfer. 546 547 @param buf 548 The buf parameter is a pointer to the buffer where the data received in the 549 IN transfer from the attached MSC class device is stored. 550 551 @param sector 552 The sector parameter indicates the sector number (logical block address) on 553 the mass storage device starting from which the data is to be read. 554 555 @param count 556 The count parameter indicates the number of sectors to be read. 557 558 @return 559 This function returns a zero value when execution was successful. 560 561 Example: 562 @code 563 DRESULT disk_read (BYTE drv, 564 BYTE *buff, 565 DWORD sector, 566 BYTE count) 567 { 568 if (0u != drv) 569 return(RES_ERROR); 570 if (USBH_MSC_DEVICE_READY < MSS_USBH_MSC_get_state()) 571 { 572 return(RES_NOTRDY); 573 } 574 else if (USBH_MSC_DEVICE_READY == MSS_USBH_MSC_get_state()) 575 { 576 MSS_USBH_MSC_read(buff, sector, count); 577 while (MSS_USBH_MSC_is_scsi_req_complete()); 578 return (RES_OK); 579 } 580 else 581 return (RES_ERROR); 582 } 583 @endcode 584 */ 585 int8_t 586 MSS_USBH_MSC_read 587 ( 588 uint8_t* buf, 589 uint32_t sector, 590 uint32_t count 591 ); 592 593 /*-------------------------------------------------------------------------*//** 594 The MSS_USBH_MSC_write() function can be used to write data to the attached 595 mass storage device. This is a non-blocking function. The function readies the 596 MSS USB for the USB OUT transfer. Once ready, the MSS USB will start this OUT 597 transfer depending on the configuration of the OUT pipe on which this transfer 598 is occurring. The USBH-MSC driver takes care of the allocation and 599 configuration of the OUT pipe during enumeration process depending on the 600 attached mass storage device. After starting the OUT transfer on the specified 601 OUT pipe, the MSS_USBH_MSC_is_scsi_req_complete() function can be used to find 602 out the completion of the transfer. 603 604 @param buf 605 The buf parameter is a pointer to the buffer from which data need to be 606 transmitted to the attached MSC class device. 607 608 @param sector 609 The sector parameter indicates the sector number (logical block address) on 610 the mass storage device starting from which the data is to be written. 611 612 @param count 613 The count parameter indicates the number of sectors to be written. 614 615 @return 616 This function returns a zero value when execution was successful. 617 618 Example: 619 @code 620 DRESULT disk_write (BYTE pdrv, 621 const BYTE *buff, 622 DWORD sector, 623 BYTE count) 624 { 625 if (0u != pdrv) 626 return(RES_ERROR); 627 628 if (USBH_MSC_DEVICE_READY < MSS_USBH_MSC_get_state()) 629 { 630 return(RES_NOTRDY); 631 } 632 else if (USBH_MSC_DEVICE_READY == MSS_USBH_MSC_get_state()) 633 { 634 MSS_USBH_MSC_write((uint8_t*)buff, sector, count); 635 while (MSS_USBH_MSC_is_scsi_req_complete()); 636 return (RES_OK); 637 } 638 else 639 return (RES_ERROR); 640 } 641 @endcode 642 */ 643 int8_t 644 MSS_USBH_MSC_write 645 ( 646 uint8_t* buf, 647 uint32_t sector, 648 uint32_t count 649 ); 650 651 /*-------------------------------------------------------------------------*//** 652 The MSS_USBH_MSC_get_sector_count() function can be used to find out the 653 number of sectors (logical blocks) available on the attached MSC class device. 654 655 @param 656 This function does not take any parameters. 657 658 @return 659 This function returns a value of type uint32_t indicating the number of 660 sectors (logical blocks) available on the attached MSC class device. 661 662 Example: 663 @code 664 DRESULT disk_ioctl ( 665 BYTE pdrv, 666 BYTE ctrl, 667 void *buff) 668 ) 669 { 670 UINT *result = (UINT *)buff; 671 672 switch (ctrl) { 673 case GET_SECTOR_COUNT: 674 if (USBH_MSC_DEVICE_READY == MSS_USBH_MSC_get_state()) 675 { 676 *result = MSS_USBH_MSC_get_sector_count(); 677 return RES_OK; 678 } 679 else if (USBH_MSC_DEVICE_READY < MSS_USBH_MSC_get_state()) 680 { 681 *result = 0u; 682 return RES_NOTRDY; 683 } 684 else 685 { 686 *result = 0u; 687 return RES_ERROR; 688 } 689 break; 690 691 default: 692 return RES_NOTRDY; 693 } 694 } 695 @endcode 696 */ 697 uint32_t 698 MSS_USBH_MSC_get_sector_count 699 ( 700 void 701 ); 702 703 /*-------------------------------------------------------------------------*//** 704 The MSS_USBH_MSC_get_sector_size() function can be used to find out the size 705 of a sector (in bytes) on the attached MSC class device. 706 707 @param 708 This function does not take any parameters. 709 710 @return 711 This function returns a value of type uint32_t indicating the sector size 712 (in bytes) on the attached MSC class device. 713 714 Example: 715 @code 716 DRESULT disk_ioctl ( 717 BYTE pdrv, 718 BYTE ctrl, 719 void *buff 720 ) 721 { 722 UINT *result = (UINT *)buff; 723 724 switch (ctrl) { 725 case GET_SECTOR_SIZE: 726 if(USBH_MSC_DEVICE_READY == MSS_USBH_MSC_get_state()) 727 { 728 *result = MSS_USBH_MSC_get_sector_size(); 729 return RES_OK; 730 } 731 else if(USBH_MSC_DEVICE_READY < MSS_USBH_MSC_get_state()) 732 { 733 *result = 0u; 734 return RES_NOTRDY; 735 } 736 else 737 { 738 *result = 0u; 739 return RES_ERROR; 740 } 741 break; 742 743 default: 744 return RES_NOTRDY; 745 } 746 } 747 @endcode 748 */ 749 uint32_t 750 MSS_USBH_MSC_get_sector_size 751 ( 752 void 753 ); 754 755 /*-------------------------------------------------------------------------*//** 756 The MSS_USBH_MSC_construct_cbw_cb10byte() function can be used to create the 757 SCSI request command block wrapper (CBW) as per MSC class which has command 758 block(CB) of length 10bytes. 759 760 @param command_opcode 761 The command_opcode parameter provides the transparent SCSI command code. 762 763 @param lun 764 The lun parameter indicates the logical unit number on the attached MSC 765 class device. 766 767 @param lb_addr 768 The lb_addr parameter provides the logical block address on which the 769 operation indicated by the command_opcode parameter is applicable. For the 770 commands where logical block address is not applicable, a zero value must 771 be provided. 772 773 @param num_of_lb 774 The num_of_addr parameter provides the number of logical blocks on which 775 the operation indicated by the command_opcode parameter is applicable. For 776 the commands where logical block address is not applicable, a zero value 777 must be provided. 778 779 @param lb_size 780 The lb_size parameter provides the size of the logical block on the attached 781 MSC class device. 782 783 @param buf 784 The buf parameter provides the pointer to the buffer where the formatted SCSI 785 command is to be stored. 786 787 @return 788 This function does not return any value. 789 790 Example: 791 @code 792 int8_t 793 MSS_USBH_MSC_read(uint8_t* buf, uint32_t sector, uint32_t count) 794 { 795 MSS_USBH_MSC_construct_cbw_cb10byte(USB_MSC_SCSI_READ_10, 796 0u, 797 sector, 798 count, 799 512u, 800 &g_bot_cbw); 801 802 803 MSS_USBH_MSC_scsi_req((uint8_t*)&g_bot_cbw, 804 buf, 805 (count*512u), 806 (uint8_t*)&g_bot_csw); 807 return(0); 808 } 809 @endcode 810 */ 811 void 812 MSS_USBH_MSC_construct_cbw_cb10byte 813 ( 814 uint8_t command_opcode, 815 uint8_t lun, 816 uint32_t lb_addr, 817 uint16_t num_of_lb, 818 uint16_t lb_size, 819 msd_cbw_t* buf 820 ); 821 822 /*-------------------------------------------------------------------------*//** 823 The MSS_USBH_MSC_construct_cbw_cb6byte() function can be used to create the 824 SCSI request command block wrapper (CBW) as per MSC class which has command 825 block(CB) of length 6 bytes. 826 827 @param command_opcode 828 The command_opcode parameter provides the transparent SCSI command code. 829 830 @param xfr_length 831 The xfr_length parameter provides the number of bytes to be transferred in 832 the data phase of the command. 833 834 @param buf 835 The buf parameter provides the pointer to the buffer where the formatted 836 SCSI command is to be stored. 837 838 @return 839 This function does not return any value. 840 841 Example: 842 @code 843 MSS_USBH_MSC_construct_cbw_cb6byte(USB_MSC_SCSI_TEST_UNIT_READY, 844 0u, 845 &g_bot_cbw); 846 847 MSS_USBH_write_out_pipe(g_msd_tdev_addr, 848 USBH_MSC_BULK_TX_PIPE, 849 g_tdev_out_ep.num, 850 g_tdev_out_ep.maxpktsz, 851 (uint8_t*)&g_bot_cbw, 852 31u); 853 @endcode 854 */ 855 void 856 MSS_USBH_MSC_construct_cbw_cb6byte 857 ( 858 uint8_t command_opcode, 859 uint32_t data_xfr_len, 860 msd_cbw_t* buf 861 ); 862 863 /*-------------------------------------------------------------------------*//** 864 The MSS_USBH_MSC_scsi_req() function can be used to execute any SCSI command 865 required by the MSC class on the attached MSC device. In most cases using 866 the MSS_USBH_MSC_write() and MSS_USBH_MSC_read() functions is enough for the 867 application. However, if the application wants to execute other SCSI commands 868 it can use the MSS_USBH_MSC_scsi_req() function. This function can be used as 869 alternative to MSS_USBH_MSC_write() and MSS_USBH_MSC_read() functions. 870 871 The MSS_USBH_MSC_is_scsi_req_complete() function can be used to find out when 872 the transfer started using this function is complete. 873 874 @param command_buf 875 The command_buf parameter provides the pointer to the buffer where the SCSI 876 command (CBW format) to be executed is stored. 877 878 @param data_buf 879 The data_buf parameter provides the pointer to the data buffer which is to 880 be used in the data phase of the command. This parameter is the source of 881 the data when the data direction is from the host to the device. This 882 parameter is the destination for the data when the data direction is from 883 the device to the host. This function extracts the data direction from the 884 CBW format command provided using command_buf parameter. 885 886 @param data_buf_len 887 The data_buf_len parameter indicates the number of bytes to be transferred 888 in the data phase of the current command. 889 890 @param status_buf 891 The status_buf parameter provides the pointer to the buffer where the status 892 (CSW format) received from the attached MSC device for the current SCSI 893 operation is to be stored. 894 895 @return 896 This function returns zero value when successfully executed. 897 898 Example: 899 @code 900 int8_t 901 MSS_USBH_MSC_read 902 ( 903 uint8_t* buf, 904 uint32_t sector, 905 uint32_t count 906 ) 907 { 908 MSS_USBH_MSC_construct_cbw_cb10byte(USB_MSC_SCSI_READ_10, 909 0u, 910 sector, 911 count, 912 512u, 913 &g_bot_cbw); 914 915 MSS_USBH_MSC_scsi_req((uint8_t*)&g_bot_cbw, 916 buf, 917 (count*512u), 918 (uint8_t*)&g_bot_csw); 919 return(0); 920 } 921 @endcode 922 */ 923 uint8_t 924 MSS_USBH_MSC_scsi_req 925 ( 926 uint8_t* command_buf, /* always31bytes */ 927 uint8_t* data_buf, 928 uint32_t data_buf_len, 929 uint8_t* status_buf /* status always 13bytes */ 930 ); 931 932 /*-------------------------------------------------------------------------*//** 933 The MSS_USBH_MSC_is_scsi_req_complete() function must be used to find out 934 whether the SCSI request initiated using MSS_USBH_MSC_scsi_req() or 935 MSS_USBH_MSC_read() or MSS_USBH_MSC_write() function is complete. 936 937 @param 938 This function does not take any parameters. 939 940 @return 941 This function returns zero value when the current command is completed. 942 943 Example: 944 @code 945 MSS_USBH_MSC_write((uint8_t*)buff, sector, count); 946 while (MSS_USBH_MSC_is_scsi_req_complete()); 947 return (RES_OK); 948 @endcode 949 */ 950 uint8_t 951 MSS_USBH_MSC_is_scsi_req_complete 952 ( 953 void 954 ); 955 956 #endif /* MSS_USB_HOST_ENABLED */ 957 958 #ifdef __cplusplus 959 } 960 #endif 961 962 #endif /* __MSS_USB_HOST_MSC_H_ */ 963 964