summaryrefslogtreecommitdiff
path: root/src/class/msc
diff options
context:
space:
mode:
authortobozo <[email protected]>2023-03-30 19:30:24 +0000
committerGitHub <[email protected]>2023-03-30 19:30:24 +0000
commit290f18a1fe4551cb0376d356627bda595c621518 (patch)
tree789f93ee268cb9c9cccc03702f8a1769ae4a3d9d /src/class/msc
parent9e38b4cc68d9eeeb055349a97caf30d1cf4000e0 (diff)
parent5add4c97fa834004e6a3b267345a13c6d3c9514a (diff)
Merge branch 'hathach:master' into master
Diffstat (limited to 'src/class/msc')
-rw-r--r--src/class/msc/msc.h2
-rw-r--r--src/class/msc/msc_device.c43
-rw-r--r--src/class/msc/msc_device.h2
-rw-r--r--src/class/msc/msc_host.c110
-rw-r--r--src/class/msc/msc_host.h25
5 files changed, 108 insertions, 74 deletions
diff --git a/src/class/msc/msc.h b/src/class/msc/msc.h
index 84b6e4d79..7f25a29ba 100644
--- a/src/class/msc/msc.h
+++ b/src/class/msc/msc.h
@@ -1,4 +1,4 @@
-/*
+/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c
index 3facb76d6..159a11259 100644
--- a/src/class/msc/msc_device.c
+++ b/src/class/msc/msc_device.c
@@ -28,9 +28,9 @@
#if (CFG_TUD_ENABLED && CFG_TUD_MSC)
+#include "device/dcd.h" // for faking dcd_event_xfer_complete
#include "device/usbd.h"
#include "device/usbd_pvt.h"
-#include "device/dcd.h" // for faking dcd_event_xfer_complete
#include "msc_device.h"
@@ -71,8 +71,8 @@ typedef struct
uint8_t add_sense_qualifier;
}mscd_interface_t;
-CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static mscd_interface_t _mscd_itf;
-CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static uint8_t _mscd_buf[CFG_TUD_MSC_EP_BUFSIZE];
+CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static mscd_interface_t _mscd_itf;
+CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static uint8_t _mscd_buf[CFG_TUD_MSC_EP_BUFSIZE];
//--------------------------------------------------------------------+
// INTERNAL OBJECT & FUNCTION DECLARATION
@@ -202,7 +202,7 @@ uint8_t rdwr10_validate_cmd(msc_cbw_t const* cbw)
//--------------------------------------------------------------------+
#if CFG_TUSB_DEBUG >= 2
-TU_ATTR_UNUSED static tu_lookup_entry_t const _msc_scsi_cmd_lookup[] =
+TU_ATTR_UNUSED tu_static tu_lookup_entry_t const _msc_scsi_cmd_lookup[] =
{
{ .key = SCSI_CMD_TEST_UNIT_READY , .data = "Test Unit Ready" },
{ .key = SCSI_CMD_INQUIRY , .data = "Inquiry" },
@@ -217,7 +217,7 @@ TU_ATTR_UNUSED static tu_lookup_entry_t const _msc_scsi_cmd_lookup[] =
{ .key = SCSI_CMD_WRITE_10 , .data = "Write10" }
};
-TU_ATTR_UNUSED static tu_lookup_table_t const _msc_scsi_cmd_table =
+TU_ATTR_UNUSED tu_static tu_lookup_table_t const _msc_scsi_cmd_table =
{
.count = TU_ARRAY_SIZE(_msc_scsi_cmd_lookup),
.items = _msc_scsi_cmd_lookup
@@ -463,7 +463,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
{
// Didn't check for case 9 (Ho > Dn), which requires examining scsi command first
// but it is OK to just receive data then responded with failed status
- TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_out, _mscd_buf, p_msc->total_len) );
+ TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_out, _mscd_buf, (uint16_t) p_msc->total_len) );
}
}else
{
@@ -473,7 +473,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
// Invoke user callback if not built-in
if ( (resplen < 0) && (p_msc->sense_key == 0) )
{
- resplen = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, _mscd_buf, p_msc->total_len);
+ resplen = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, _mscd_buf, (uint16_t) p_msc->total_len);
}
if ( resplen < 0 )
@@ -506,7 +506,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
{
// cannot return more than host expect
p_msc->total_len = tu_min32((uint32_t) resplen, p_cbw->total_bytes);
- TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_in, _mscd_buf, p_msc->total_len) );
+ TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_in, _mscd_buf, (uint16_t) p_msc->total_len) );
}
}
}
@@ -541,7 +541,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
// OUT transfer, invoke callback if needed
if ( !is_data_in(p_cbw->dir) )
{
- int32_t cb_result = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, _mscd_buf, p_msc->total_len);
+ int32_t cb_result = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, _mscd_buf, (uint16_t) p_msc->total_len);
if ( cb_result < 0 )
{
@@ -707,7 +707,7 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_
read_capa10.block_size = tu_htonl(block_size);
resplen = sizeof(read_capa10);
- memcpy(buffer, &read_capa10, resplen);
+ TU_VERIFY(0 == tu_memcpy_s(buffer, bufsize, &read_capa10, (size_t) resplen));
}
}
break;
@@ -741,7 +741,7 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_
read_fmt_capa.block_size_u16 = tu_htons(block_size);
resplen = sizeof(read_fmt_capa);
- memcpy(buffer, &read_fmt_capa, resplen);
+ TU_VERIFY(0 == tu_memcpy_s(buffer, bufsize, &read_fmt_capa, (size_t) resplen));
}
}
break;
@@ -764,7 +764,7 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_
tud_msc_inquiry_cb(lun, inquiry_rsp.vendor_id, inquiry_rsp.product_id, inquiry_rsp.product_rev);
resplen = sizeof(inquiry_rsp);
- memcpy(buffer, &inquiry_rsp, resplen);
+ TU_VERIFY(0 == tu_memcpy_s(buffer, bufsize, &inquiry_rsp, (size_t) resplen));
}
break;
@@ -788,7 +788,7 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_
mode_resp.write_protected = !writable;
resplen = sizeof(mode_resp);
- memcpy(buffer, &mode_resp, resplen);
+ TU_VERIFY(0 == tu_memcpy_s(buffer, bufsize, &mode_resp, (size_t) resplen));
}
break;
@@ -801,17 +801,17 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_
};
sense_rsp.add_sense_len = sizeof(scsi_sense_fixed_resp_t) - 8;
- sense_rsp.sense_key = p_msc->sense_key;
+ sense_rsp.sense_key = (uint8_t) (p_msc->sense_key & 0x0F);
sense_rsp.add_sense_code = p_msc->add_sense_code;
sense_rsp.add_sense_qualifier = p_msc->add_sense_qualifier;
resplen = sizeof(sense_rsp);
- memcpy(buffer, &sense_rsp, resplen);
+ TU_VERIFY(0 == tu_memcpy_s(buffer, bufsize, &sense_rsp, (size_t) resplen));
// request sense callback could overwrite the sense data
if (tud_msc_request_sense_cb)
{
- resplen = tud_msc_request_sense_cb(lun, buffer, bufsize);
+ resplen = tud_msc_request_sense_cb(lun, buffer, (uint16_t) bufsize);
}
// Clear sense data after copy
@@ -859,7 +859,7 @@ static void proc_read10_cmd(uint8_t rhport, mscd_interface_t* p_msc)
}
else
{
- TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_in, _mscd_buf, nbytes), );
+ TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_in, _mscd_buf, (uint16_t) nbytes), );
}
}
@@ -883,7 +883,7 @@ static void proc_write10_cmd(uint8_t rhport, mscd_interface_t* p_msc)
}
// remaining bytes capped at class buffer
- int32_t nbytes = (int32_t) tu_min32(sizeof(_mscd_buf), p_cbw->total_bytes-p_msc->xferred_len);
+ uint16_t nbytes = (uint16_t) tu_min32(sizeof(_mscd_buf), p_cbw->total_bytes-p_msc->xferred_len);
// Write10 callback will be called later when usb transfer complete
TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_out, _mscd_buf, nbytes), );
@@ -921,14 +921,15 @@ static void proc_write10_new_data(uint8_t rhport, mscd_interface_t* p_msc, uint3
// Application consume less than what we got (including zero)
if ( (uint32_t) nbytes < xferred_bytes )
{
+ uint32_t const left_over = xferred_bytes - (uint32_t) nbytes;
if ( nbytes > 0 )
{
- p_msc->xferred_len += nbytes;
- memmove(_mscd_buf, _mscd_buf+nbytes, xferred_bytes-nbytes);
+ p_msc->xferred_len += (uint16_t) nbytes;
+ memmove(_mscd_buf, _mscd_buf+nbytes, left_over);
}
// simulate an transfer complete with adjusted parameters --> callback will be invoked with adjusted parameter
- dcd_event_xfer_complete(rhport, p_msc->ep_out, xferred_bytes-nbytes, XFER_RESULT_SUCCESS, false);
+ dcd_event_xfer_complete(rhport, p_msc->ep_out, left_over, XFER_RESULT_SUCCESS, false);
}
else
{
diff --git a/src/class/msc/msc_device.h b/src/class/msc/msc_device.h
index 5839b168d..72f95be06 100644
--- a/src/class/msc/msc_device.h
+++ b/src/class/msc/msc_device.h
@@ -1,4 +1,4 @@
-/*
+/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c
index c54a63f37..1b48813ec 100644
--- a/src/class/msc/msc_host.c
+++ b/src/class/msc/msc_host.c
@@ -1,4 +1,4 @@
-/*
+/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
@@ -33,6 +33,11 @@
#include "msc_host.h"
+// Debug level, TUSB_CFG_DEBUG must be at least this level for debug message
+#define MSCH_DEBUG 2
+
+#define TU_LOG_MSCH(...) TU_LOG(MSCH_DEBUG, __VA_ARGS__)
+
//--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF
//--------------------------------------------------------------------+
@@ -64,16 +69,17 @@ typedef struct
uint8_t stage;
void* buffer;
tuh_msc_complete_cb_t complete_cb;
+ uintptr_t complete_arg;
- msc_cbw_t cbw;
- msc_csw_t csw;
+ CFG_TUH_MEM_ALIGN msc_cbw_t cbw;
+ CFG_TUH_MEM_ALIGN msc_csw_t csw;
}msch_interface_t;
-CFG_TUSB_MEM_SECTION static msch_interface_t _msch_itf[CFG_TUH_DEVICE_MAX];
+CFG_TUH_MEM_SECTION static msch_interface_t _msch_itf[CFG_TUH_DEVICE_MAX];
// 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)
+CFG_TUH_MEM_SECTION CFG_TUH_MEM_ALIGN
static uint8_t _msch_buffer[sizeof(scsi_inquiry_resp_t)];
TU_ATTR_ALWAYS_INLINE
@@ -126,7 +132,7 @@ static inline void cbw_init(msc_cbw_t *cbw, uint8_t lun)
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)
+bool tuh_msc_scsi_command(uint8_t dev_addr, msc_cbw_t const* cbw, void* data, tuh_msc_complete_cb_t complete_cb, uintptr_t arg)
{
msch_interface_t* p_msc = get_itf(dev_addr);
TU_VERIFY(p_msc->configured);
@@ -137,13 +143,14 @@ bool tuh_msc_scsi_command(uint8_t dev_addr, msc_cbw_t const* cbw, void* data, tu
p_msc->stage = MSC_STAGE_CMD;
p_msc->buffer = data;
p_msc->complete_cb = complete_cb;
+ p_msc->complete_arg = arg;
TU_ASSERT(usbh_edpt_xfer(dev_addr, p_msc->ep_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cbw_t)));
return true;
}
-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)
+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, uintptr_t arg)
{
msch_interface_t* p_msc = get_itf(dev_addr);
TU_VERIFY(p_msc->configured);
@@ -156,10 +163,10 @@ bool tuh_msc_read_capacity(uint8_t dev_addr, uint8_t lun, scsi_read_capacity10_r
cbw.cmd_len = sizeof(scsi_read_capacity10_t);
cbw.command[0] = SCSI_CMD_READ_CAPACITY_10;
- return tuh_msc_scsi_command(dev_addr, &cbw, response, complete_cb);
+ return tuh_msc_scsi_command(dev_addr, &cbw, response, complete_cb, arg);
}
-bool tuh_msc_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, uintptr_t arg)
{
msch_interface_t* p_msc = get_itf(dev_addr);
TU_VERIFY(p_msc->mounted);
@@ -178,10 +185,10 @@ bool tuh_msc_inquiry(uint8_t dev_addr, uint8_t lun, scsi_inquiry_resp_t* respons
};
memcpy(cbw.command, &cmd_inquiry, cbw.cmd_len);
- return tuh_msc_scsi_command(dev_addr, &cbw, response, complete_cb);
+ return tuh_msc_scsi_command(dev_addr, &cbw, response, complete_cb, arg);
}
-bool tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, tuh_msc_complete_cb_t complete_cb)
+bool tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, tuh_msc_complete_cb_t complete_cb, uintptr_t arg)
{
msch_interface_t* p_msc = get_itf(dev_addr);
TU_VERIFY(p_msc->configured);
@@ -195,10 +202,10 @@ bool tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, tuh_msc_complete_cb_
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);
+ return tuh_msc_scsi_command(dev_addr, &cbw, NULL, complete_cb, arg);
}
-bool tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, void *resposne, tuh_msc_complete_cb_t complete_cb)
+bool tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, void *response, tuh_msc_complete_cb_t complete_cb, uintptr_t arg)
{
msc_cbw_t cbw;
cbw_init(&cbw, lun);
@@ -215,34 +222,34 @@ bool tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, void *resposne, tuh_ms
memcpy(cbw.command, &cmd_request_sense, cbw.cmd_len);
- return tuh_msc_scsi_command(dev_addr, &cbw, resposne, complete_cb);
+ return tuh_msc_scsi_command(dev_addr, &cbw, response, complete_cb, arg);
}
-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)
+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, uintptr_t arg)
{
msch_interface_t* p_msc = get_itf(dev_addr);
TU_VERIFY(p_msc->mounted);
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)
};
-
+
memcpy(cbw.command, &cmd_read10, cbw.cmd_len);
-
- return tuh_msc_scsi_command(dev_addr, &cbw, buffer, complete_cb);
+
+ return tuh_msc_scsi_command(dev_addr, &cbw, buffer, complete_cb, arg);
}
-
-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)
+
+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, uintptr_t arg)
{
msch_interface_t* p_msc = get_itf(dev_addr);
TU_VERIFY(p_msc->mounted);
@@ -263,7 +270,7 @@ bool tuh_msc_write10(uint8_t dev_addr, uint8_t lun, void const * buffer, uint32_
memcpy(cbw.command, &cmd_write10, cbw.cmd_len);
- return tuh_msc_scsi_command(dev_addr, &cbw, (void*)(uintptr_t) buffer, complete_cb);
+ return tuh_msc_scsi_command(dev_addr, &cbw, (void*)(uintptr_t) buffer, complete_cb, arg);
}
#if 0
@@ -325,26 +332,36 @@ bool msch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32
p_msc->stage = MSC_STAGE_DATA;
uint8_t const ep_data = (cbw->dir & TUSB_DIR_IN_MASK) ? p_msc->ep_in : p_msc->ep_out;
- TU_ASSERT(usbh_edpt_xfer(dev_addr, ep_data, p_msc->buffer, cbw->total_bytes));
+ TU_ASSERT(usbh_edpt_xfer(dev_addr, ep_data, p_msc->buffer, (uint16_t) cbw->total_bytes));
}else
{
// Status stage
p_msc->stage = MSC_STAGE_STATUS;
- TU_ASSERT(usbh_edpt_xfer(dev_addr, p_msc->ep_in, (uint8_t*) &p_msc->csw, sizeof(msc_csw_t)));
+ TU_ASSERT(usbh_edpt_xfer(dev_addr, p_msc->ep_in, (uint8_t*) &p_msc->csw, (uint16_t) sizeof(msc_csw_t)));
}
break;
case MSC_STAGE_DATA:
// Status stage
p_msc->stage = MSC_STAGE_STATUS;
- TU_ASSERT(usbh_edpt_xfer(dev_addr, p_msc->ep_in, (uint8_t*) &p_msc->csw, sizeof(msc_csw_t)));
+ TU_ASSERT(usbh_edpt_xfer(dev_addr, p_msc->ep_in, (uint8_t*) &p_msc->csw, (uint16_t) sizeof(msc_csw_t)));
break;
case MSC_STAGE_STATUS:
// SCSI op is complete
p_msc->stage = MSC_STAGE_IDLE;
- if (p_msc->complete_cb) p_msc->complete_cb(dev_addr, cbw, csw);
+ if (p_msc->complete_cb)
+ {
+ tuh_msc_complete_data_t const cb_data =
+ {
+ .cbw = cbw,
+ .csw = csw,
+ .scsi_data = p_msc->buffer,
+ .user_arg = p_msc->complete_arg
+ };
+ p_msc->complete_cb(dev_addr, &cb_data);
+ }
break;
// unknown state
@@ -359,9 +376,9 @@ bool msch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32
//--------------------------------------------------------------------+
static void config_get_maxlun_complete (tuh_xfer_t* xfer);
-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);
+static bool config_test_unit_ready_complete(uint8_t dev_addr, tuh_msc_complete_data_t const * cb_data);
+static bool config_request_sense_complete(uint8_t dev_addr, tuh_msc_complete_data_t const* cb_data);
+static bool config_read_capacity_complete(uint8_t dev_addr, tuh_msc_complete_data_t const* cb_data);
bool msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len)
{
@@ -370,7 +387,7 @@ bool msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *de
MSC_PROTOCOL_BOT == desc_itf->bInterfaceProtocol);
// msc driver length is fixed
- uint16_t const drv_len = sizeof(tusb_desc_interface_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t);
+ uint16_t const drv_len = (uint16_t) (sizeof(tusb_desc_interface_t) + desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t));
TU_ASSERT(drv_len <= max_len);
msch_interface_t* p_msc = get_itf(dev_addr);
@@ -405,7 +422,7 @@ bool msch_set_config(uint8_t dev_addr, uint8_t itf_num)
p_msc->configured = true;
//------------- Get Max Lun -------------//
- TU_LOG2("MSC Get Max Lun\r\n");
+ TU_LOG_MSCH("MSC Get Max Lun\r\n");
tusb_control_request_t const request =
{
.bmRequestType_bit =
@@ -444,39 +461,48 @@ static void config_get_maxlun_complete (tuh_xfer_t* xfer)
p_msc->max_lun++; // MAX LUN is minus 1 by specs
// TODO multiple LUN support
- TU_LOG2("SCSI Test Unit Ready\r\n");
+ TU_LOG_MSCH("SCSI Test Unit Ready\r\n");
uint8_t const lun = 0;
- tuh_msc_test_unit_ready(daddr, lun, config_test_unit_ready_complete);
+ tuh_msc_test_unit_ready(daddr, lun, config_test_unit_ready_complete, 0);
}
-static bool config_test_unit_ready_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw)
+static bool config_test_unit_ready_complete(uint8_t dev_addr, tuh_msc_complete_data_t const * cb_data)
{
+ msc_cbw_t const* cbw = cb_data->cbw;
+ msc_csw_t const* csw = cb_data->csw;
+
if (csw->status == 0)
{
// 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*) ((void*) _msch_buffer), config_read_capacity_complete);
+ TU_LOG_MSCH("SCSI Read Capacity\r\n");
+ tuh_msc_read_capacity(dev_addr, cbw->lun, (scsi_read_capacity10_resp_t*) ((void*) _msch_buffer), config_read_capacity_complete, 0);
}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_LOG2("SCSI Request Sense\r\n");
- TU_ASSERT(tuh_msc_request_sense(dev_addr, cbw->lun, _msch_buffer, config_request_sense_complete));
+ TU_LOG_MSCH("SCSI Request Sense\r\n");
+ TU_ASSERT(tuh_msc_request_sense(dev_addr, cbw->lun, _msch_buffer, config_request_sense_complete, 0));
}
return true;
}
-static bool config_request_sense_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, tuh_msc_complete_data_t const * cb_data)
{
+ msc_cbw_t const* cbw = cb_data->cbw;
+ msc_csw_t const* csw = cb_data->csw;
+
TU_ASSERT(csw->status == 0);
- TU_ASSERT(tuh_msc_test_unit_ready(dev_addr, cbw->lun, config_test_unit_ready_complete));
+ TU_ASSERT(tuh_msc_test_unit_ready(dev_addr, cbw->lun, config_test_unit_ready_complete, 0));
return true;
}
-static bool config_read_capacity_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, tuh_msc_complete_data_t const * cb_data)
{
+ msc_cbw_t const* cbw = cb_data->cbw;
+ msc_csw_t const* csw = cb_data->csw;
+
TU_ASSERT(csw->status == 0);
msch_interface_t* p_msc = get_itf(dev_addr);
diff --git a/src/class/msc/msc_host.h b/src/class/msc/msc_host.h
index 7718ad4fe..6c0e5c9dd 100644
--- a/src/class/msc/msc_host.h
+++ b/src/class/msc/msc_host.h
@@ -1,4 +1,4 @@
-/*
+/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
@@ -41,7 +41,14 @@
#define CFG_TUH_MSC_MAXLUN 4
#endif
-typedef bool (*tuh_msc_complete_cb_t)(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw);
+typedef struct {
+ msc_cbw_t const* cbw; // SCSI command
+ msc_csw_t const* csw; // SCSI status
+ void* scsi_data; // SCSI Data
+ uintptr_t user_arg; // user argument
+}tuh_msc_complete_data_t;
+
+typedef bool (*tuh_msc_complete_cb_t)(uint8_t dev_addr, tuh_msc_complete_data_t const* cb_data);
//--------------------------------------------------------------------+
// Application API
@@ -66,33 +73,33 @@ 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);
+bool tuh_msc_scsi_command(uint8_t dev_addr, msc_cbw_t const* cbw, void* data, tuh_msc_complete_cb_t complete_cb, uintptr_t arg);
// 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);
+bool tuh_msc_inquiry(uint8_t dev_addr, uint8_t lun, scsi_inquiry_resp_t* response, tuh_msc_complete_cb_t complete_cb, uintptr_t arg);
// 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);
+bool tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, tuh_msc_complete_cb_t complete_cb, uintptr_t arg);
// 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);
+bool tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, void *response, tuh_msc_complete_cb_t complete_cb, uintptr_t arg);
// 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);
+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, uintptr_t arg);
// 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);
+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, uintptr_t arg);
// 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);
+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, uintptr_t arg);
//------------- Application Callback -------------//