msc_device.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /*
  2. * The MIT License (MIT)
  3. *
  4. * Copyright (c) 2019 Ha Thach (tinyusb.org)
  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 deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * 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 FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. * THE SOFTWARE.
  23. *
  24. * This file is part of the TinyUSB stack.
  25. */
  26. #ifndef _TUSB_MSC_DEVICE_H_
  27. #define _TUSB_MSC_DEVICE_H_
  28. #include "common/tusb_common.h"
  29. #include "msc.h"
  30. #ifdef __cplusplus
  31. extern "C" {
  32. #endif
  33. //--------------------------------------------------------------------+
  34. // Class Driver Configuration
  35. //--------------------------------------------------------------------+
  36. #if !defined(CFG_TUD_MSC_EP_BUFSIZE) & defined(CFG_TUD_MSC_BUFSIZE)
  37. // TODO warn user to use new name later on
  38. // #warning CFG_TUD_MSC_BUFSIZE is renamed to CFG_TUD_MSC_EP_BUFSIZE, please update to use the new name
  39. #define CFG_TUD_MSC_EP_BUFSIZE CFG_TUD_MSC_BUFSIZE
  40. #endif
  41. #ifndef CFG_TUD_MSC_EP_BUFSIZE
  42. #error CFG_TUD_MSC_EP_BUFSIZE must be defined, value of a block size should work well, the more the better
  43. #endif
  44. TU_VERIFY_STATIC(CFG_TUD_MSC_EP_BUFSIZE < UINT16_MAX, "Size is not correct");
  45. //--------------------------------------------------------------------+
  46. // Application API
  47. //--------------------------------------------------------------------+
  48. // Set SCSI sense response
  49. bool tud_msc_set_sense(uint8_t lun, uint8_t sense_key, uint8_t add_sense_code, uint8_t add_sense_qualifier);
  50. //--------------------------------------------------------------------+
  51. // Application Callbacks (WEAK is optional)
  52. //--------------------------------------------------------------------+
  53. // Invoked when received SCSI READ10 command
  54. // - Address = lba * BLOCK_SIZE + offset
  55. // - offset is only needed if CFG_TUD_MSC_EP_BUFSIZE is smaller than BLOCK_SIZE.
  56. //
  57. // - Application fill the buffer (up to bufsize) with address contents and return number of read byte. If
  58. // - read < bufsize : These bytes are transferred first and callback invoked again for remaining data.
  59. //
  60. // - read == 0 : Indicate application is not ready yet e.g disk I/O busy.
  61. // Callback invoked again with the same parameters later on.
  62. //
  63. // - read < 0 : Indicate application error e.g invalid address. This request will be STALLed
  64. // and return failed status in command status wrapper phase.
  65. int32_t tud_msc_read10_cb (uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize);
  66. // Invoked when received SCSI WRITE10 command
  67. // - Address = lba * BLOCK_SIZE + offset
  68. // - offset is only needed if CFG_TUD_MSC_EP_BUFSIZE is smaller than BLOCK_SIZE.
  69. //
  70. // - Application write data from buffer to address contents (up to bufsize) and return number of written byte. If
  71. // - write < bufsize : callback invoked again with remaining data later on.
  72. //
  73. // - write == 0 : Indicate application is not ready yet e.g disk I/O busy.
  74. // Callback invoked again with the same parameters later on.
  75. //
  76. // - write < 0 : Indicate application error e.g invalid address. This request will be STALLed
  77. // and return failed status in command status wrapper phase.
  78. //
  79. // TODO change buffer to const uint8_t*
  80. int32_t tud_msc_write10_cb (uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize);
  81. // Invoked when received SCSI_CMD_INQUIRY
  82. // Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively
  83. void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]);
  84. // Invoked when received Test Unit Ready command.
  85. // return true allowing host to read/write this LUN e.g SD card inserted
  86. bool tud_msc_test_unit_ready_cb(uint8_t lun);
  87. // Invoked when received SCSI_CMD_READ_CAPACITY_10 and SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size
  88. // Application update block count and block size
  89. void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size);
  90. /**
  91. * Invoked when received an SCSI command not in built-in list below.
  92. * - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, TEST_UNIT_READY, START_STOP_UNIT, MODE_SENSE6, REQUEST_SENSE
  93. * - READ10 and WRITE10 has their own callbacks
  94. *
  95. * \param[in] lun Logical unit number
  96. * \param[in] scsi_cmd SCSI command contents which application must examine to response accordingly
  97. * \param[out] buffer Buffer for SCSI Data Stage.
  98. * - For INPUT: application must fill this with response.
  99. * - For OUTPUT it holds the Data from host
  100. * \param[in] bufsize Buffer's length.
  101. *
  102. * \return Actual bytes processed, can be zero for no-data command.
  103. * \retval negative Indicate error e.g unsupported command, tinyusb will \b STALL the corresponding
  104. * endpoint and return failed status in command status wrapper phase.
  105. */
  106. int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize);
  107. /*------------- Optional callbacks -------------*/
  108. // Invoked when received GET_MAX_LUN request, required for multiple LUNs implementation
  109. TU_ATTR_WEAK uint8_t tud_msc_get_maxlun_cb(void);
  110. // Invoked when received Start Stop Unit command
  111. // - Start = 0 : stopped power mode, if load_eject = 1 : unload disk storage
  112. // - Start = 1 : active mode, if load_eject = 1 : load disk storage
  113. TU_ATTR_WEAK bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject);
  114. // Invoked when received REQUEST_SENSE
  115. TU_ATTR_WEAK int32_t tud_msc_request_sense_cb(uint8_t lun, void* buffer, uint16_t bufsize);
  116. // Invoked when Read10 command is complete
  117. TU_ATTR_WEAK void tud_msc_read10_complete_cb(uint8_t lun);
  118. // Invoke when Write10 command is complete, can be used to flush flash caching
  119. TU_ATTR_WEAK void tud_msc_write10_complete_cb(uint8_t lun);
  120. // Invoked when command in tud_msc_scsi_cb is complete
  121. TU_ATTR_WEAK void tud_msc_scsi_complete_cb(uint8_t lun, uint8_t const scsi_cmd[16]);
  122. // Invoked to check if device is writable as part of SCSI WRITE10
  123. TU_ATTR_WEAK bool tud_msc_is_writable_cb(uint8_t lun);
  124. //--------------------------------------------------------------------+
  125. // Internal Class Driver API
  126. //--------------------------------------------------------------------+
  127. void mscd_init (void);
  128. void mscd_reset (uint8_t rhport);
  129. uint16_t mscd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
  130. bool mscd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * p_request);
  131. bool mscd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
  132. #ifdef __cplusplus
  133. }
  134. #endif
  135. #endif /* _TUSB_MSC_DEVICE_H_ */