diff --git a/examples/host/msc_file_explorer/src/msc_app.c b/examples/host/msc_file_explorer/src/msc_app.c index ddd39c674..035d74689 100644 --- a/examples/host/msc_file_explorer/src/msc_app.c +++ b/examples/host/msc_file_explorer/src/msc_app.c @@ -53,7 +53,11 @@ static CLI_UINT cli_buffer[BYTES_TO_CLI_UINTS(CLI_BUFFER_SIZE)]; static FATFS fatfs[CFG_TUH_DEVICE_MAX]; // for simplicity only support 1 LUN per device static volatile bool _disk_busy[CFG_TUH_DEVICE_MAX]; -static scsi_inquiry_resp_t inquiry_resp; +// define the buffer to be place in USB/DMA memory with correct alignment/cache line size +CFG_TUH_MEM_SECTION static struct { + TUH_EPBUF_TYPE_DEF(scsi_inquiry_resp_t, inquiry); +} scsi_resp; + //--------------------------------------------------------------------+ // @@ -107,7 +111,7 @@ bool inquiry_complete_cb(uint8_t dev_addr, tuh_msc_complete_data_t const * cb_da } // Print out Vendor ID, Product ID and Rev - printf("%.8s %.16s rev %.4s\r\n", inquiry_resp.vendor_id, inquiry_resp.product_id, inquiry_resp.product_rev); + printf("%.8s %.16s rev %.4s\r\n", scsi_resp.inquiry.vendor_id, scsi_resp.inquiry.product_id, scsi_resp.inquiry.product_rev); // Get capacity of device uint32_t const block_count = tuh_msc_get_block_count(dev_addr, cbw->lun); @@ -145,7 +149,7 @@ void tuh_msc_mount_cb(uint8_t dev_addr) printf("A MassStorage device is mounted\r\n"); uint8_t const lun = 0; - tuh_msc_inquiry(dev_addr, lun, &inquiry_resp, inquiry_complete_cb, 0); + tuh_msc_inquiry(dev_addr, lun, &scsi_resp.inquiry, inquiry_complete_cb, 0); } void tuh_msc_umount_cb(uint8_t dev_addr) diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index 02791dace..900b31d7d 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -54,13 +54,12 @@ typedef struct { uint8_t itf_num; uint8_t ep_in; uint8_t ep_out; - uint8_t max_lun; volatile bool configured; // Receive SET_CONFIGURE volatile bool mounted; // Enumeration is complete - //------------- SCSI -------------// + // SCSI command data uint8_t stage; void* buffer; tuh_msc_complete_cb_t complete_cb; @@ -82,7 +81,7 @@ CFG_TUH_MEM_SECTION static msch_epbuf_t _msch_epbuf[CFG_TUH_DEVICE_MAX]; // Epbuf for enumeration, shared for all devices CFG_TUH_MEM_SECTION static struct { - TUH_EPBUF_DEF(buf, 32); // TODO make this configurable + TUH_EPBUF_DEF(buf, 32); } _msch_enum_buf; TU_ATTR_ALWAYS_INLINE static inline msch_interface_t* get_itf(uint8_t daddr) { @@ -141,10 +140,10 @@ bool tuh_msc_scsi_command(uint8_t daddr, msc_cbw_t const* cbw, void* data, msch_epbuf_t* epbuf = get_epbuf(daddr); epbuf->cbw = *cbw; - p_msc->stage = MSC_STAGE_CMD; p_msc->buffer = data; p_msc->complete_cb = complete_cb; p_msc->complete_arg = arg; + p_msc->stage = MSC_STAGE_CMD; if (!usbh_edpt_xfer(daddr, p_msc->ep_out, (uint8_t*) &epbuf->cbw, sizeof(msc_cbw_t))) { usbh_edpt_release(daddr, p_msc->ep_out); @@ -292,6 +291,7 @@ bool tuh_msc_reset(uint8_t dev_addr) { //--------------------------------------------------------------------+ bool msch_init(void) { TU_LOG_DRV("sizeof(msch_interface_t) = %u\r\n", sizeof(msch_interface_t)); + TU_LOG_DRV("sizeof(msch_epbuf_t) = %u\r\n", sizeof(msch_epbuf_t)); tu_memclr(_msch_itf, sizeof(_msch_itf)); return true; } @@ -325,18 +325,15 @@ bool msch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32 case MSC_STAGE_CMD: // Must be Command Block TU_ASSERT(ep_addr == p_msc->ep_out && event == XFER_RESULT_SUCCESS && xferred_bytes == sizeof(msc_cbw_t)); - if (cbw->total_bytes && p_msc->buffer) { // Data stage if any 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, (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*) csw, (uint16_t) sizeof(msc_csw_t))); + break; } - break; + + TU_ATTR_FALLTHROUGH; // fallthrough to status stage case MSC_STAGE_DATA: // Status stage diff --git a/src/class/msc/msc_host.h b/src/class/msc/msc_host.h index 6969336a0..09d777066 100644 --- a/src/class/msc/msc_host.h +++ b/src/class/msc/msc_host.h @@ -73,10 +73,12 @@ 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. +// NOTE: buffer must be accessible by USB/DMA controller, aligned correctly and multiple of cache line if enabled bool tuh_msc_scsi_command(uint8_t daddr, 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. +// NOTE: response must be accessible by USB/DMA controller, aligned correctly and multiple of cache line if enabled 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 @@ -85,14 +87,17 @@ bool tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, tuh_msc_complete_cb_ // Perform SCSI Request Sense 10 command // Complete callback is invoked when SCSI op is complete. +// NOTE: response must be accessible by USB/DMA controller, aligned correctly and multiple of cache line if enabled 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. +// NOTE: buffer must be accessible by USB/DMA controller, aligned correctly and multiple of cache line if enabled 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. +// NOTE: buffer must be accessible by USB/DMA controller, aligned correctly and multiple of cache line if enabled 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