summaryrefslogtreecommitdiff
path: root/src/class
diff options
context:
space:
mode:
Diffstat (limited to 'src/class')
-rw-r--r--src/class/hid/hid_device.c41
-rw-r--r--src/class/hid/hid_device.h14
-rw-r--r--src/class/msc/msc_host.c217
-rw-r--r--src/class/msc/msc_host.h86
4 files changed, 173 insertions, 185 deletions
diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c
index 4cdcecc9e..18d35bc20 100644
--- a/src/class/hid/hid_device.c
+++ b/src/class/hid/hid_device.c
@@ -251,11 +251,7 @@ bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t
}
else if (request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_REPORT)
{
- uint8_t const * desc_report = tud_hid_descriptor_report_cb(
- #if CFG_TUD_HID > 1
- hid_itf // TODO for backward compatible callback, remove later when appropriate
- #endif
- );
+ uint8_t const * desc_report = tud_hid_descriptor_report_cb(hid_itf);
tud_control_xfer(rhport, request, (void*) desc_report, p_hid->report_desc_len);
}
else
@@ -275,12 +271,7 @@ bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t
uint8_t const report_type = tu_u16_high(request->wValue);
uint8_t const report_id = tu_u16_low(request->wValue);
- uint16_t xferlen = tud_hid_get_report_cb(
- #if CFG_TUD_HID > 1
- hid_itf, // TODO for backward compatible callback, remove later when appropriate
- #endif
- report_id, (hid_report_type_t) report_type, p_hid->epin_buf, request->wLength
- );
+ uint16_t xferlen = tud_hid_get_report_cb(hid_itf, report_id, (hid_report_type_t) report_type, p_hid->epin_buf, request->wLength);
TU_ASSERT( xferlen > 0 );
tud_control_xfer(rhport, request, p_hid->epin_buf, xferlen);
@@ -298,12 +289,7 @@ bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t
uint8_t const report_type = tu_u16_high(request->wValue);
uint8_t const report_id = tu_u16_low(request->wValue);
- tud_hid_set_report_cb(
- #if CFG_TUD_HID > 1
- hid_itf, // TODO for backward compatible callback, remove later when appropriate
- #endif
- report_id, (hid_report_type_t) report_type, p_hid->epout_buf, request->wLength
- );
+ tud_hid_set_report_cb(hid_itf, report_id, (hid_report_type_t) report_type, p_hid->epout_buf, request->wLength);
}
break;
@@ -314,12 +300,7 @@ bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t
if ( tud_hid_set_idle_cb )
{
// stall request if callback return false
- TU_VERIFY( tud_hid_set_idle_cb(
- #if CFG_TUD_HID > 1
- hid_itf, // TODO for backward compatible callback, remove later when appropriate
- #endif
- p_hid->idle_rate)
- );
+ TU_VERIFY( tud_hid_set_idle_cb( hid_itf, p_hid->idle_rate) );
}
tud_control_status(rhport, request);
@@ -354,12 +335,7 @@ bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t
{
if (tud_hid_boot_mode_cb)
{
- tud_hid_boot_mode_cb(
- #if CFG_TUD_HID > 1
- hid_itf, // TODO for backward compatible callback, remove later when appropriate
- #endif
- p_hid->boot_mode
- );
+ tud_hid_boot_mode_cb(hid_itf, p_hid->boot_mode);
}
}
break;
@@ -400,12 +376,7 @@ bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_
// Received report
else if (ep_addr == p_hid->ep_out)
{
- tud_hid_set_report_cb(
- #if CFG_TUD_HID > 1
- itf, // TODO for backward compatible callback, remove later when appropriate
- #endif
- 0, HID_REPORT_TYPE_INVALID, p_hid->epout_buf, xferred_bytes
- );
+ tud_hid_set_report_cb(itf, 0, HID_REPORT_TYPE_INVALID, p_hid->epout_buf, xferred_bytes);
TU_ASSERT(usbd_edpt_xfer(rhport, p_hid->ep_out, p_hid->epout_buf, sizeof(p_hid->epout_buf)));
}
diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h
index d5de53221..0c59d5d20 100644
--- a/src/class/hid/hid_device.h
+++ b/src/class/hid/hid_device.h
@@ -88,8 +88,6 @@ static inline bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8
// Callbacks (Weak is optional)
//--------------------------------------------------------------------+
-#if CFG_TUD_HID > 1
-
// Invoked when received GET HID REPORT DESCRIPTOR request
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
uint8_t const * tud_hid_descriptor_report_cb(uint8_t itf);
@@ -111,18 +109,6 @@ TU_ATTR_WEAK void tud_hid_boot_mode_cb(uint8_t itf, uint8_t boot_mode);
// - Idle Rate > 0 : skip duplication, but send at least 1 report every idle rate (in unit of 4 ms).
TU_ATTR_WEAK bool tud_hid_set_idle_cb(uint8_t itf, uint8_t idle_rate);
-#else
-
-// TODO for backward compatible callback, remove later when appropriate
-uint8_t const * tud_hid_descriptor_report_cb(void);
-uint16_t tud_hid_get_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen);
-void tud_hid_set_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize);
-
-TU_ATTR_WEAK void tud_hid_boot_mode_cb(uint8_t boot_mode);
-TU_ATTR_WEAK bool tud_hid_set_idle_cb(uint8_t idle_rate);
-
-#endif
-
// Invoked when sent REPORT successfully to host
// Application can use this to send the next report
// Note: For composite reports, report[0] is report ID
diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c
index 02ca81e77..34dbec2e3 100644
--- a/src/class/msc/msc_host.c
+++ b/src/class/msc/msc_host.c
@@ -47,14 +47,21 @@ enum
typedef struct
{
- uint8_t itf_num;
- uint8_t ep_in;
- uint8_t ep_out;
+ uint8_t itf_num;
+ uint8_t ep_in;
+ uint8_t ep_out;
- uint8_t max_lun;
+ uint8_t max_lun;
- volatile bool mounted;
+ volatile bool configured; // Receive SET_CONFIGURE
+ volatile bool mounted; // Enumeration is complete
+ struct {
+ uint32_t block_size;
+ uint32_t block_count;
+ } capacity[CFG_TUH_MSC_MAXLUN];
+
+ //------------- SCSI -------------//
uint8_t stage;
void* buffer;
tuh_msc_complete_cb_t complete_cb;
@@ -63,14 +70,15 @@ typedef struct
msc_csw_t csw;
}msch_interface_t;
-CFG_TUSB_MEM_SECTION static msch_interface_t msch_data[CFG_TUSB_HOST_DEVICE_MAX];
+CFG_TUSB_MEM_SECTION static msch_interface_t _msch_itf[CFG_TUSB_HOST_DEVICE_MAX];
-// buffer used to read scsi information when mounted, largest response data currently is inquiry
-CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(4) static uint8_t msch_buffer[sizeof(scsi_inquiry_resp_t)];
+// buffer used to read scsi information when mounted
+// largest response data currently is inquiry TODO Inquiry is not part of enum anymore
+CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(4) static uint8_t _msch_buffer[sizeof(scsi_inquiry_resp_t)];
static inline msch_interface_t* get_itf(uint8_t dev_addr)
{
- return &msch_data[dev_addr-1];
+ return &_msch_itf[dev_addr-1];
}
//--------------------------------------------------------------------+
@@ -82,34 +90,45 @@ uint8_t tuh_msc_get_maxlun(uint8_t dev_addr)
return p_msc->max_lun;
}
-bool tuh_msc_mounted(uint8_t dev_addr)
+uint32_t tuh_msc_get_block_count(uint8_t dev_addr, uint8_t lun)
{
msch_interface_t* p_msc = get_itf(dev_addr);
+ return p_msc->capacity[lun].block_count;
+}
- // is configured can be omitted
- return tuh_device_is_configured(dev_addr) && p_msc->mounted;
+uint32_t tuh_msc_get_block_size(uint8_t dev_addr, uint8_t lun)
+{
+ msch_interface_t* p_msc = get_itf(dev_addr);
+ return p_msc->capacity[lun].block_size;
}
-bool tuh_msc_is_busy(uint8_t dev_addr)
+bool tuh_msc_mounted(uint8_t dev_addr)
{
msch_interface_t* p_msc = get_itf(dev_addr);
- return p_msc->mounted && hcd_edpt_busy(dev_addr, p_msc->ep_in);
+ return p_msc->mounted;
+}
+
+bool tuh_msc_ready(uint8_t dev_addr)
+{
+ msch_interface_t* p_msc = get_itf(dev_addr);
+ return p_msc->mounted && !hcd_edpt_busy(dev_addr, p_msc->ep_in);
}
//--------------------------------------------------------------------+
// PUBLIC API: SCSI COMMAND
//--------------------------------------------------------------------+
-static inline void msc_cbw_add_signature(msc_cbw_t *p_cbw, uint8_t lun)
+static inline void cbw_init(msc_cbw_t *cbw, uint8_t lun)
{
- p_cbw->signature = MSC_CBW_SIGNATURE;
- p_cbw->tag = 0x54555342; // TUSB
- p_cbw->lun = lun;
+ tu_memclr(cbw, sizeof(msc_cbw_t));
+ cbw->signature = MSC_CBW_SIGNATURE;
+ cbw->tag = 0x54555342; // TUSB
+ cbw->lun = lun;
}
bool tuh_msc_scsi_command(uint8_t dev_addr, msc_cbw_t const* cbw, void* data, tuh_msc_complete_cb_t complete_cb)
{
msch_interface_t* p_msc = get_itf(dev_addr);
- // TU_VERIFY(p_msc->mounted); // TODO part of the enumeration also use scsi command
+ TU_VERIFY(p_msc->configured);
// TODO claim endpoint
@@ -125,12 +144,12 @@ bool tuh_msc_scsi_command(uint8_t dev_addr, msc_cbw_t const* cbw, void* data, tu
bool tuh_msc_read_capacity(uint8_t dev_addr, uint8_t lun, scsi_read_capacity10_resp_t* response, tuh_msc_complete_cb_t complete_cb)
{
- msch_interface_t* p_msc = get_itf(dev_addr);
- if ( !p_msc->mounted ) return false;
+ msch_interface_t* p_msc = get_itf(dev_addr);
+ TU_VERIFY(p_msc->configured);
- msc_cbw_t cbw = { 0 };
+ msc_cbw_t cbw;
+ cbw_init(&cbw, lun);
- msc_cbw_add_signature(&cbw, lun);
cbw.total_bytes = sizeof(scsi_read_capacity10_resp_t);
cbw.dir = TUSB_DIR_IN_MASK;
cbw.cmd_len = sizeof(scsi_read_capacity10_t);
@@ -139,11 +158,14 @@ bool tuh_msc_read_capacity(uint8_t dev_addr, uint8_t lun, scsi_read_capacity10_r
return tuh_msc_scsi_command(dev_addr, &cbw, response, complete_cb);
}
-bool tuh_msc_scsi_inquiry(uint8_t dev_addr, uint8_t lun, scsi_inquiry_resp_t* response, tuh_msc_complete_cb_t complete_cb)
+bool tuh_msc_inquiry(uint8_t dev_addr, uint8_t lun, scsi_inquiry_resp_t* response, tuh_msc_complete_cb_t complete_cb)
{
- msc_cbw_t cbw = { 0 };
+ msch_interface_t* p_msc = get_itf(dev_addr);
+ TU_VERIFY(p_msc->mounted);
+
+ msc_cbw_t cbw;
+ cbw_init(&cbw, lun);
- msc_cbw_add_signature(&cbw, lun);
cbw.total_bytes = sizeof(scsi_inquiry_resp_t);
cbw.dir = TUSB_DIR_IN_MASK;
cbw.cmd_len = sizeof(scsi_inquiry_t);
@@ -160,26 +182,29 @@ bool tuh_msc_scsi_inquiry(uint8_t dev_addr, uint8_t lun, scsi_inquiry_resp_t* re
bool tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, tuh_msc_complete_cb_t complete_cb)
{
- msc_cbw_t cbw = { 0 };
- msc_cbw_add_signature(&cbw, lun);
+ msch_interface_t* p_msc = get_itf(dev_addr);
+ TU_VERIFY(p_msc->configured);
- cbw.total_bytes = 0; // Number of bytes
- cbw.dir = TUSB_DIR_OUT;
- cbw.cmd_len = sizeof(scsi_test_unit_ready_t);
- cbw.command[0] = SCSI_CMD_TEST_UNIT_READY;
- cbw.command[1] = lun; // according to wiki TODO need verification
+ msc_cbw_t cbw;
+ cbw_init(&cbw, lun);
+
+ cbw.total_bytes = 0;
+ cbw.dir = TUSB_DIR_OUT;
+ cbw.cmd_len = sizeof(scsi_test_unit_ready_t);
+ cbw.command[0] = SCSI_CMD_TEST_UNIT_READY;
+ cbw.command[1] = lun; // according to wiki TODO need verification
return tuh_msc_scsi_command(dev_addr, &cbw, NULL, complete_cb);
}
bool tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, void *resposne, tuh_msc_complete_cb_t complete_cb)
{
- msc_cbw_t cbw = { 0 };
- msc_cbw_add_signature(&cbw, lun);
+ msc_cbw_t cbw;
+ cbw_init(&cbw, lun);
cbw.total_bytes = 18; // TODO sense response
- cbw.dir = TUSB_DIR_IN_MASK;
- cbw.cmd_len = sizeof(scsi_request_sense_t);
+ cbw.dir = TUSB_DIR_IN_MASK;
+ cbw.cmd_len = sizeof(scsi_request_sense_t);
scsi_request_sense_t const cmd_request_sense =
{
@@ -192,60 +217,53 @@ bool tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, void *resposne, tuh_ms
return tuh_msc_scsi_command(dev_addr, &cbw, resposne, complete_cb);
}
-#if 0
-
-tusb_error_t tuh_msc_read10(uint8_t dev_addr, uint8_t lun, void * p_buffer, uint32_t lba, uint16_t block_count)
+bool tuh_msc_read10(uint8_t dev_addr, uint8_t lun, void * buffer, uint32_t lba, uint16_t block_count, tuh_msc_complete_cb_t complete_cb)
{
- msch_interface_t* p_msch = &msch_data[dev_addr-1];
-
- //------------- Command Block Wrapper -------------//
- msc_cbw_add_signature(&p_msch->cbw, lun);
-
- p_msch->cbw.total_bytes = p_msch->block_size*block_count; // Number of bytes
- p_msch->cbw.dir = TUSB_DIR_IN_MASK;
- p_msch->cbw.cmd_len = sizeof(scsi_read10_t);
+ msch_interface_t* p_msc = get_itf(dev_addr);
+ TU_VERIFY(p_msc->mounted);
- //------------- SCSI command -------------//
- scsi_read10_t cmd_read10 =msch_sem_hdl
+ msc_cbw_t cbw;
+ cbw_init(&cbw, lun);
+
+ cbw.total_bytes = block_count*p_msc->capacity[lun].block_size;
+ cbw.dir = TUSB_DIR_IN_MASK;
+ cbw.cmd_len = sizeof(scsi_read10_t);
+
+ scsi_read10_t const cmd_read10 =
{
- .cmd_code = SCSI_CMD_READ_10,
- .lba = tu_htonl(lba),
- .block_count = tu_htons(block_count)
+ .cmd_code = SCSI_CMD_READ_10,
+ .lba = tu_htonl(lba),
+ .block_count = tu_htons(block_count)
};
-
- memcpy(p_msch->cbw.command, &cmd_read10, p_msch->cbw.cmd_len);
-
- TU_ASSERT_ERR ( send_cbw(dev_addr, p_msch, p_buffer));
-
- return TUSB_ERROR_NONE;
+
+ memcpy(cbw.command, &cmd_read10, cbw.cmd_len);
+
+ return tuh_msc_scsi_command(dev_addr, &cbw, buffer, complete_cb);
}
-
-tusb_error_t tuh_msc_write10(uint8_t dev_addr, uint8_t lun, void const * p_buffer, uint32_t lba, uint16_t block_count)
+
+bool tuh_msc_write10(uint8_t dev_addr, uint8_t lun, void const * buffer, uint32_t lba, uint16_t block_count, tuh_msc_complete_cb_t complete_cb)
{
- msch_interface_t* p_msch = &msch_data[dev_addr-1];
+ msch_interface_t* p_msc = get_itf(dev_addr);
+ TU_VERIFY(p_msc->mounted);
- //------------- Command Block Wrapper -------------//
- msc_cbw_add_signature(&p_msch->cbw, lun);
+ msc_cbw_t cbw;
+ cbw_init(&cbw, lun);
- p_msch->cbw.total_bytes = p_msch->block_size*block_count; // Number of bytes
- p_msch->cbw.dir = TUSB_DIR_OUT;
- p_msch->cbw.cmd_len = sizeof(scsi_write10_t);
+ cbw.total_bytes = block_count*p_msc->capacity[lun].block_size;
+ cbw.dir = TUSB_DIR_OUT;
+ cbw.cmd_len = sizeof(scsi_write10_t);
- //------------- SCSI command -------------//
- scsi_write10_t cmd_write10 =
+ scsi_write10_t const cmd_write10 =
{
- .cmd_code = SCSI_CMD_WRITE_10,
- .lba = tu_htonl(lba),
- .block_count = tu_htons(block_count)
+ .cmd_code = SCSI_CMD_WRITE_10,
+ .lba = tu_htonl(lba),
+ .block_count = tu_htons(block_count)
};
- memcpy(p_msch->cbw.command, &cmd_write10, p_msch->cbw.cmd_len);
-
- TU_ASSERT_ERR ( send_cbw(dev_addr, p_msch, (void*) p_buffer));
+ memcpy(cbw.command, &cmd_write10, cbw.cmd_len);
- return TUSB_ERROR_NONE;
+ return tuh_msc_scsi_command(dev_addr, &cbw, (void*) buffer, complete_cb);
}
-#endif
#if 0
// MSC interface Reset (not used now)
@@ -273,14 +291,14 @@ bool tuh_msc_reset(uint8_t dev_addr)
//--------------------------------------------------------------------+
void msch_init(void)
{
- tu_memclr(msch_data, sizeof(msch_interface_t)*CFG_TUSB_HOST_DEVICE_MAX);
+ tu_memclr(_msch_itf, sizeof(msch_interface_t)*CFG_TUSB_HOST_DEVICE_MAX);
}
void msch_close(uint8_t dev_addr)
{
msch_interface_t* p_msc = get_itf(dev_addr);
tu_memclr(p_msc, sizeof(msch_interface_t));
- tuh_msc_unmounted_cb(dev_addr); // invoke Application Callback
+ tuh_msc_unmount_cb(dev_addr); // invoke Application Callback
}
bool msch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes)
@@ -337,6 +355,7 @@ bool msch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32
static bool config_get_maxlun_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result);
static bool config_test_unit_ready_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw);
static bool config_request_sense_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw);
+static bool config_read_capacity_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw);
bool msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t *p_length)
{
@@ -375,6 +394,8 @@ bool msch_set_config(uint8_t dev_addr, uint8_t itf_num)
msch_interface_t* p_msc = get_itf(dev_addr);
TU_ASSERT(p_msc->itf_num == itf_num);
+ p_msc->configured = true;
+
//------------- Get Max Lun -------------//
TU_LOG2("MSC Get Max Lun\r\n");
tusb_control_request_t request =
@@ -402,12 +423,13 @@ static bool config_get_maxlun_complete (uint8_t dev_addr, tusb_control_request_t
msch_interface_t* p_msc = get_itf(dev_addr);
// STALL means zero
- p_msc->max_lun = (XFER_RESULT_SUCCESS == result) ? msch_buffer[0] : 0;
+ p_msc->max_lun = (XFER_RESULT_SUCCESS == result) ? _msch_buffer[0] : 0;
p_msc->max_lun++; // MAX LUN is minus 1 by specs
// TODO multiple LUN support
TU_LOG2("SCSI Test Unit Ready\r\n");
- tuh_msc_test_unit_ready(dev_addr, 0, config_test_unit_ready_complete);
+ uint8_t const lun = 0;
+ tuh_msc_test_unit_ready(dev_addr, lun, config_test_unit_ready_complete);
return true;
}
@@ -416,19 +438,16 @@ static bool config_test_unit_ready_complete(uint8_t dev_addr, msc_cbw_t const* c
{
if (csw->status == 0)
{
- msch_interface_t* p_msc = get_itf(dev_addr);
-
- usbh_driver_set_config_complete(dev_addr, p_msc->itf_num);
-
- // Unit is ready, Enumeration is complete
- p_msc->mounted = true;
- tuh_msc_mounted_cb(dev_addr);
+ // Unit is ready, read its capacity
+ TU_LOG2("SCSI Read Capacity\r\n");
+ tuh_msc_read_capacity(dev_addr, cbw->lun, (scsi_read_capacity10_resp_t*) _msch_buffer, config_read_capacity_complete);
}else
{
// Note: During enumeration, some device fails Test Unit Ready and require a few retries
// with Request Sense to start working !!
// TODO limit number of retries
- TU_ASSERT(tuh_msc_request_sense(dev_addr, cbw->lun, msch_buffer, config_request_sense_complete));
+ TU_LOG2("SCSI Request Sense\r\n");
+ TU_ASSERT(tuh_msc_request_sense(dev_addr, cbw->lun, _msch_buffer, config_request_sense_complete));
}
return true;
@@ -441,4 +460,24 @@ static bool config_request_sense_complete(uint8_t dev_addr, msc_cbw_t const* cbw
return true;
}
+static bool config_read_capacity_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw)
+{
+ TU_ASSERT(csw->status == 0);
+
+ msch_interface_t* p_msc = get_itf(dev_addr);
+
+ // Capacity response field: Block size and Last LBA are both Big-Endian
+ scsi_read_capacity10_resp_t* resp = (scsi_read_capacity10_resp_t*) _msch_buffer;
+ p_msc->capacity[cbw->lun].block_count = tu_ntohl(resp->last_lba) + 1;
+ p_msc->capacity[cbw->lun].block_size = tu_ntohl(resp->block_size);
+
+ // Mark enumeration is complete
+ p_msc->mounted = true;
+ tuh_msc_mount_cb(dev_addr);
+
+ usbh_driver_set_config_complete(dev_addr, p_msc->itf_num);
+
+ return true;
+}
+
#endif
diff --git a/src/class/msc/msc_host.h b/src/class/msc/msc_host.h
index 5913350b8..8116e729f 100644
--- a/src/class/msc/msc_host.h
+++ b/src/class/msc/msc_host.h
@@ -35,6 +35,15 @@
extern "C" {
#endif
+//--------------------------------------------------------------------+
+// Class Driver Configuration
+//--------------------------------------------------------------------+
+
+#ifndef CFG_TUH_MSC_MAXLUN
+#define CFG_TUH_MSC_MAXLUN 4
+#endif
+
+
/** \addtogroup ClassDriver_MSC
* @{
* \defgroup MSC_Host Host
@@ -51,73 +60,56 @@ typedef bool (*tuh_msc_complete_cb_t)(uint8_t dev_addr, msc_cbw_t const* cbw, ms
// This function true after tuh_msc_mounted_cb() and false after tuh_msc_unmounted_cb()
bool tuh_msc_mounted(uint8_t dev_addr);
-/** \brief Check if the interface is currently busy or not
- * \param[in] dev_addr device address
- * \retval true if the interface is busy meaning the stack is still transferring/waiting data from/to device
- * \retval false if the interface is not busy meaning the stack successfully transferred data from/to device
- * \note This function is used to check if previous transfer is complete (success or error), so that the next transfer
- * can be scheduled. User needs to make sure the corresponding interface is mounted (by \ref tuh_msc_is_mounted)
- * before calling this function
- */
-bool tuh_msc_is_busy(uint8_t dev_addr);
+// Check if the interface is currently ready or busy transferring data
+bool tuh_msc_ready(uint8_t dev_addr);
// Get Max Lun
uint8_t tuh_msc_get_maxlun(uint8_t dev_addr);
-// Carry out a full SCSI command (cbw, data, csw) in non-blocking manner.
-// `complete_cb` callback is invoked when SCSI op is complete.
+// Get number of block
+uint32_t tuh_msc_get_block_count(uint8_t dev_addr, uint8_t lun);
+
+// Get block size in bytes
+uint32_t tuh_msc_get_block_size(uint8_t dev_addr, uint8_t lun);
+
+// Perform a full SCSI command (cbw, data, csw) in non-blocking manner.
+// Complete callback is invoked when SCSI op is complete.
// return true if success, false if there is already pending operation.
bool tuh_msc_scsi_command(uint8_t dev_addr, msc_cbw_t const* cbw, void* data, tuh_msc_complete_cb_t complete_cb);
-// Carry out SCSI INQUIRY command in non-blocking manner.
-bool tuh_msc_scsi_inquiry(uint8_t dev_addr, uint8_t lun, scsi_inquiry_resp_t* response, tuh_msc_complete_cb_t complete_cb);
+// Perform SCSI Inquiry command
+// Complete callback is invoked when SCSI op is complete.
+bool tuh_msc_inquiry(uint8_t dev_addr, uint8_t lun, scsi_inquiry_resp_t* response, tuh_msc_complete_cb_t complete_cb);
-// Carry out SCSI REQUEST SENSE (10) command in non-blocking manner.
+// Perform SCSI Test Unit Ready command
+// Complete callback is invoked when SCSI op is complete.
bool tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, tuh_msc_complete_cb_t complete_cb);
-// Carry out SCSI REQUEST SENSE (10) command in non-blocking manner.
+// Perform SCSI Request Sense 10 command
+// Complete callback is invoked when SCSI op is complete.
bool tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, void *resposne, tuh_msc_complete_cb_t complete_cb);
-// Carry out SCSI READ CAPACITY (10) command in non-blocking manner.
-bool tuh_msc_read_capacity(uint8_t dev_addr, uint8_t lun, scsi_read_capacity10_resp_t* response, tuh_msc_complete_cb_t complete_cb);
+// Perform SCSI Read 10 command. Read n blocks starting from LBA to buffer
+// Complete callback is invoked when SCSI op is complete.
+bool tuh_msc_read10(uint8_t dev_addr, uint8_t lun, void * buffer, uint32_t lba, uint16_t block_count, tuh_msc_complete_cb_t complete_cb);
-#if 0
-/** \brief Perform SCSI READ 10 command to read data from MassStorage device
- * \param[in] dev_addr device address
- * \param[in] lun Targeted Logical Unit
- * \param[out] p_buffer Buffer used to store data read from device. Must be accessible by USB controller (see \ref CFG_TUSB_MEM_SECTION)
- * \param[in] lba Starting Logical Block Address to be read
- * \param[in] block_count Number of Block to be read
- * \retval TUSB_ERROR_NONE on success
- * \retval TUSB_ERROR_INTERFACE_IS_BUSY if the interface is already transferring data with device
- * \retval TUSB_ERROR_DEVICE_NOT_READY if device is not yet configured (by SET CONFIGURED request)
- * \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct
- * \note This function is non-blocking and returns immediately. The result of USB transfer will be reported by the interface's callback function
- */
-tusb_error_t tuh_msc_read10 (uint8_t dev_addr, uint8_t lun, void * p_buffer, uint32_t lba, uint16_t block_count);
+// Perform SCSI Write 10 command. Write n blocks starting from LBA to device
+// Complete callback is invoked when SCSI op is complete.
+bool tuh_msc_write10(uint8_t dev_addr, uint8_t lun, void const * buffer, uint32_t lba, uint16_t block_count, tuh_msc_complete_cb_t complete_cb);
-/** \brief Perform SCSI WRITE 10 command to write data to MassStorage device
- * \param[in] dev_addr device address
- * \param[in] lun Targeted Logical Unit
- * \param[in] p_buffer Buffer containing data. Must be accessible by USB controller (see \ref CFG_TUSB_MEM_SECTION)
- * \param[in] lba Starting Logical Block Address to be written
- * \param[in] block_count Number of Block to be written
- * \retval TUSB_ERROR_NONE on success
- * \retval TUSB_ERROR_INTERFACE_IS_BUSY if the interface is already transferring data with device
- * \retval TUSB_ERROR_DEVICE_NOT_READY if device is not yet configured (by SET CONFIGURED request)
- * \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct
- * \note This function is non-blocking and returns immediately. The result of USB transfer will be reported by the interface's callback function
- */
-tusb_error_t tuh_msc_write10(uint8_t dev_addr, uint8_t lun, void const * p_buffer, uint32_t lba, uint16_t block_count);
-#endif
+// Perform SCSI Read Capacity 10 command
+// Complete callback is invoked when SCSI op is complete.
+// Note: during enumeration, host stack already carried out this request. Application can retrieve capacity by
+// simply call tuh_msc_get_block_count() and tuh_msc_get_block_size()
+bool tuh_msc_read_capacity(uint8_t dev_addr, uint8_t lun, scsi_read_capacity10_resp_t* response, tuh_msc_complete_cb_t complete_cb);
//------------- Application Callback -------------//
// Invoked when a device with MassStorage interface is mounted
-void tuh_msc_mounted_cb(uint8_t dev_addr);
+void tuh_msc_mount_cb(uint8_t dev_addr);
// Invoked when a device with MassStorage interface is unmounted
-void tuh_msc_unmounted_cb(uint8_t dev_addr);
+void tuh_msc_unmount_cb(uint8_t dev_addr);
//--------------------------------------------------------------------+
// Internal Class Driver API