summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhathach <[email protected]>2025-07-01 21:52:57 +0700
committerhathach <[email protected]>2025-07-01 22:17:38 +0700
commitc96cc4369f1b97efe85575f3e5633e38598e9fc2 (patch)
treed1c4c18b039f89fecbe9bb69442ef3a32357aca6
parent216a35e59a095e6ccb70f7c9bd4f7bc737f44140 (diff)
defer proc_async_io_done()
-rw-r--r--src/class/msc/msc_device.c62
-rw-r--r--src/class/msc/msc_device.h9
2 files changed, 38 insertions, 33 deletions
diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c
index a8c52b6bd..747ad03ed 100644
--- a/src/class/msc/msc_device.c
+++ b/src/class/msc/msc_device.c
@@ -254,10 +254,10 @@ TU_ATTR_ALWAYS_INLINE static inline void set_sense_medium_not_present(uint8_t lu
tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x3A, 0x00);
}
-static void proc_async_io_done(void *bytes_processed) {
+static void proc_async_io_done(void *bytes_io) {
mscd_interface_t *p_msc = &_mscd_itf;
TU_VERIFY(p_msc->pending_io, );
- const int32_t nbytes = (int32_t) (intptr_t) bytes_processed;
+ const int32_t nbytes = (int32_t) (intptr_t) bytes_io;
const uint8_t cmd = p_msc->cbw.command[0];
p_msc->pending_io = 0;
@@ -283,15 +283,9 @@ bool tud_msc_async_io_done(int32_t bytes_io, bool in_isr) {
// Precheck to avoid queueing multiple RW done callback
TU_VERIFY(_mscd_itf.pending_io);
if (bytes_io == 0) {
- bytes_io = TUD_MSC_RET_ERROR; // 0 is treated as error, no sense to call this with BUSY here
+ bytes_io = TUD_MSC_RET_ERROR; // 0 is treated as error, no reason to call this with BUSY here
}
-
- if (in_isr) {
- usbd_defer_func(proc_async_io_done, (void*) (intptr_t)bytes_io, in_isr);
- } else {
- proc_async_io_done((void*)(intptr_t) bytes_io);
- }
-
+ usbd_defer_func(proc_async_io_done, (void *) (intptr_t) bytes_io, in_isr);
return true;
}
@@ -827,21 +821,26 @@ static void proc_read10_cmd(mscd_interface_t* p_msc) {
}
static void proc_read_io_data(mscd_interface_t* p_msc, int32_t nbytes) {
- uint8_t rhport = p_msc->rhport;
- if (nbytes == TUD_MSC_RET_ERROR) {
- // error -> endpoint is stalled & status in CSW set to failed
- TU_LOG_DRV(" IO read() failed\r\n");
+ const uint8_t rhport = p_msc->rhport;
+ if (nbytes > 0) {
+ TU_ASSERT(usbd_edpt_xfer(rhport, p_msc->ep_in, _mscd_epbuf.buf, (uint16_t) nbytes),);
+ } else {
+ // nbytes is status
+ switch (nbytes) {
+ case TUD_MSC_RET_ERROR:
+ // error -> endpoint is stalled & status in CSW set to failed
+ TU_LOG_DRV(" IO read() failed\r\n");
+ set_sense_medium_not_present(p_msc->cbw.lun);
+ fail_scsi_op(p_msc, MSC_CSW_STATUS_FAILED);
+ break;
- // set sense
- msc_cbw_t const* p_cbw = &p_msc->cbw;
- set_sense_medium_not_present(p_cbw->lun);
+ case TUD_MSC_RET_BUSY:
+ // not ready yet -> fake a transfer complete so that this driver callback will fire again
+ dcd_event_xfer_complete(rhport, p_msc->ep_in, 0, XFER_RESULT_SUCCESS, false);
+ break;
- fail_scsi_op(p_msc, MSC_CSW_STATUS_FAILED);
- } else if (nbytes == TUD_MSC_RET_BUSY) {
- // zero means not ready -> fake a transfer complete so that this driver callback will fire again
- dcd_event_xfer_complete(rhport, p_msc->ep_in, 0, XFER_RESULT_SUCCESS, false);
- } else {
- TU_ASSERT(usbd_edpt_xfer(rhport, p_msc->ep_in, _mscd_epbuf.buf, (uint16_t) nbytes),);
+ default: break;
+ }
}
}
@@ -886,13 +885,20 @@ static void proc_write10_host_data(mscd_interface_t* p_msc, uint32_t xferred_byt
static void proc_write_io_data(mscd_interface_t* p_msc, uint32_t xferred_bytes, int32_t nbytes) {
if (nbytes < 0) {
- // negative means error -> failed this scsi op
- TU_LOG_DRV(" IO write() failed\r\n");
- set_sense_medium_not_present(p_msc->cbw.lun);
- fail_scsi_op(p_msc, MSC_CSW_STATUS_FAILED);
+ // nbytes is status
+ switch (nbytes) {
+ case TUD_MSC_RET_ERROR:
+ // IO error -> failed this scsi op
+ TU_LOG_DRV(" IO write() failed\r\n");
+ set_sense_medium_not_present(p_msc->cbw.lun);
+ fail_scsi_op(p_msc, MSC_CSW_STATUS_FAILED);
+ break;
+
+ default: break;
+ }
} else {
if ((uint32_t)nbytes < xferred_bytes) {
- // Application consume less than what we got (including zero)
+ // Application consume less than what we got including TUD_MSC_RET_BUSY (0)
const uint32_t left_over = xferred_bytes - (uint32_t)nbytes;
if (nbytes > 0) {
memmove(_mscd_epbuf.buf, _mscd_epbuf.buf + nbytes, left_over);
diff --git a/src/class/msc/msc_device.h b/src/class/msc/msc_device.h
index 2ad31c245..f2ea256b4 100644
--- a/src/class/msc/msc_device.h
+++ b/src/class/msc/msc_device.h
@@ -79,12 +79,11 @@ bool tud_msc_async_io_done(int32_t bytes_io, bool in_isr);
- offset is only needed if CFG_TUD_MSC_EP_BUFSIZE is smaller than BLOCK_SIZE.
- Application fill the buffer (up to bufsize) with address contents and return number of bytes read or status.
- 0 < ret < bufsize: These bytes are transferred first and callback will be invoked again for remaining data.
- - ret == TUD_MSC_RET_BUSY
- Application is buys e.g disk I/O not ready.
- Callback will be invoked again with the same parameters later on.
- - ret == TUD_MSC_RET_ERROR
+ - TUD_MSC_RET_BUSY
+ Application is buys e.g disk I/O not ready. Callback will be invoked again with the same parameters later on.
+ - TUD_MSC_RET_ERROR
error such as invalid address. This request will be STALLed and scsi command will be failed
- - ret == TUD_MSC_RET_ASYNC
+ - TUD_MSC_RET_ASYNC
Data I/O will be done asynchronously in a background task. Application should return immediately.
tud_msc_async_io_done() must be called once IO/ is done to signal completion.
*/