|
|
@@ -64,6 +64,7 @@ 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;
|
|
|
@@ -126,7 +127,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 +138,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 +158,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 +180,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 +197,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 *resposne, tuh_msc_complete_cb_t complete_cb, uintptr_t arg)
|
|
|
{
|
|
|
msc_cbw_t cbw;
|
|
|
cbw_init(&cbw, lun);
|
|
|
@@ -215,10 +217,10 @@ 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, resposne, 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);
|
|
|
@@ -239,10 +241,10 @@ bool tuh_msc_read10(uint8_t dev_addr, uint8_t lun, void * buffer, uint32_t lba,
|
|
|
|
|
|
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 +265,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
|
|
|
@@ -344,7 +346,17 @@ bool msch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32
|
|
|
// 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 +371,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)
|
|
|
{
|
|
|
@@ -446,37 +458,46 @@ static void config_get_maxlun_complete (tuh_xfer_t* xfer)
|
|
|
// TODO multiple LUN support
|
|
|
TU_LOG2("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);
|
|
|
+ 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_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);
|