Use return code to choose async io.
Signed-off-by: HiFiPhile <admin@hifiphile.com>
This commit is contained in:
@@ -78,10 +78,10 @@ typedef struct {
|
|||||||
uint8_t sense_key;
|
uint8_t sense_key;
|
||||||
uint8_t add_sense_code;
|
uint8_t add_sense_code;
|
||||||
uint8_t add_sense_qualifier;
|
uint8_t add_sense_qualifier;
|
||||||
#if CFG_TUD_MSC_ASYNC_IO
|
|
||||||
|
// Async IO
|
||||||
uint8_t next_op;
|
uint8_t next_op;
|
||||||
uint32_t xferred_bytes;
|
uint32_t xferred_bytes;
|
||||||
#endif
|
|
||||||
}mscd_interface_t;
|
}mscd_interface_t;
|
||||||
|
|
||||||
static mscd_interface_t _mscd_itf;
|
static mscd_interface_t _mscd_itf;
|
||||||
@@ -100,9 +100,7 @@ static void proc_write10_cmd(mscd_interface_t* p_msc);
|
|||||||
static void proc_write10_new_data(mscd_interface_t* p_msc, uint32_t xferred_bytes);
|
static void proc_write10_new_data(mscd_interface_t* p_msc, uint32_t xferred_bytes);
|
||||||
static void proc_write10_next(mscd_interface_t* p_msc, uint32_t xferred_bytes, int32_t nbytes);
|
static void proc_write10_next(mscd_interface_t* p_msc, uint32_t xferred_bytes, int32_t nbytes);
|
||||||
static bool proc_stage_status(mscd_interface_t* p_msc);
|
static bool proc_stage_status(mscd_interface_t* p_msc);
|
||||||
#if CFG_TUD_MSC_ASYNC_IO
|
|
||||||
static void tud_msc_async_io_done_cb(void* bytes_processed);
|
static void tud_msc_async_io_done_cb(void* bytes_processed);
|
||||||
#endif
|
|
||||||
|
|
||||||
TU_ATTR_ALWAYS_INLINE static inline bool is_data_in(uint8_t dir) {
|
TU_ATTR_ALWAYS_INLINE static inline bool is_data_in(uint8_t dir) {
|
||||||
return tu_bit_test(dir, 7);
|
return tu_bit_test(dir, 7);
|
||||||
@@ -265,7 +263,6 @@ static inline void set_sense_medium_not_present(uint8_t lun) {
|
|||||||
tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x3A, 0x00);
|
tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x3A, 0x00);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CFG_TUD_MSC_ASYNC_IO
|
|
||||||
void tud_msc_async_io_done(int32_t bytes_processed) {
|
void tud_msc_async_io_done(int32_t bytes_processed) {
|
||||||
// Precheck to avoid queueing multiple RW done callback
|
// Precheck to avoid queueing multiple RW done callback
|
||||||
TU_VERIFY(_mscd_itf.next_op != MSC_NEXT_OP_NONE,);
|
TU_VERIFY(_mscd_itf.next_op != MSC_NEXT_OP_NONE,);
|
||||||
@@ -289,7 +286,6 @@ static void tud_msc_async_io_done_cb(void* bytes_processed) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// USBD Driver API
|
// USBD Driver API
|
||||||
@@ -821,13 +817,12 @@ static void proc_read10_cmd(mscd_interface_t* p_msc) {
|
|||||||
// Application can consume smaller bytes
|
// Application can consume smaller bytes
|
||||||
uint32_t const offset = p_msc->xferred_len % block_sz;
|
uint32_t const offset = p_msc->xferred_len % block_sz;
|
||||||
|
|
||||||
#if CFG_TUD_MSC_ASYNC_IO
|
|
||||||
p_msc->next_op = MSC_NEXT_OP_READ10;
|
p_msc->next_op = MSC_NEXT_OP_READ10;
|
||||||
tud_msc_read10_cb(p_cbw->lun, lba, offset, _mscd_epbuf.buf, (uint32_t)nbytes);
|
|
||||||
#else
|
|
||||||
nbytes = tud_msc_read10_cb(p_cbw->lun, lba, offset, _mscd_epbuf.buf, (uint32_t)nbytes);
|
nbytes = tud_msc_read10_cb(p_cbw->lun, lba, offset, _mscd_epbuf.buf, (uint32_t)nbytes);
|
||||||
proc_read10_next(p_msc, nbytes);
|
if (nbytes != TUD_MSC_RET_ASYNC) {
|
||||||
#endif
|
p_msc->next_op = MSC_NEXT_OP_NONE;
|
||||||
|
proc_read10_next(p_msc, nbytes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void proc_read10_next(mscd_interface_t* p_msc, int32_t nbytes) {
|
static void proc_read10_next(mscd_interface_t* p_msc, int32_t nbytes) {
|
||||||
@@ -885,14 +880,13 @@ static void proc_write10_new_data(mscd_interface_t* p_msc, uint32_t xferred_byte
|
|||||||
// Invoke callback to consume new data
|
// Invoke callback to consume new data
|
||||||
uint32_t const offset = p_msc->xferred_len % block_sz;
|
uint32_t const offset = p_msc->xferred_len % block_sz;
|
||||||
|
|
||||||
#if CFG_TUD_MSC_ASYNC_IO
|
|
||||||
p_msc->next_op = MSC_NEXT_OP_WRITE10;
|
p_msc->next_op = MSC_NEXT_OP_WRITE10;
|
||||||
p_msc->xferred_bytes = xferred_bytes;
|
p_msc->xferred_bytes = xferred_bytes;
|
||||||
tud_msc_write10_cb(p_cbw->lun, lba, offset, _mscd_epbuf.buf, xferred_bytes);
|
|
||||||
#else
|
|
||||||
int32_t nbytes = tud_msc_write10_cb(p_cbw->lun, lba, offset, _mscd_epbuf.buf, xferred_bytes);
|
int32_t nbytes = tud_msc_write10_cb(p_cbw->lun, lba, offset, _mscd_epbuf.buf, xferred_bytes);
|
||||||
proc_write10_next(p_msc, xferred_bytes, nbytes);
|
if (nbytes != TUD_MSC_RET_ASYNC) {
|
||||||
#endif
|
p_msc->next_op = MSC_NEXT_OP_NONE;
|
||||||
|
proc_write10_next(p_msc, xferred_bytes, nbytes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void proc_write10_next(mscd_interface_t* p_msc, uint32_t xferred_bytes, int32_t nbytes) {
|
static void proc_write10_next(mscd_interface_t* p_msc, uint32_t xferred_bytes, int32_t nbytes) {
|
||||||
|
@@ -48,10 +48,11 @@
|
|||||||
#error CFG_TUD_MSC_EP_BUFSIZE must be defined, value of a block size should work well, the more the better
|
#error CFG_TUD_MSC_EP_BUFSIZE must be defined, value of a block size should work well, the more the better
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Enable asynchronous read/write, once operation is finished tud_msc_async_io_done() must be called
|
// Return value of callback functions
|
||||||
#ifndef CFG_TUD_MSC_ASYNC_IO
|
// Error
|
||||||
#define CFG_TUD_MSC_ASYNC_IO 0
|
#define TUD_MSC_RET_ERROR -1
|
||||||
#endif
|
// Asynchronous IO
|
||||||
|
#define TUD_MSC_RET_ASYNC -16
|
||||||
|
|
||||||
TU_VERIFY_STATIC(CFG_TUD_MSC_EP_BUFSIZE < UINT16_MAX, "Size is not correct");
|
TU_VERIFY_STATIC(CFG_TUD_MSC_EP_BUFSIZE < UINT16_MAX, "Size is not correct");
|
||||||
|
|
||||||
@@ -62,6 +63,11 @@ TU_VERIFY_STATIC(CFG_TUD_MSC_EP_BUFSIZE < UINT16_MAX, "Size is not correct");
|
|||||||
// Set SCSI sense response
|
// Set SCSI sense response
|
||||||
bool tud_msc_set_sense(uint8_t lun, uint8_t sense_key, uint8_t add_sense_code, uint8_t add_sense_qualifier);
|
bool tud_msc_set_sense(uint8_t lun, uint8_t sense_key, uint8_t add_sense_code, uint8_t add_sense_qualifier);
|
||||||
|
|
||||||
|
// Called once asynchronous read/write operation is done
|
||||||
|
// bytes_processed has the same meaning of tud_msc_read10_cb() /
|
||||||
|
// tud_msc_write10_cb() return value
|
||||||
|
void tud_msc_async_io_done(int32_t bytes_processed);
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Application Callbacks (WEAK is optional)
|
// Application Callbacks (WEAK is optional)
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
@@ -70,34 +76,40 @@ bool tud_msc_set_sense(uint8_t lun, uint8_t sense_key, uint8_t add_sense_code, u
|
|||||||
// - Address = lba * BLOCK_SIZE + offset
|
// - Address = lba * BLOCK_SIZE + offset
|
||||||
// - 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 read byte. If
|
// - Application fill the buffer (up to bufsize) with address contents and return number of bytes read or status.
|
||||||
// - read < bufsize : These bytes are transferred first and callback invoked again for remaining data.
|
|
||||||
//
|
//
|
||||||
// - read == 0 : Indicate application is not ready yet e.g disk I/O busy.
|
// - ret < bufsize : These bytes are transferred first and callback will be invoked again for remaining data.
|
||||||
// Callback invoked again with the same parameters later on.
|
|
||||||
//
|
//
|
||||||
// - read < 0 : Indicate application error e.g invalid address. This request will be STALLed
|
// - ret == 0 : Indicate application is not ready yet e.g disk I/O busy.
|
||||||
|
// Callback will be invoked again with the same parameters later on.
|
||||||
|
//
|
||||||
|
// - ret == TUD_MSC_RET_ERROR (-1)
|
||||||
|
// : Indicate application error e.g invalid address. This request will be STALLed
|
||||||
// and return failed status in command status wrapper phase.
|
// and return failed status in command status wrapper phase.
|
||||||
//
|
//
|
||||||
// - In case of asynchronous IO enabled, application should passing reading parameters to background IO
|
// - ret == TUD_MSC_RET_ASYNC (-16)
|
||||||
// task and return immediately. Once reading is done, tud_msc_async_io_done() must be called.
|
// : Data reading will be done asynchronously in a background task. Application should return immediately.
|
||||||
|
// tud_msc_async_io_done() must be called once reading is done to signal completion.
|
||||||
int32_t tud_msc_read10_cb (uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize);
|
int32_t tud_msc_read10_cb (uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize);
|
||||||
|
|
||||||
// Invoked when received SCSI WRITE10 command
|
// Invoked when received SCSI WRITE10 command
|
||||||
// - Address = lba * BLOCK_SIZE + offset
|
// - Address = lba * BLOCK_SIZE + offset
|
||||||
// - 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 write data from buffer to address contents (up to bufsize) and return number of written byte. If
|
// - Application writes data from buffer to address contents (up to bufsize) and returns the number of bytes written or status.
|
||||||
// - write < bufsize : callback invoked again with remaining data later on.
|
|
||||||
//
|
//
|
||||||
// - write == 0 : Indicate application is not ready yet e.g disk I/O busy.
|
// - ret < bufsize : Callback will be invoked again with remaining data later on.
|
||||||
// Callback invoked again with the same parameters later on.
|
|
||||||
//
|
//
|
||||||
// - write < 0 : Indicate application error e.g invalid address. This request will be STALLed
|
// - ret == 0 : Indicate application is not ready yet e.g disk I/O busy.
|
||||||
// and return failed status in command status wrapper phase.
|
// Callback will be invoked again with the same parameters later on.
|
||||||
//
|
//
|
||||||
// - In case of asynchronous IO enabled, application should passing writing parameters to background IO
|
// - ret == TUD_MSC_RET_ERROR (-1)
|
||||||
// task and return immediately. Once writing is done, tud_msc_async_io_done() must be called.
|
// : Indicate application error e.g invalid address. This request will be STALLed
|
||||||
|
// and return failed status in command status wrapper phase.
|
||||||
|
//
|
||||||
|
// - ret == TUD_MSC_RET_ASYNC (-16)
|
||||||
|
// : Data writing will be done asynchronously in a background task. Application should return immediately.
|
||||||
|
// tud_msc_async_io_done() must be called once writing is done to signal completion.
|
||||||
// TODO change buffer to const uint8_t*
|
// TODO change buffer to const uint8_t*
|
||||||
int32_t tud_msc_write10_cb (uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize);
|
int32_t tud_msc_write10_cb (uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize);
|
||||||
|
|
||||||
@@ -131,12 +143,6 @@ void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_siz
|
|||||||
*/
|
*/
|
||||||
int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize);
|
int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize);
|
||||||
|
|
||||||
#if CFG_TUD_MSC_ASYNC_IO
|
|
||||||
// Called once asynchronous read/write operation is done
|
|
||||||
// bytes_processed has the same meaning of tud_msc_read10_cb() /
|
|
||||||
// tud_msc_write10_cb() return value
|
|
||||||
void tud_msc_async_io_done(int32_t bytes_processed);
|
|
||||||
#endif
|
|
||||||
/*------------- Optional callbacks -------------*/
|
/*------------- Optional callbacks -------------*/
|
||||||
|
|
||||||
// Invoked when received GET_MAX_LUN request, required for multiple LUNs implementation
|
// Invoked when received GET_MAX_LUN request, required for multiple LUNs implementation
|
||||||
|
Reference in New Issue
Block a user