defer proc_async_io_done()
This commit is contained in:
@@ -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);
|
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;
|
mscd_interface_t *p_msc = &_mscd_itf;
|
||||||
TU_VERIFY(p_msc->pending_io, );
|
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];
|
const uint8_t cmd = p_msc->cbw.command[0];
|
||||||
|
|
||||||
p_msc->pending_io = 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
|
// Precheck to avoid queueing multiple RW done callback
|
||||||
TU_VERIFY(_mscd_itf.pending_io);
|
TU_VERIFY(_mscd_itf.pending_io);
|
||||||
if (bytes_io == 0) {
|
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
|
||||||
}
|
}
|
||||||
|
usbd_defer_func(proc_async_io_done, (void *) (intptr_t) bytes_io, in_isr);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
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) {
|
static void proc_read_io_data(mscd_interface_t* p_msc, int32_t nbytes) {
|
||||||
uint8_t rhport = p_msc->rhport;
|
const uint8_t rhport = p_msc->rhport;
|
||||||
if (nbytes == TUD_MSC_RET_ERROR) {
|
if (nbytes > 0) {
|
||||||
// error -> endpoint is stalled & status in CSW set to failed
|
|
||||||
TU_LOG_DRV(" IO read() failed\r\n");
|
|
||||||
|
|
||||||
// set sense
|
|
||||||
msc_cbw_t const* p_cbw = &p_msc->cbw;
|
|
||||||
set_sense_medium_not_present(p_cbw->lun);
|
|
||||||
|
|
||||||
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),);
|
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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
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) {
|
static void proc_write_io_data(mscd_interface_t* p_msc, uint32_t xferred_bytes, int32_t nbytes) {
|
||||||
if (nbytes < 0) {
|
if (nbytes < 0) {
|
||||||
// negative means error -> failed this scsi op
|
// nbytes is status
|
||||||
TU_LOG_DRV(" IO write() failed\r\n");
|
switch (nbytes) {
|
||||||
set_sense_medium_not_present(p_msc->cbw.lun);
|
case TUD_MSC_RET_ERROR:
|
||||||
fail_scsi_op(p_msc, MSC_CSW_STATUS_FAILED);
|
// 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 {
|
} else {
|
||||||
if ((uint32_t)nbytes < xferred_bytes) {
|
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;
|
const uint32_t left_over = xferred_bytes - (uint32_t)nbytes;
|
||||||
if (nbytes > 0) {
|
if (nbytes > 0) {
|
||||||
memmove(_mscd_epbuf.buf, _mscd_epbuf.buf + nbytes, left_over);
|
memmove(_mscd_epbuf.buf, _mscd_epbuf.buf + nbytes, left_over);
|
||||||
|
@@ -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.
|
- 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.
|
- 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.
|
- 0 < ret < bufsize: These bytes are transferred first and callback will be invoked again for remaining data.
|
||||||
- ret == TUD_MSC_RET_BUSY
|
- TUD_MSC_RET_BUSY
|
||||||
Application is buys e.g disk I/O not ready.
|
Application is buys e.g disk I/O not ready. Callback will be invoked again with the same parameters later on.
|
||||||
Callback will be invoked again with the same parameters later on.
|
- TUD_MSC_RET_ERROR
|
||||||
- ret == TUD_MSC_RET_ERROR
|
|
||||||
error such as invalid address. This request will be STALLed and scsi command will be failed
|
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.
|
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.
|
tud_msc_async_io_done() must be called once IO/ is done to signal completion.
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user