summaryrefslogtreecommitdiff
path: root/class
diff options
context:
space:
mode:
authorsakumisu <[email protected]>2022-07-28 21:25:29 +0800
committersakumisu <[email protected]>2022-07-28 21:35:22 +0800
commitf1bc0aef0419d648967779d9807bd00784cb9987 (patch)
treeb6b3cfbde9794e6091b7cd63d0670f1b898bc024 /class
parentd2fb9b36246dc1285c29a8581b3a3b58cb213f1e (diff)
refactor dcd api and ep in/out irq callback process
Diffstat (limited to 'class')
-rw-r--r--class/cdc/usbd_cdc.c7
-rw-r--r--class/cdc/usbd_cdc.h5
-rw-r--r--class/hid/usbd_hid.c7
-rw-r--r--class/hid/usbd_hid.h10
-rw-r--r--class/msc/usbd_msc.c590
5 files changed, 269 insertions, 350 deletions
diff --git a/class/cdc/usbd_cdc.c b/class/cdc/usbd_cdc.c
index ef002fac..c6defc37 100644
--- a/class/cdc/usbd_cdc.c
+++ b/class/cdc/usbd_cdc.c
@@ -152,6 +152,9 @@ static void cdc_notify_handler(uint8_t event, void *arg)
usbd_cdc_acm_reset();
#endif
break;
+ case USBD_EVENT_CONFIGURED:
+ usbd_cdc_acm_setup();
+ break;
default:
break;
@@ -207,3 +210,7 @@ __WEAK void usbd_cdc_acm_set_dtr(uint8_t intf, bool dtr)
__WEAK void usbd_cdc_acm_set_rts(uint8_t intf, bool rts)
{
}
+
+__WEAK void usbd_cdc_acm_setup(void)
+{
+}
diff --git a/class/cdc/usbd_cdc.h b/class/cdc/usbd_cdc.h
index 19d41dcf..88e975f1 100644
--- a/class/cdc/usbd_cdc.h
+++ b/class/cdc/usbd_cdc.h
@@ -29,12 +29,17 @@
extern "C" {
#endif
+/* Register api */
void usbd_cdc_add_acm_interface(usbd_class_t *devclass, usbd_interface_t *intf);
+/* Setup request command callback api */
void usbd_cdc_acm_set_line_coding(uint8_t intf, uint32_t baudrate, uint8_t databits, uint8_t parity, uint8_t stopbits);
void usbd_cdc_acm_set_dtr(uint8_t intf, bool dtr);
void usbd_cdc_acm_set_rts(uint8_t intf, bool rts);
+/* Setup cdc acm first rx transfer */
+void usbd_cdc_acm_setup(void);
+
#ifdef __cplusplus
}
#endif
diff --git a/class/hid/usbd_hid.c b/class/hid/usbd_hid.c
index 7aa38031..b0544e77 100644
--- a/class/hid/usbd_hid.c
+++ b/class/hid/usbd_hid.c
@@ -175,6 +175,9 @@ static void hid_notify_handler(uint8_t event, void *arg)
case USBD_EVENT_RESET:
usbd_hid_reset();
break;
+ case USBD_EVENT_CONFIGURED:
+ usbd_hid_setup();
+ break;
default:
break;
@@ -258,4 +261,8 @@ __WEAK void usbh_hid_set_idle(uint8_t intf, uint8_t report_id, uint8_t duration)
__WEAK void usbh_hid_set_protocol(uint8_t intf, uint8_t protocol)
{
+}
+
+__WEAK void usbd_hid_setup(void)
+{
} \ No newline at end of file
diff --git a/class/hid/usbd_hid.h b/class/hid/usbd_hid.h
index 09f949fb..0f89c0b5 100644
--- a/class/hid/usbd_hid.h
+++ b/class/hid/usbd_hid.h
@@ -29,9 +29,14 @@
extern "C" {
#endif
+/* Register api */
+void usbd_hid_add_interface(usbd_class_t *devclass, usbd_interface_t *intf);
+
+/* Register desc api */
void usbd_hid_descriptor_register(uint8_t intf_num, const uint8_t *desc);
void usbd_hid_report_descriptor_register(uint8_t intf_num, const uint8_t *desc, uint32_t desc_len);
-void usbd_hid_add_interface(usbd_class_t *devclass, usbd_interface_t *intf);
+
+/* Setup request command callback api */
uint8_t usbh_hid_get_report(uint8_t intf, uint8_t report_id, uint8_t report_type);
uint8_t usbh_hid_get_idle(uint8_t intf, uint8_t report_id);
uint8_t usbh_hid_get_protocol(uint8_t intf);
@@ -39,6 +44,9 @@ void usbh_hid_set_report(uint8_t intf, uint8_t report_id, uint8_t report_type, u
void usbh_hid_set_idle(uint8_t intf, uint8_t report_id, uint8_t duration);
void usbh_hid_set_protocol(uint8_t intf, uint8_t protocol);
+/* Setup hid first rx transfer */
+void usbd_hid_setup(void);
+
#ifdef __cplusplus
}
#endif
diff --git a/class/msc/usbd_msc.c b/class/msc/usbd_msc.c
index 92148f6d..0e0464a9 100644
--- a/class/msc/usbd_msc.c
+++ b/class/msc/usbd_msc.c
@@ -85,14 +85,7 @@ static uint32_t current_byte_read;
static void usbd_msc_reset(void)
{
- uint8_t *buf = NULL;
-
- buf = usbd_msc_cfg.block_buffer;
-
- memset((uint8_t *)&usbd_msc_cfg, 0, sizeof(struct usbd_msc_cfg_priv));
-
- usbd_msc_get_cap(0, &usbd_msc_cfg.scsi_blk_nbr, &usbd_msc_cfg.scsi_blk_size);
- usbd_msc_cfg.block_buffer = buf;
+ usbd_msc_cfg.stage = MSC_READ_CBW;
}
/**
@@ -112,24 +105,10 @@ static int msc_storage_class_request_handler(struct usb_setup_packet *setup, uin
switch (setup->bRequest) {
case MSC_REQUEST_RESET:
- USB_LOG_DBG("MSC_REQUEST_RESET\r\n");
-
- if (setup->wLength) {
- USB_LOG_WRN("Invalid length\r\n");
- return -1;
- }
-
usbd_msc_reset();
break;
case MSC_REQUEST_GET_MAX_LUN:
- USB_LOG_DBG("MSC_REQUEST_GET_MAX_LUN\r\n");
-
- if (setup->wLength != 1) {
- USB_LOG_WRN("Invalid length\r\n");
- return -1;
- }
-
*data = (uint8_t *)(&usbd_msc_cfg.max_lun);
*len = 1;
break;
@@ -142,15 +121,32 @@ static int msc_storage_class_request_handler(struct usb_setup_packet *setup, uin
return 0;
}
+void msc_storage_notify_handler(uint8_t event, void *arg)
+{
+ switch (event) {
+ case USBD_EVENT_RESET:
+ usbd_msc_reset();
+ break;
+ case USBD_EVENT_CONFIGURED:
+ USB_LOG_DBG("Start reading cbw\r\n");
+ usbd_ep_start_read(mass_ep_data[MSD_OUT_EP_IDX].ep_addr, (uint8_t *)&usbd_msc_cfg.cbw, USB_SIZEOF_MSC_CBW);
+ break;
+
+ default:
+ break;
+ }
+}
+
static void usbd_msc_bot_abort(void)
{
if ((usbd_msc_cfg.cbw.bmFlags == 0) && (usbd_msc_cfg.cbw.dDataLength != 0)) {
usbd_ep_set_stall(mass_ep_data[MSD_OUT_EP_IDX].ep_addr);
}
usbd_ep_set_stall(mass_ep_data[MSD_IN_EP_IDX].ep_addr);
+ usbd_ep_start_read(mass_ep_data[0].ep_addr, (uint8_t *)&usbd_msc_cfg.cbw, USB_SIZEOF_MSC_CBW);
}
-static void sendCSW(uint8_t CSW_Status)
+static void usbd_msc_send_csw(uint8_t CSW_Status)
{
usbd_msc_cfg.csw.dSignature = MSC_CSW_Signature;
usbd_msc_cfg.csw.bStatus = CSW_Status;
@@ -160,13 +156,11 @@ static void sendCSW(uint8_t CSW_Status)
*/
usbd_msc_cfg.stage = MSC_WAIT_CSW;
- if (usbd_ep_write(mass_ep_data[MSD_IN_EP_IDX].ep_addr, (uint8_t *)&usbd_msc_cfg.csw,
- sizeof(struct CSW), NULL) != 0) {
- USB_LOG_ERR("usb write failure\r\n");
- }
+ USB_LOG_DBG("Send csw\r\n");
+ usbd_ep_start_write(mass_ep_data[MSD_IN_EP_IDX].ep_addr, (uint8_t *)&usbd_msc_cfg.csw, sizeof(struct CSW));
}
-static void sendLastData(uint8_t *buffer, uint8_t size)
+static void usbd_msc_send_info(uint8_t *buffer, uint8_t size)
{
size = MIN(size, usbd_msc_cfg.cbw.dDataLength);
@@ -175,31 +169,14 @@ static void sendLastData(uint8_t *buffer, uint8_t size)
*/
usbd_msc_cfg.stage = MSC_SEND_CSW;
- if (usbd_ep_write(mass_ep_data[MSD_IN_EP_IDX].ep_addr, buffer, size, NULL) != 0) {
- USB_LOG_ERR("USB write failed\r\n");
- }
+ usbd_ep_start_write(mass_ep_data[MSD_IN_EP_IDX].ep_addr, buffer, size);
usbd_msc_cfg.csw.dDataResidue -= size;
usbd_msc_cfg.csw.bStatus = CSW_STATUS_CMD_PASSED;
}
-/**
- * @brief SCSI COMMAND
- */
-static bool SCSI_testUnitReady(uint8_t **data, uint32_t *len);
-static bool SCSI_requestSense(uint8_t **data, uint32_t *len);
-static bool SCSI_inquiry(uint8_t **data, uint32_t *len);
-static bool SCSI_startStopUnit(uint8_t **data, uint32_t *len);
-static bool SCSI_preventAllowMediaRemoval(uint8_t **data, uint32_t *len);
-static bool SCSI_modeSense6(uint8_t **data, uint32_t *len);
-static bool SCSI_modeSense10(uint8_t **data, uint32_t *len);
-static bool SCSI_readFormatCapacity(uint8_t **data, uint32_t *len);
-static bool SCSI_readCapacity10(uint8_t **data, uint32_t *len);
-static bool SCSI_read10(uint8_t **data, uint32_t *len);
-static bool SCSI_read12(uint8_t **data, uint32_t *len);
-static bool SCSI_write10(uint8_t **data, uint32_t *len);
-static bool SCSI_write12(uint8_t **data, uint32_t *len);
-static bool SCSI_verify10(uint8_t **data, uint32_t *len);
+static bool SCSI_processWrite(uint32_t nbytes);
+static bool SCSI_processRead(void);
/**
* @brief SCSI_SetSenseData
@@ -216,258 +193,10 @@ static void SCSI_SetSenseData(uint32_t KCQ)
usbd_msc_cfg.ASQ = (uint8_t)(KCQ);
}
-#ifdef CONFIG_USBDEV_MSC_THREAD
-static void usbd_msc_thread_memory_read_done(void)
-{
- size_t flags;
- uint32_t transfer_len;
- uint32_t offset;
-
- USB_LOG_DBG("read addr:%d\r\n", usbd_msc_cfg.scsi_blk_addr);
-
- flags = usb_osal_enter_critical_section();
-
- transfer_len = MIN(usbd_msc_cfg.scsi_blk_len, MASS_STORAGE_BULK_EP_MPS);
- offset = usbd_msc_cfg.scsi_blk_addr % usbd_msc_cfg.scsi_blk_size;
-
- usbd_msc_cfg.scsi_blk_addr += transfer_len;
- usbd_msc_cfg.scsi_blk_len -= transfer_len;
- usbd_msc_cfg.csw.dDataResidue -= transfer_len;
-
- if (usbd_msc_cfg.scsi_blk_len == 0) {
- usbd_msc_cfg.stage = MSC_SEND_CSW;
- }
- usb_osal_leave_critical_section(flags);
-
- usbd_ep_write(mass_ep_data[MSD_IN_EP_IDX].ep_addr,
- &usbd_msc_cfg.block_buffer[offset], transfer_len, NULL);
-}
-#endif
-
-static bool SCSI_processRead(void)
-{
- uint32_t transfer_len;
-
- USB_LOG_DBG("read addr:%d\r\n", usbd_msc_cfg.scsi_blk_addr);
-
- transfer_len = MIN(usbd_msc_cfg.scsi_blk_len, MASS_STORAGE_BULK_EP_MPS);
-
- /* we read an entire block */
- if (!(usbd_msc_cfg.scsi_blk_addr % usbd_msc_cfg.scsi_blk_size)) {
-#ifdef CONFIG_USBDEV_MSC_THREAD
- thread_op = MSC_THREAD_OP_READ_MEM;
- usb_osal_sem_give(msc_sem);
- return true;
-#else
- if (usbd_msc_sector_read((usbd_msc_cfg.scsi_blk_addr / usbd_msc_cfg.scsi_blk_size), usbd_msc_cfg.block_buffer, usbd_msc_cfg.scsi_blk_size) != 0) {
- SCSI_SetSenseData(SCSI_KCQHE_UREINRESERVEDAREA);
- return false;
- }
-#endif
- }
-
- usbd_ep_write(mass_ep_data[MSD_IN_EP_IDX].ep_addr,
- &usbd_msc_cfg.block_buffer[usbd_msc_cfg.scsi_blk_addr % usbd_msc_cfg.scsi_blk_size], transfer_len, NULL);
-
- usbd_msc_cfg.scsi_blk_addr += transfer_len;
- usbd_msc_cfg.scsi_blk_len -= transfer_len;
- usbd_msc_cfg.csw.dDataResidue -= transfer_len;
-
- if (usbd_msc_cfg.scsi_blk_len == 0) {
- usbd_msc_cfg.stage = MSC_SEND_CSW;
- }
-
- return true;
-}
-
-#ifdef CONFIG_USBDEV_MSC_THREAD
-static void usbd_msc_thread_memory_write_done()
-{
- size_t flags;
- uint32_t bytes_read;
- USB_LOG_DBG("write addr:%d\r\n", usbd_msc_cfg.scsi_blk_addr);
-
- flags = usb_osal_enter_critical_section();
-
- bytes_read = current_byte_read;
-
- usbd_msc_cfg.scsi_blk_addr += bytes_read;
- usbd_msc_cfg.scsi_blk_len -= bytes_read;
- usbd_msc_cfg.csw.dDataResidue -= bytes_read;
-
- usb_osal_leave_critical_section(flags);
-
- thread_op = MSC_THREAD_OP_WRITE_DONE;
- /*set ep ack to recv next data*/
- usbd_ep_read(mass_ep_data[MSD_OUT_EP_IDX].ep_addr, NULL, 0, NULL);
-
- if (usbd_msc_cfg.scsi_blk_len == 0) {
- sendCSW(CSW_STATUS_CMD_PASSED);
- }
-}
-#endif
-
-static bool SCSI_processWrite()
-{
- uint32_t bytes_read;
- USB_LOG_DBG("write addr:%d\r\n", usbd_msc_cfg.scsi_blk_addr);
-
- /* we fill an array in RAM of 1 block before writing it in memory */
- usbd_ep_read(mass_ep_data[MSD_OUT_EP_IDX].ep_addr, &usbd_msc_cfg.block_buffer[usbd_msc_cfg.scsi_blk_addr % usbd_msc_cfg.scsi_blk_size], MASS_STORAGE_BULK_EP_MPS,
- &bytes_read);
-
- /* if the array is filled, write it in memory */
- if ((usbd_msc_cfg.scsi_blk_addr % usbd_msc_cfg.scsi_blk_size) + bytes_read >= usbd_msc_cfg.scsi_blk_size) {
-#ifdef CONFIG_USBDEV_MSC_THREAD
- thread_op = MSC_THREAD_OP_WRITE_MEM;
- current_byte_read = bytes_read;
- usb_osal_sem_give(msc_sem);
- return true;
-#else
- if (usbd_msc_sector_write((usbd_msc_cfg.scsi_blk_addr / usbd_msc_cfg.scsi_blk_size), usbd_msc_cfg.block_buffer, usbd_msc_cfg.scsi_blk_size) != 0) {
- SCSI_SetSenseData(SCSI_KCQHE_WRITEFAULT);
- return false;
- }
-#endif
- }
-
- usbd_msc_cfg.scsi_blk_addr += bytes_read;
- usbd_msc_cfg.scsi_blk_len -= bytes_read;
- usbd_msc_cfg.csw.dDataResidue -= bytes_read;
-
- if (usbd_msc_cfg.scsi_blk_len == 0) {
- sendCSW(CSW_STATUS_CMD_PASSED);
- }
-
- return true;
-}
-
-static bool SCSI_processVerify()
-{
-#if 0
- uint32_t bytes_read;
- uint8_t out_buffer[MASS_STORAGE_BULK_EP_MPS];
-
- USB_LOG_DBG("verify addr:%d\r\n", usbd_msc_cfg.scsi_blk_addr);
-
- /* we fill an array in RAM of 1 block before writing it in memory */
- usbd_ep_read(mass_ep_data[MSD_OUT_EP_IDX].ep_addr, out_buffer, MASS_STORAGE_BULK_EP_MPS,
- &bytes_read);
-
- /* we read an entire block */
- if (!(usbd_msc_cfg.scsi_blk_addr % usbd_msc_cfg.scsi_blk_size)) {
- if (usbd_msc_sector_read((usbd_msc_cfg.scsi_blk_addr / usbd_msc_cfg.scsi_blk_size), usbd_msc_cfg.block_buffer, usbd_msc_cfg.scsi_blk_size) != 0) {
- SCSI_SetSenseData(SCSI_KCQHE_UREINRESERVEDAREA);
- return false;
- }
- }
-
- /* info are in RAM -> no need to re-read memory */
- for (uint16_t i = 0U; i < bytes_read; i++) {
- if (usbd_msc_cfg.block_buffer[usbd_msc_cfg.scsi_blk_addr % usbd_msc_cfg.scsi_blk_size + i] != out_buffer[i]) {
- USB_LOG_DBG("Mismatch sector %d offset %d",
- usbd_msc_cfg.scsi_blk_addr / usbd_msc_cfg.scsi_blk_size, i);
- memOK = false;
- break;
- }
- }
-
- usbd_msc_cfg.scsi_blk_addr += bytes_read;
- usbd_msc_cfg.scsi_blk_len -= bytes_read;
- usbd_msc_cfg.csw.dDataResidue -= bytes_read;
-
- if (usbd_msc_cfg.scsi_blk_len == 0) {
- sendCSW(CSW_STATUS_CMD_PASSED);
- }
-#endif
- return true;
-}
-
-static bool SCSI_CBWDecode()
-{
- uint8_t *buf2send = usbd_msc_cfg.block_buffer;
- uint32_t len2send = 0;
- uint32_t bytes_read;
- bool ret = false;
-
- usbd_ep_read(mass_ep_data[MSD_OUT_EP_IDX].ep_addr, (uint8_t *)&usbd_msc_cfg.cbw, USB_SIZEOF_MSC_CBW,
- &bytes_read);
-
- if (bytes_read != sizeof(struct CBW)) {
- USB_LOG_ERR("size != sizeof(cbw)\r\n");
- SCSI_SetSenseData(SCSI_KCQIR_INVALIDCOMMAND);
- return false;
- }
-
- usbd_msc_cfg.csw.dTag = usbd_msc_cfg.cbw.dTag;
- usbd_msc_cfg.csw.dDataResidue = usbd_msc_cfg.cbw.dDataLength;
-
- if ((usbd_msc_cfg.cbw.bLUN > 1) || (usbd_msc_cfg.cbw.dSignature != MSC_CBW_Signature) || (usbd_msc_cfg.cbw.bCBLength < 1) || (usbd_msc_cfg.cbw.bCBLength > 16)) {
- SCSI_SetSenseData(SCSI_KCQIR_INVALIDCOMMAND);
- return false;
- } else {
- switch (usbd_msc_cfg.cbw.CB[0]) {
- case SCSI_CMD_TESTUNITREADY:
- ret = SCSI_testUnitReady(&buf2send, &len2send);
- break;
- case SCSI_CMD_REQUESTSENSE:
- ret = SCSI_requestSense(&buf2send, &len2send);
- break;
- case SCSI_CMD_INQUIRY:
- ret = SCSI_inquiry(&buf2send, &len2send);
- break;
- case SCSI_CMD_STARTSTOPUNIT:
- ret = SCSI_startStopUnit(&buf2send, &len2send);
- break;
- case SCSI_CMD_PREVENTMEDIAREMOVAL:
- ret = SCSI_preventAllowMediaRemoval(&buf2send, &len2send);
- break;
- case SCSI_CMD_MODESENSE6:
- ret = SCSI_modeSense6(&buf2send, &len2send);
- break;
- case SCSI_CMD_MODESENSE10:
- ret = SCSI_modeSense10(&buf2send, &len2send);
- break;
- case SCSI_CMD_READFORMATCAPACITIES:
- ret = SCSI_readFormatCapacity(&buf2send, &len2send);
- break;
- case SCSI_CMD_READCAPACITY10:
- ret = SCSI_readCapacity10(&buf2send, &len2send);
- break;
- case SCSI_CMD_READ10:
- ret = SCSI_read10(NULL, 0);
- break;
- case SCSI_CMD_READ12:
- ret = SCSI_read12(NULL, 0);
- break;
- case SCSI_CMD_WRITE10:
- ret = SCSI_write10(NULL, 0);
- break;
- case SCSI_CMD_WRITE12:
- ret = SCSI_write12(NULL, 0);
- break;
- case SCSI_CMD_VERIFY10:
- ret = SCSI_verify10(NULL, 0);
- break;
-
- default:
- SCSI_SetSenseData(SCSI_KCQIR_INVALIDCOMMAND);
- USB_LOG_WRN("unsupported cmd:0x%02x\r\n", usbd_msc_cfg.cbw.CB[0]);
- ret = false;
- break;
- }
- }
- if (ret) {
- if (usbd_msc_cfg.stage == MSC_READ_CBW) {
- if (len2send) {
- sendLastData(buf2send, len2send);
- } else {
- sendCSW(CSW_STATUS_CMD_PASSED);
- }
- }
- }
- return ret;
-}
+/**
+ * @brief SCSI Command list
+ *
+ */
static bool SCSI_testUnitReady(uint8_t **data, uint32_t *len)
{
@@ -871,6 +600,7 @@ static bool SCSI_write10(uint8_t **data, uint32_t *len)
return false;
}
usbd_msc_cfg.stage = MSC_DATA_OUT;
+ usbd_ep_start_read(mass_ep_data[MSD_OUT_EP_IDX].ep_addr, &usbd_msc_cfg.block_buffer[usbd_msc_cfg.scsi_blk_addr % usbd_msc_cfg.scsi_blk_size], usbd_msc_cfg.scsi_blk_size);
return true;
}
@@ -904,6 +634,7 @@ static bool SCSI_write12(uint8_t **data, uint32_t *len)
return false;
}
usbd_msc_cfg.stage = MSC_DATA_OUT;
+ usbd_ep_start_read(mass_ep_data[MSD_OUT_EP_IDX].ep_addr, &usbd_msc_cfg.block_buffer[usbd_msc_cfg.scsi_blk_addr % usbd_msc_cfg.scsi_blk_size], MASS_STORAGE_BULK_EP_MPS);
return true;
}
@@ -952,30 +683,222 @@ static bool SCSI_verify10(uint8_t **data, uint32_t *len)
return true;
}
-static void mass_storage_bulk_out(uint8_t ep)
+#ifdef CONFIG_USBDEV_MSC_THREAD
+static void usbd_msc_thread_memory_read_done(void)
+{
+ size_t flags;
+ uint32_t transfer_len;
+
+ flags = usb_osal_enter_critical_section();
+
+ transfer_len = MIN(usbd_msc_cfg.scsi_blk_len, usbd_msc_cfg.scsi_blk_size);
+
+ usbd_ep_start_write(mass_ep_data[MSD_IN_EP_IDX].ep_addr,
+ &usbd_msc_cfg.block_buffer[usbd_msc_cfg.scsi_blk_addr % usbd_msc_cfg.scsi_blk_size], transfer_len);
+
+ usbd_msc_cfg.scsi_blk_addr += transfer_len;
+ usbd_msc_cfg.scsi_blk_len -= transfer_len;
+ usbd_msc_cfg.csw.dDataResidue -= transfer_len;
+
+ if (usbd_msc_cfg.scsi_blk_len == 0) {
+ usbd_msc_cfg.stage = MSC_SEND_CSW;
+ }
+ usb_osal_leave_critical_section(flags);
+}
+#endif
+
+static bool SCSI_processRead(void)
+{
+ uint32_t transfer_len;
+
+ USB_LOG_DBG("read addr:%d\r\n", usbd_msc_cfg.scsi_blk_addr);
+
+ transfer_len = MIN(usbd_msc_cfg.scsi_blk_len, usbd_msc_cfg.scsi_blk_size);
+
+ /* we read an entire block */
+ if (!(usbd_msc_cfg.scsi_blk_addr % usbd_msc_cfg.scsi_blk_size)) {
+#ifdef CONFIG_USBDEV_MSC_THREAD
+ thread_op = MSC_THREAD_OP_READ_MEM;
+ usb_osal_sem_give(msc_sem);
+ return true;
+#else
+ if (usbd_msc_sector_read((usbd_msc_cfg.scsi_blk_addr / usbd_msc_cfg.scsi_blk_size), usbd_msc_cfg.block_buffer, usbd_msc_cfg.scsi_blk_size) != 0) {
+ SCSI_SetSenseData(SCSI_KCQHE_UREINRESERVEDAREA);
+ return false;
+ }
+#endif
+ }
+
+ usbd_ep_start_write(mass_ep_data[MSD_IN_EP_IDX].ep_addr,
+ &usbd_msc_cfg.block_buffer[usbd_msc_cfg.scsi_blk_addr % usbd_msc_cfg.scsi_blk_size], transfer_len);
+
+ usbd_msc_cfg.scsi_blk_addr += transfer_len;
+ usbd_msc_cfg.scsi_blk_len -= transfer_len;
+ usbd_msc_cfg.csw.dDataResidue -= transfer_len;
+
+ if (usbd_msc_cfg.scsi_blk_len == 0) {
+ usbd_msc_cfg.stage = MSC_SEND_CSW;
+ }
+
+ return true;
+}
+
+#ifdef CONFIG_USBDEV_MSC_THREAD
+static void usbd_msc_thread_memory_write_done()
+{
+ size_t flags;
+ uint32_t nbytes;
+
+ flags = usb_osal_enter_critical_section();
+
+ nbytes = current_byte_read;
+
+ usbd_msc_cfg.scsi_blk_addr += nbytes;
+ usbd_msc_cfg.scsi_blk_len -= nbytes;
+ usbd_msc_cfg.csw.dDataResidue -= nbytes;
+
+ if (usbd_msc_cfg.scsi_blk_len == 0) {
+ usbd_msc_send_csw(CSW_STATUS_CMD_PASSED);
+ } else {
+ usbd_ep_start_read(mass_ep_data[MSD_OUT_EP_IDX].ep_addr, &usbd_msc_cfg.block_buffer[usbd_msc_cfg.scsi_blk_addr % usbd_msc_cfg.scsi_blk_size], MASS_STORAGE_BULK_EP_MPS);
+ }
+
+ usb_osal_leave_critical_section(flags);
+}
+#endif
+
+static bool SCSI_processWrite(uint32_t nbytes)
+{
+ USB_LOG_DBG("write addr:%d\r\n", usbd_msc_cfg.scsi_blk_addr);
+
+ /* if the array is filled, write it in memory */
+ if ((usbd_msc_cfg.scsi_blk_addr % usbd_msc_cfg.scsi_blk_size) + nbytes >= usbd_msc_cfg.scsi_blk_size) {
+#ifdef CONFIG_USBDEV_MSC_THREAD
+ thread_op = MSC_THREAD_OP_WRITE_MEM;
+ current_byte_read = nbytes;
+ usb_osal_sem_give(msc_sem);
+ return true;
+#else
+ if (usbd_msc_sector_write((usbd_msc_cfg.scsi_blk_addr / usbd_msc_cfg.scsi_blk_size), usbd_msc_cfg.block_buffer, usbd_msc_cfg.scsi_blk_size) != 0) {
+ SCSI_SetSenseData(SCSI_KCQHE_WRITEFAULT);
+ return false;
+ }
+#endif
+ }
+
+ usbd_msc_cfg.scsi_blk_addr += nbytes;
+ usbd_msc_cfg.scsi_blk_len -= nbytes;
+ usbd_msc_cfg.csw.dDataResidue -= nbytes;
+
+ if (usbd_msc_cfg.scsi_blk_len == 0) {
+ usbd_msc_send_csw(CSW_STATUS_CMD_PASSED);
+ } else {
+ usbd_ep_start_read(mass_ep_data[MSD_OUT_EP_IDX].ep_addr, &usbd_msc_cfg.block_buffer[usbd_msc_cfg.scsi_blk_addr % usbd_msc_cfg.scsi_blk_size], usbd_msc_cfg.scsi_blk_size);
+ }
+
+ return true;
+}
+
+static bool SCSI_CBWDecode(uint32_t nbytes)
+{
+ uint8_t *buf2send = usbd_msc_cfg.block_buffer;
+ uint32_t len2send = 0;
+ bool ret = false;
+
+ if (nbytes != sizeof(struct CBW)) {
+ USB_LOG_ERR("size != sizeof(cbw)\r\n");
+ SCSI_SetSenseData(SCSI_KCQIR_INVALIDCOMMAND);
+ return false;
+ }
+
+ usbd_msc_cfg.csw.dTag = usbd_msc_cfg.cbw.dTag;
+ usbd_msc_cfg.csw.dDataResidue = usbd_msc_cfg.cbw.dDataLength;
+
+ if ((usbd_msc_cfg.cbw.bLUN > 1) || (usbd_msc_cfg.cbw.dSignature != MSC_CBW_Signature) || (usbd_msc_cfg.cbw.bCBLength < 1) || (usbd_msc_cfg.cbw.bCBLength > 16)) {
+ SCSI_SetSenseData(SCSI_KCQIR_INVALIDCOMMAND);
+ return false;
+ } else {
+ USB_LOG_DBG("Decode CB:0x%02x\r\n",usbd_msc_cfg.cbw.CB[0]);
+ switch (usbd_msc_cfg.cbw.CB[0]) {
+ case SCSI_CMD_TESTUNITREADY:
+ ret = SCSI_testUnitReady(&buf2send, &len2send);
+ break;
+ case SCSI_CMD_REQUESTSENSE:
+ ret = SCSI_requestSense(&buf2send, &len2send);
+ break;
+ case SCSI_CMD_INQUIRY:
+ ret = SCSI_inquiry(&buf2send, &len2send);
+ break;
+ case SCSI_CMD_STARTSTOPUNIT:
+ ret = SCSI_startStopUnit(&buf2send, &len2send);
+ break;
+ case SCSI_CMD_PREVENTMEDIAREMOVAL:
+ ret = SCSI_preventAllowMediaRemoval(&buf2send, &len2send);
+ break;
+ case SCSI_CMD_MODESENSE6:
+ ret = SCSI_modeSense6(&buf2send, &len2send);
+ break;
+ case SCSI_CMD_MODESENSE10:
+ ret = SCSI_modeSense10(&buf2send, &len2send);
+ break;
+ case SCSI_CMD_READFORMATCAPACITIES:
+ ret = SCSI_readFormatCapacity(&buf2send, &len2send);
+ break;
+ case SCSI_CMD_READCAPACITY10:
+ ret = SCSI_readCapacity10(&buf2send, &len2send);
+ break;
+ case SCSI_CMD_READ10:
+ ret = SCSI_read10(NULL, 0);
+ break;
+ case SCSI_CMD_READ12:
+ ret = SCSI_read12(NULL, 0);
+ break;
+ case SCSI_CMD_WRITE10:
+ ret = SCSI_write10(NULL, 0);
+ break;
+ case SCSI_CMD_WRITE12:
+ ret = SCSI_write12(NULL, 0);
+ break;
+ case SCSI_CMD_VERIFY10:
+ ret = SCSI_verify10(NULL, 0);
+ break;
+
+ default:
+ SCSI_SetSenseData(SCSI_KCQIR_INVALIDCOMMAND);
+ USB_LOG_WRN("unsupported cmd:0x%02x\r\n", usbd_msc_cfg.cbw.CB[0]);
+ ret = false;
+ break;
+ }
+ }
+ if (ret) {
+ if (usbd_msc_cfg.stage == MSC_READ_CBW) {
+ if (len2send) {
+ USB_LOG_DBG("Send info len:%d\r\n",len2send);
+ usbd_msc_send_info(buf2send, len2send);
+ } else {
+ usbd_msc_send_csw(CSW_STATUS_CMD_PASSED);
+ }
+ }
+ }
+ return ret;
+}
+
+static void mass_storage_bulk_out(uint8_t ep, uint32_t nbytes)
{
switch (usbd_msc_cfg.stage) {
case MSC_READ_CBW:
- if (SCSI_CBWDecode() == false) {
+ if (SCSI_CBWDecode(nbytes) == false) {
USB_LOG_ERR("Command:0x%02x decode err\r\n", usbd_msc_cfg.cbw.CB[0]);
usbd_msc_bot_abort();
return;
}
break;
- /* last command is write10 or write12,and has caculated blk_addr and blk_len,so the device start reading data from host*/
case MSC_DATA_OUT:
switch (usbd_msc_cfg.cbw.CB[0]) {
case SCSI_CMD_WRITE10:
case SCSI_CMD_WRITE12:
- if (SCSI_processWrite() == false) {
- sendCSW(CSW_STATUS_CMD_FAILED); /* send fail status to host,and the host will retry*/
- //return;
- }
- break;
- case SCSI_CMD_VERIFY10:
- if (SCSI_processVerify() == false) {
- sendCSW(CSW_STATUS_CMD_FAILED); /* send fail status to host,and the host will retry*/
- //return;
+ if (SCSI_processWrite(nbytes) == false) {
+ usbd_msc_send_csw(CSW_STATUS_CMD_FAILED); /* send fail status to host,and the host will retry*/
}
break;
default:
@@ -985,65 +908,34 @@ static void mass_storage_bulk_out(uint8_t ep)
default:
break;
}
-
-#ifdef CONFIG_USBDEV_MSC_THREAD
- if (thread_op != MSC_THREAD_OP_WRITE_MEM) {
- /*set ep ack to recv next data*/
- usbd_ep_read(ep, NULL, 0, NULL);
- }
-#else
- /*set ep ack to recv next data*/
- usbd_ep_read(ep, NULL, 0, NULL);
-#endif
}
-/**
- * @brief EP Bulk IN handler, used to send data to the Host
- *
- * @param ep Endpoint address.
- * @param ep_status Endpoint status code.
- *
- * @return N/A.
- */
-static void mass_storage_bulk_in(uint8_t ep)
+static void mass_storage_bulk_in(uint8_t ep, uint32_t nbytes)
{
switch (usbd_msc_cfg.stage) {
- /* last command is read10 or read12,and has caculated blk_addr and blk_len,so the device has to send remain data to host*/
case MSC_DATA_IN:
switch (usbd_msc_cfg.cbw.CB[0]) {
case SCSI_CMD_READ10:
case SCSI_CMD_READ12:
if (SCSI_processRead() == false) {
- sendCSW(CSW_STATUS_CMD_FAILED); /* send fail status to host,and the host will retry*/
+ usbd_msc_send_csw(CSW_STATUS_CMD_FAILED); /* send fail status to host,and the host will retry*/
return;
}
break;
default:
break;
}
-
break;
-
- /*the device has to send a CSW*/
+ /*the device has to send a CSW*/
case MSC_SEND_CSW:
- sendCSW(CSW_STATUS_CMD_PASSED);
+ usbd_msc_send_csw(CSW_STATUS_CMD_PASSED);
break;
/*the host has received the CSW*/
case MSC_WAIT_CSW:
usbd_msc_cfg.stage = MSC_READ_CBW;
- break;
-
- default:
- break;
- }
-}
-
-void msc_storage_notify_handler(uint8_t event, void *arg)
-{
- switch (event) {
- case USBD_EVENT_RESET:
- usbd_msc_reset();
+ USB_LOG_DBG("Start reading cbw\r\n");
+ usbd_ep_start_read(mass_ep_data[MSD_OUT_EP_IDX].ep_addr, (uint8_t *)&usbd_msc_cfg.cbw, USB_SIZEOF_MSC_CBW);
break;
default: