From fbdac6a96a952a85791c95689bf6a5d328a0ee85 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 28 Jul 2015 10:18:39 +0900 Subject: [PATCH] More USB driver change --- ChangeLog | 13 ++- src/usb-msc.c | 30 ++++-- src/usb_ctrl.c | 66 ++++++------ src/usb_desc.c | 36 +++---- src/usb_lld.h | 20 ++-- src/usb_stm32f103.c | 244 ++++++++++++++++++-------------------------- 6 files changed, 194 insertions(+), 215 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6a90611..747a9c0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,13 +1,20 @@ +2015-07-28 Niibe Yutaka + + * src/usb-msc.c: Update from Fraucheky. + + * src/usb_stm32f103.c (struct DATA_INFO): Remove offset. + (struct DEVICE_INFO): Integrate CONTROL_INFO. + 2015-07-27 Niibe Yutaka - * src/usb_stm32f103.c (usb_lld_answer_control): New. + * src/usb_stm32f103.c (usb_lld_reply_request): New. (usb_lld_set_data_to_send): Remove. (usb_lld_set_data_to_recv): Not a macro but a function. (std_get_status): Don't use statically allocated memory. - (std_get_configuration): Use usb_lld_answer_control. + (std_get_configuration): Use usb_lld_reply_request. (handle_setup0): Follow the change. * src/usb_ctrl.c (vcom_port_data_setup, usb_cb_setup) - (usb_cb_interface): Use usb_lld_answer_control. + (usb_cb_interface): Use usb_lld_reply_request. * src/usb_desc.c (usb_cb_get_descriptor): Likewise. 2015-07-24 Niibe Yutaka diff --git a/src/usb-msc.c b/src/usb-msc.c index 8e0801c..e9e9161 100644 --- a/src/usb-msc.c +++ b/src/usb-msc.c @@ -1,7 +1,8 @@ /* * usb-msc.c -- USB Mass Storage Class protocol handling * - * Copyright (C) 2011, 2012, 2013 Free Software Initiative of Japan + * Copyright (C) 2011, 2012, 2013, 2015 + * Free Software Initiative of Japan * Author: NIIBE Yutaka * * This file is a part of Gnuk, a GnuPG USB Token implementation. @@ -170,11 +171,13 @@ EP6_OUT_Callback (void) } static const uint8_t scsi_inquiry_data_00[] = { 0, 0, 0, 0, 0 }; +static const uint8_t scsi_inquiry_data_83[] = { 0, 0x83, 0, 0 }; + static const uint8_t scsi_inquiry_data[] = { 0x00, /* Direct Access Device. */ 0x80, /* RMB = 1: Removable Medium. */ - 0x05, /* Version: SPC-3. */ + 0x00, /* Version: not claim conformance. */ 0x02, /* Response format: SPC-3. */ 36 - 4, /* Additional Length. */ 0x00, @@ -330,6 +333,11 @@ msc_handle_command (void) CSW.dCSWTag = CBW.dCBWTag; switch (CBW.CBWCB[0]) { + case SCSI_REPORT_LUN: + buf[0] = buf[1] = buf[2] = buf[3] = 0; + buf[4] = buf[5] = buf[6] = buf[7] = 0; + msc_send_result (buf, 8); + goto done; case SCSI_REQUEST_SENSE: if (CBW.CBWCB[1] & 0x01) /* DESC */ msc_send_result ((uint8_t *)&scsi_sense_data_desc, @@ -345,10 +353,18 @@ msc_handle_command (void) } goto done; case SCSI_INQUIRY: - if (CBW.CBWCB[1] & 0x01) /* EVPD */ - /* assume page 00 */ - msc_send_result ((uint8_t *)&scsi_inquiry_data_00, - sizeof scsi_inquiry_data_00); + if (CBW.CBWCB[1] & 0x01) + /* EVPD */ + { + if (CBW.CBWCB[2] == 0x83) + /* Handle the case Page Code 0x83 */ + msc_send_result ((uint8_t *)&scsi_inquiry_data_83, + sizeof scsi_inquiry_data_83); + else + /* Otherwise, assume page 00 */ + msc_send_result ((uint8_t *)&scsi_inquiry_data_00, + sizeof scsi_inquiry_data_00); + } else msc_send_result ((uint8_t *)&scsi_inquiry_data, sizeof scsi_inquiry_data); @@ -462,6 +478,7 @@ msc_handle_command (void) if (CBW.CBWCB[8]-- == 0) CBW.CBWCB[7]--; CSW.dCSWDataResidue += 512; + lba++; } else { @@ -507,6 +524,7 @@ msc_handle_command (void) if (CBW.CBWCB[8]-- == 0) CBW.CBWCB[7]--; CSW.dCSWDataResidue -= 512; + lba++; } else { diff --git a/src/usb_ctrl.c b/src/usb_ctrl.c index b76ffaa..bf26c29 100644 --- a/src/usb_ctrl.c +++ b/src/usb_ctrl.c @@ -58,12 +58,12 @@ static struct line_coding line_coding = { }; static int -vcom_port_data_setup (uint8_t req, uint8_t req_no, uint16_t value) +vcom_port_data_setup (uint8_t req, uint8_t req_no, struct control_info *detail) { if (USB_SETUP_GET (req)) { if (req_no == USB_CDC_REQ_GET_LINE_CODING) - return usb_lld_answer_control (&line_coding, sizeof(line_coding)); + return usb_lld_reply_request (&line_coding, sizeof(line_coding), detail); } else /* USB_SETUP_SET (req) */ { @@ -76,7 +76,7 @@ vcom_port_data_setup (uint8_t req, uint8_t req_no, uint16_t value) { uint8_t connected_saved = stdout.connected; - if (value != 0) + if (detail->value != 0) { if (stdout.connected == 0) /* It's Open call */ @@ -259,8 +259,7 @@ static int download_check_crc32 (const uint32_t *end_p) } int -usb_cb_setup (uint8_t req, uint8_t req_no, - uint16_t value, uint16_t index, uint16_t len) +usb_cb_setup (uint8_t req, uint8_t req_no, struct control_info *detail) { uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT); @@ -269,27 +268,27 @@ usb_cb_setup (uint8_t req, uint8_t req_no, if (USB_SETUP_GET (req)) { if (req_no == USB_FSIJ_GNUK_MEMINFO) - return usb_lld_answer_control (mem_info, sizeof (mem_info)); + return usb_lld_reply_request (mem_info, sizeof (mem_info), detail); } else /* SETUP_SET */ { - uint8_t *addr = (uint8_t *)(0x20000000 + value * 0x100 + index); + uint8_t *addr = (uint8_t *)(0x20000000 + detail->value * 0x100 + detail->index); if (req_no == USB_FSIJ_GNUK_DOWNLOAD) { if (icc_state_p == NULL || *icc_state_p != ICC_STATE_EXITED) return USB_UNSUPPORT; - if (addr < &_regnual_start || addr + len > __heap_end__) + if (addr < &_regnual_start || addr + detail->len > __heap_end__) return USB_UNSUPPORT; - if (index + len < 256) - memset (addr + index + len, 0, 256 - (index + len)); + if (detail->index + detail->len < 256) + memset (addr + detail->index + detail->len, 0, 256 - (detail->index + detail->len)); - usb_lld_set_data_to_recv (addr, len); + usb_lld_set_data_to_recv (addr, detail->len); return USB_SUCCESS; } - else if (req_no == USB_FSIJ_GNUK_EXEC && len == 0) + else if (req_no == USB_FSIJ_GNUK_EXEC && detail->len == 0) { if (icc_state_p == NULL || *icc_state_p != ICC_STATE_EXITED) return USB_UNSUPPORT; @@ -299,27 +298,28 @@ usb_cb_setup (uint8_t req, uint8_t req_no, return download_check_crc32 ((uint32_t *)addr); } - else if (req_no == USB_FSIJ_GNUK_CARD_CHANGE && len == 0) + else if (req_no == USB_FSIJ_GNUK_CARD_CHANGE && detail->len == 0) { - if (value != 0 && value != 1 && value != 2) + if (detail->value != 0 && detail->value != 1 && detail->value != 2) return USB_UNSUPPORT; - ccid_card_change_signal (value); + ccid_card_change_signal (detail->value); return USB_SUCCESS; } } } else if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT)) { - if (index == ICC_INTERFACE) + if (detail->index == ICC_INTERFACE) { if (USB_SETUP_GET (req)) { if (req_no == USB_CCID_REQ_GET_CLOCK_FREQUENCIES) - return usb_lld_answer_control (freq_table, sizeof (freq_table)); + return usb_lld_reply_request (freq_table, sizeof (freq_table), + detail); else if (req_no == USB_CCID_REQ_GET_DATA_RATES) - return usb_lld_answer_control (data_rate_table, - sizeof (data_rate_table)); + return usb_lld_reply_request (data_rate_table, + sizeof (data_rate_table), detail); } else { @@ -335,19 +335,19 @@ usb_cb_setup (uint8_t req, uint8_t req_no, switch (req_no) { case USB_HID_REQ_GET_IDLE: - return usb_lld_answer_control (&hid_idle_rate, 1); + return usb_lld_reply_request (&hid_idle_rate, 1, detail); case USB_HID_REQ_SET_IDLE: - usb_lld_set_data_to_recv (&hid_idle_rate, 1); + usb_lld_set_data_to_recv (&hid_idle_rate, 1, detail); return USB_SUCCESS; case USB_HID_REQ_GET_REPORT: /* Request of LED status and key press */ - return usb_lld_answer_control (&hid_report, 2); + return usb_lld_reply_request (&hid_report, 2, detail); case USB_HID_REQ_SET_REPORT: /* Received LED set request */ - if (len == 1) - usb_lld_set_data_to_recv (&hid_report, len); + if (detail->len == 1) + usb_lld_set_data_to_recv (&hid_report, detail->len); return USB_SUCCESS; case USB_HID_REQ_GET_PROTOCOL: @@ -362,7 +362,7 @@ usb_cb_setup (uint8_t req, uint8_t req_no, #endif #ifdef ENABLE_VIRTUAL_COM_PORT else if (index == VCOM_INTERFACE_0) - return vcom_port_data_setup (req, req_no, value); + return vcom_port_data_setup (req, req_no, detail); #endif #ifdef PINPAD_DND_SUPPORT else if (index == MSC_INTERFACE) @@ -370,7 +370,8 @@ usb_cb_setup (uint8_t req, uint8_t req_no, if (USB_SETUP_GET (req)) { if (req_no == MSC_GET_MAX_LUN_COMMAND) - return usb_lld_answer_control (lun_table, sizeof (lun_table)); + return usb_lld_reply_request (lun_table, sizeof (lun_table), + detail); } else if (req_no == MSC_MASS_STORAGE_RESET_COMMAND) @@ -385,14 +386,13 @@ usb_cb_setup (uint8_t req, uint8_t req_no, void -usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value, - uint16_t index, uint16_t len) +usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value) { uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT); if (type_rcp == (VENDOR_REQUEST | DEVICE_RECIPIENT)) { - if (USB_SETUP_SET (req) && req_no == USB_FSIJ_GNUK_EXEC && len == 0) + if (USB_SETUP_SET (req) && req_no == USB_FSIJ_GNUK_EXEC) { if (icc_state_p == NULL || *icc_state_p != ICC_STATE_EXITED) return; @@ -459,9 +459,11 @@ int usb_cb_handle_event (uint8_t event_type, uint16_t value) return USB_UNSUPPORT; } -int usb_cb_interface (uint8_t cmd, uint16_t interface, uint16_t alt) +int usb_cb_interface (uint8_t cmd, struct control_info *detail) { const uint8_t zero = 0; + uint16_t interface = detail->index; + uint16_t alt = detail->value; if (interface >= NUM_INTERFACES) return USB_UNSUPPORT; @@ -478,10 +480,10 @@ int usb_cb_interface (uint8_t cmd, uint16_t interface, uint16_t alt) } case USB_GET_INTERFACE: - return usb_lld_answer_control (&zero, 1); + return usb_lld_reply_request (&zero, 1, detail); - default: case USB_QUERY_INTERFACE: + default: return USB_SUCCESS; } } diff --git a/src/usb_desc.c b/src/usb_desc.c index 804b3be..8db6f3e 100644 --- a/src/usb_desc.c +++ b/src/usb_desc.c @@ -59,7 +59,7 @@ static const uint8_t hid_report_desc[] = { #define USB_ICC_DATA_SIZE 64 /* USB Standard Device Descriptor */ -static const uint8_t gnukDeviceDescriptor[] = { +static const uint8_t device_desc[] = { 18, /* bLength */ USB_DEVICE_DESCRIPTOR_TYPE, /* bDescriptorType */ 0x10, 0x01, /* bcdUSB = 1.1 */ @@ -99,7 +99,7 @@ static const uint8_t gnukDeviceDescriptor[] = { /* Configuation Descriptor */ -static const uint8_t gnukConfigDescriptor[] = { +static const uint8_t config_desc[] = { 9, /* bLength: Configuation Descriptor size */ USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */ W_TOTAL_LENGTH, 0x00, /* wTotalLength:no of returned bytes */ @@ -346,21 +346,20 @@ static const struct desc string_descriptors[] = { int usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index, - uint16_t index, uint16_t length) + struct control_info *detail) { if (rcp == DEVICE_RECIPIENT) { if (desc_type == DEVICE_DESCRIPTOR) - return usb_lld_answer_control (gnukDeviceDescriptor, - sizeof (gnukDeviceDescriptor)); + return usb_lld_reply_request (device_desc, sizeof (device_desc), detail); else if (desc_type == CONFIG_DESCRIPTOR) - return usb_lld_answer_control (gnukConfigDescriptor, - sizeof (gnukConfigDescriptor)); + return usb_lld_reply_request (config_desc, sizeof (config_desc), detail); else if (desc_type == STRING_DESCRIPTOR) { if (desc_index < NUM_STRING_DESC) - return usb_lld_answer_control (string_descriptors[desc_index].desc, - string_descriptors[desc_index].size); + return usb_lld_reply_request (string_descriptors[desc_index].desc, + string_descriptors[desc_index].size, + detail); else if (desc_index == NUM_STRING_DESC) { uint8_t usbbuf[64]; @@ -377,27 +376,24 @@ usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index, } usbbuf[0] = len = i*2 + 2; usbbuf[1] = USB_STRING_DESCRIPTOR_TYPE; - if (len > length) - len = length; - return usb_lld_answer_control (usbbuf, len); + return usb_lld_reply_request (usbbuf, len, detail); } } } +#ifdef HID_CARD_CHANGE_SUPPORT else if (rcp == INTERFACE_RECIPIENT) { -#ifdef HID_CARD_CHANGE_SUPPORT - if (index == 1) + if (detail->index == 1) { if (desc_type == USB_DT_HID) - return usb_lld_answer_control (gnukConfigDescriptor+ICC_TOTAL_LENGTH+9, 9); + return usb_lld_reply_request (config_desc+ICC_TOTAL_LENGTH+9, 9, + detail); else if (desc_type == USB_DT_REPORT) - return usb_lld_answer_control (hid_report_desc, HID_REPORT_DESC_SIZE); + return usb_lld_reply_request (hid_report_desc, HID_REPORT_DESC_SIZE, + detail); } - else -#else - (void)index; -#endif } +#endif return USB_UNSUPPORT; } diff --git a/src/usb_lld.h b/src/usb_lld.h index 2608bd7..fd4bc08 100644 --- a/src/usb_lld.h +++ b/src/usb_lld.h @@ -55,15 +55,19 @@ enum USB_SUCCESS = 1, }; +struct control_info { + uint16_t value; + uint16_t index; + uint16_t len; +}; + void usb_cb_device_reset (void); -void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, - uint16_t value, uint16_t index, uint16_t len); -int usb_cb_setup (uint8_t req, uint8_t req_no, uint16_t value, - uint16_t index, uint16_t len); +int usb_cb_setup (uint8_t req, uint8_t req_no, struct control_info *detail); +int usb_cb_interface (uint8_t cmd, struct control_info *detail); int usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index, - uint16_t index, uint16_t length); + struct control_info *detail); int usb_cb_handle_event (uint8_t event_type, uint16_t value); -int usb_cb_interface (uint8_t cmd, uint16_t interface, uint16_t value); +void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value); enum { USB_EVENT_ADDRESS, @@ -89,7 +93,6 @@ enum DEVICE_STATE CONFIGURED }; - void usb_lld_init (uint8_t feature); void usb_lld_to_pmabuf (const void *src, uint16_t addr, size_t n); void usb_lld_from_pmabuf (void *dst, uint16_t addr, size_t n); @@ -99,7 +102,8 @@ int usb_lld_tx_data_len (int ep_num); void usb_lld_txcpy (const void *src, int ep_num, int offset, size_t len); void usb_lld_tx_enable (int ep_num, size_t len); void usb_lld_write (uint8_t ep_num, const void *buf, size_t len); -int usb_lld_answer_control (const void *buf, size_t buflen); +int usb_lld_reply_request (const void *buf, size_t buflen, + struct control_info *ctrl); void usb_lld_rx_enable (int ep_num); int usb_lld_rx_data_len (int ep_num); void usb_lld_rxcpy (uint8_t *dst, int ep_num, int offset, size_t len); diff --git a/src/usb_stm32f103.c b/src/usb_stm32f103.c index a874e41..c213d6a 100644 --- a/src/usb_stm32f103.c +++ b/src/usb_stm32f103.c @@ -1,9 +1,6 @@ #include #include -#define TRUE 1 -#define FALSE 0 - #include "sys.h" #include "usb_lld.h" @@ -49,33 +46,27 @@ enum FEATURE_SELECTOR struct DATA_INFO { - uint16_t len; - uint16_t offset; uint8_t *addr; + uint16_t len; uint8_t require_zlp; }; -struct CONTROL_INFO -{ - uint8_t bmRequestType; - uint8_t bRequest; - uint16_t wValue; - uint16_t wIndex; - uint16_t wLength; -}; struct DEVICE_INFO { uint8_t current_configuration; uint8_t current_feature; uint8_t state; + /**/ + uint8_t bmRequestType; + uint8_t bRequest; + /**/ + uint16_t value; }; -static struct CONTROL_INFO control_info; static struct DEVICE_INFO device_info; static struct DATA_INFO data_info; -static struct CONTROL_INFO *const ctrl_p = &control_info; static struct DEVICE_INFO *const dev_p = &device_info; static struct DATA_INFO *const data_p = &data_info; @@ -412,16 +403,14 @@ static void handle_datastage_out (void) { if (data_p->addr && data_p->len) { - uint8_t *buf; uint32_t len = st103_get_rx_count (ENDP0); if (len > data_p->len) len = data_p->len; - buf = data_p->addr + data_p->offset; - usb_lld_from_pmabuf (buf, st103_get_rx_addr (ENDP0), len); + usb_lld_from_pmabuf (data_p->addr, st103_get_rx_addr (ENDP0), len); data_p->len -= len; - data_p->offset += len; + data_p->addr += len; } if (data_p->len == 0) @@ -440,13 +429,12 @@ static void handle_datastage_out (void) static void handle_datastage_in (void) { uint32_t len = USB_MAX_PACKET_SIZE;; - const uint8_t *buf; if ((data_p->len == 0) && (dev_p->state == LAST_IN_DATA)) { - if (data_p->require_zlp == TRUE) + if (data_p->require_zlp) { - data_p->require_zlp = FALSE; + data_p->require_zlp = 0; /* No more data to send. Send empty packet */ st103_set_tx_count (ENDP0, 0); @@ -467,37 +455,33 @@ static void handle_datastage_in (void) if (len > data_p->len) len = data_p->len; - buf = (const uint8_t *)data_p->addr + data_p->offset; - usb_lld_to_pmabuf (buf, st103_get_tx_addr (ENDP0), len); + usb_lld_to_pmabuf (data_p->addr, st103_get_tx_addr (ENDP0), len); data_p->len -= len; - data_p->offset += len; + data_p->addr += len; st103_set_tx_count (ENDP0, len); st103_ep_set_tx_status (ENDP0, EP_TX_VALID); } -typedef int (*HANDLER) (uint8_t req, - uint16_t value, uint16_t index, uint16_t length); +typedef int (*HANDLER) (uint8_t req, struct control_info *detail); -static int std_none (uint8_t req, - uint16_t value, uint16_t index, uint16_t length) +static int std_none (uint8_t req, struct control_info *detail) { - (void)req; (void)value; (void)index; (void)length; + (void)req; (void)detail; return USB_UNSUPPORT; } -static int std_get_status (uint8_t req, - uint16_t value, uint16_t index, uint16_t length) +static int std_get_status (uint8_t req, struct control_info *detail) { uint8_t rcp = req & RECIPIENT; uint16_t status_info = 0; - if (value != 0 || length != 2 || (index >> 8) != 0 + if (detail->value != 0 || detail->len != 2 || (detail->index >> 8) != 0 || (req & REQUEST_DIR) == 0) return USB_UNSUPPORT; if (rcp == DEVICE_RECIPIENT) { - if (index == 0) + if (detail->index == 0) { /* Get Device Status */ uint8_t feature = dev_p->current_feature; @@ -514,7 +498,7 @@ static int std_get_status (uint8_t req, else /* Self-powered */ status_info &= ~1; - return usb_lld_answer_control (&status_info, 2); + return usb_lld_reply_request (&status_info, 2, detail); } } else if (rcp == INTERFACE_RECIPIENT) @@ -524,21 +508,21 @@ static int std_get_status (uint8_t req, if (dev_p->current_configuration == 0) return USB_UNSUPPORT; - r = usb_cb_interface (USB_QUERY_INTERFACE, index, 0); + r = usb_cb_interface (USB_QUERY_INTERFACE, detail); if (r != USB_SUCCESS) return USB_UNSUPPORT; - return usb_lld_answer_control (&status_info, 2); + return usb_lld_reply_request (&status_info, 2, detail); } else if (rcp == ENDPOINT_RECIPIENT) { - uint8_t endpoint = (index & 0x0f); + uint8_t endpoint = (detail->index & 0x0f); uint16_t status; - if ((index & 0x70) || endpoint == ENDP0) + if ((detail->index & 0x70) || endpoint == ENDP0) return USB_UNSUPPORT; - if ((index & 0x80)) + if ((detail->index & 0x80)) { status = st103_ep_get_tx_status (endpoint); if (status == 0) /* Disabled */ @@ -555,14 +539,13 @@ static int std_get_status (uint8_t req, status_info |= 1; /* OUT Endpoint stalled */ } - return usb_lld_answer_control (&status_info, 2); + return usb_lld_reply_request (&status_info, 2, detail); } return USB_UNSUPPORT; } -static int std_clear_feature (uint8_t req, uint16_t value, - uint16_t index, uint16_t length) +static int std_clear_feature (uint8_t req, struct control_info *detail) { uint8_t rcp = req & RECIPIENT; @@ -571,10 +554,10 @@ static int std_clear_feature (uint8_t req, uint16_t value, if (rcp == DEVICE_RECIPIENT) { - if (length != 0 || index != 0) + if (detail->len != 0 || detail->index != 0) return USB_UNSUPPORT; - if (value == DEVICE_REMOTE_WAKEUP) + if (detail->value == DEVICE_REMOTE_WAKEUP) { dev_p->current_feature &= ~(1 << 5); return USB_SUCCESS; @@ -582,17 +565,17 @@ static int std_clear_feature (uint8_t req, uint16_t value, } else if (rcp == ENDPOINT_RECIPIENT) { - uint8_t endpoint = (index & 0x0f); + uint8_t endpoint = (detail->index & 0x0f); uint16_t status; if (dev_p->current_configuration == 0) return USB_UNSUPPORT; - if (length != 0 || (index >> 8) != 0 || value != ENDPOINT_STALL - || endpoint == ENDP0) + if (detail->len != 0 || (detail->index >> 8) != 0 + || detail->value != ENDPOINT_STALL || endpoint == ENDP0) return USB_UNSUPPORT; - if ((index & 0x80)) + if ((detail->index & 0x80)) status = st103_ep_get_tx_status (endpoint); else status = st103_ep_get_rx_status (endpoint); @@ -600,7 +583,7 @@ static int std_clear_feature (uint8_t req, uint16_t value, if (status == 0) /* Disabled */ return USB_UNSUPPORT; - if (index & 0x80) /* IN endpoint */ + if (detail->index & 0x80) /* IN endpoint */ st103_ep_clear_dtog_tx (endpoint); else /* OUT endpoint */ st103_ep_clear_dtog_rx (endpoint); @@ -612,8 +595,7 @@ static int std_clear_feature (uint8_t req, uint16_t value, return USB_UNSUPPORT; } -static int std_set_feature (uint8_t req, uint16_t value, - uint16_t index, uint16_t length) +static int std_set_feature (uint8_t req, struct control_info *detail) { uint8_t rcp = req & RECIPIENT; @@ -622,10 +604,10 @@ static int std_set_feature (uint8_t req, uint16_t value, if (rcp == DEVICE_RECIPIENT) { - if (length != 0 || index != 0) + if (detail->len != 0 || detail->index != 0) return USB_UNSUPPORT; - if (value == DEVICE_REMOTE_WAKEUP) + if (detail->value == DEVICE_REMOTE_WAKEUP) { dev_p->current_feature |= 1 << 5; // event?? @@ -634,16 +616,17 @@ static int std_set_feature (uint8_t req, uint16_t value, } else if (rcp == ENDPOINT_RECIPIENT) { - uint8_t endpoint = (index & 0x0f); + uint8_t endpoint = (detail->index & 0x0f); uint32_t status; if (dev_p->current_configuration == 0) return USB_UNSUPPORT; - if (length != 0 || (index >> 8) != 0 || value != 0 || endpoint == ENDP0) + if (detail->len != 0 || (detail->index >> 8) != 0 + || detail->value != 0 || endpoint == ENDP0) return USB_UNSUPPORT; - if ((index & 0x80)) + if ((detail->index & 0x80)) status = st103_ep_get_tx_status (endpoint); else status = st103_ep_get_rx_status (endpoint); @@ -651,7 +634,7 @@ static int std_set_feature (uint8_t req, uint16_t value, if (status == 0) /* Disabled */ return USB_UNSUPPORT; - if (index & 0x80) + if (detail->index & 0x80) /* IN endpoint */ st103_ep_set_tx_status (endpoint, EP_TX_STALL); else @@ -665,74 +648,59 @@ static int std_set_feature (uint8_t req, uint16_t value, return USB_UNSUPPORT; } -static int std_set_address (uint8_t req, uint16_t value, - uint16_t index, uint16_t length) +static int std_set_address (uint8_t req, struct control_info *detail) { uint8_t rcp = req & RECIPIENT; if ((req & REQUEST_DIR) == 1) return USB_UNSUPPORT; - if (rcp == DEVICE_RECIPIENT) - { - if (length == 0 && value <= 127 && index == 0 - && dev_p->current_configuration == 0) - return USB_SUCCESS; - } + if (rcp == DEVICE_RECIPIENT && detail->len == 0 && detail->value <= 127 + && detail->index == 0 && dev_p->current_configuration == 0) + return USB_SUCCESS; return USB_UNSUPPORT; } -static int std_get_descriptor (uint8_t req, uint16_t value, - uint16_t index, uint16_t length) +static int std_get_descriptor (uint8_t req, struct control_info *detail) { uint8_t rcp = req & RECIPIENT; if ((req & REQUEST_DIR) == 0) return USB_UNSUPPORT; - (void)length; - return usb_cb_get_descriptor (rcp, (value >> 8), (value & 0xff), - index, length); + return usb_cb_get_descriptor (rcp, (detail->value >> 8), + (detail->value & 0xff), detail); } -static int std_get_configuration (uint8_t req, uint16_t value, - uint16_t index, uint16_t length) +static int std_get_configuration (uint8_t req, struct control_info *detail) { uint8_t rcp = req & RECIPIENT; + (void)detail; if ((req & REQUEST_DIR) == 0) return USB_UNSUPPORT; - (void)value; (void)index; (void)length; if (rcp == DEVICE_RECIPIENT) - return usb_lld_answer_control (&dev_p->current_configuration, 1); + return usb_lld_reply_request (&dev_p->current_configuration, 1, detail); return USB_UNSUPPORT; } -static int std_set_configuration (uint8_t req, uint16_t value, - uint16_t index, uint16_t length) +static int std_set_configuration (uint8_t req, struct control_info *detail) { uint8_t rcp = req & RECIPIENT; if ((req & REQUEST_DIR) == 1) return USB_UNSUPPORT; - if (rcp == DEVICE_RECIPIENT && index == 0 && length == 0) - { - int r; - - r = usb_cb_handle_event (USB_EVENT_CONFIG, value); - if (r == USB_SUCCESS) - return USB_SUCCESS; - } + if (rcp == DEVICE_RECIPIENT && detail->index == 0 && detail->len == 0) + return usb_cb_handle_event (USB_EVENT_CONFIG, detail->value); return USB_UNSUPPORT; } -static int std_get_interface (uint8_t req, uint16_t value, - uint16_t index, uint16_t length) +static int std_get_interface (uint8_t req, struct control_info *detail) { uint8_t rcp = req & RECIPIENT; @@ -741,74 +709,61 @@ static int std_get_interface (uint8_t req, uint16_t value, if (rcp == INTERFACE_RECIPIENT) { - if (value != 0 || (index >> 8) != 0 || length != 1) + if (detail->value != 0 || (detail->index >> 8) != 0 || detail->len != 1) return USB_UNSUPPORT; if (dev_p->current_configuration == 0) return USB_UNSUPPORT; - return usb_cb_interface (USB_GET_INTERFACE, index, 0); + return usb_cb_interface (USB_GET_INTERFACE, detail); } return USB_UNSUPPORT; } -static int std_set_interface (uint8_t req, uint16_t value, - uint16_t index, uint16_t length) +static int std_set_interface (uint8_t req, struct control_info *detail) { uint8_t rcp = req & RECIPIENT; - if ((req & REQUEST_DIR) == 1) + if ((req & REQUEST_DIR) == 1 || rcp != INTERFACE_RECIPIENT + || detail->len != 0 || (detail->index >> 8) != 0 + || (detail->value >> 8) != 0 || dev_p->current_configuration != 0) return USB_UNSUPPORT; - if (rcp == INTERFACE_RECIPIENT) - { - int r; - - if (length != 0 || (index >> 8) != 0 || (value >> 8) != 0) - return USB_UNSUPPORT; - - if (dev_p->current_configuration != 0) - return USB_UNSUPPORT; - - r = usb_cb_interface (USB_SET_INTERFACE, index, value); - if (r == USB_SUCCESS) - return USB_SUCCESS; - } - - return USB_UNSUPPORT; + return usb_cb_interface (USB_SET_INTERFACE, detail); } static void handle_setup0 (void) { const uint16_t *pw; + struct control_info ctrl; uint16_t w; - uint8_t req; + uint8_t req_no; int r = USB_UNSUPPORT; HANDLER handler; pw = (uint16_t *)(PMA_ADDR + (uint8_t *)(st103_get_rx_addr (ENDP0) * 2)); w = *pw++; - ctrl_p->bmRequestType = w & 0xff; - ctrl_p->bRequest = req = w >> 8; + dev_p->bmRequestType = w & 0xff; + dev_p->bRequest = req_no = w >> 8; pw++; - ctrl_p->wValue = *pw++; + ctrl.value = *pw++; pw++; - ctrl_p->wIndex = *pw++; + ctrl.index = *pw++; pw++; - ctrl_p->wLength = *pw; + ctrl.len = *pw; data_p->addr = NULL; data_p->len = 0; - data_p->offset = 0; + data_p->require_zlp = 0; - if ((ctrl_p->bmRequestType & REQUEST_TYPE) == STANDARD_REQUEST) + if ((dev_p->bmRequestType & REQUEST_TYPE) == STANDARD_REQUEST) { - if (req < TOTAL_REQUEST) + if (req_no < TOTAL_REQUEST) { - switch (req) + switch (req_no) { case 0: handler = std_get_status; break; case 1: handler = std_clear_feature; break; @@ -822,30 +777,30 @@ static void handle_setup0 (void) default: handler = std_none; break; } - r = (*handler) (ctrl_p->bmRequestType, - ctrl_p->wValue, ctrl_p->wIndex, ctrl_p->wLength); + r = (*handler) (dev_p->bmRequestType, &ctrl); } } else - r = usb_cb_setup (ctrl_p->bmRequestType, req, - ctrl_p->wValue, ctrl_p->wIndex, ctrl_p->wLength); + r = usb_cb_setup (dev_p->bmRequestType, req_no, &ctrl); if (r != USB_SUCCESS) dev_p->state = STALLED; else { - if (USB_SETUP_GET (ctrl_p->bmRequestType)) - ; - else if (ctrl_p->wLength == 0) + if (USB_SETUP_SET (dev_p->bmRequestType)) { - dev_p->state = WAIT_STATUS_IN; - st103_set_tx_count (ENDP0, 0); - st103_ep_set_rxtx_status (ENDP0, EP_RX_STALL, EP_TX_VALID); - } - else - { - dev_p->state = OUT_DATA; - st103_ep_set_rx_status (ENDP0, EP_RX_VALID); + dev_p->value = ctrl.value; + if (ctrl.len == 0) + { + dev_p->state = WAIT_STATUS_IN; + st103_set_tx_count (ENDP0, 0); + st103_ep_set_rxtx_status (ENDP0, EP_RX_STALL, EP_TX_VALID); + } + else + { + dev_p->state = OUT_DATA; + st103_ep_set_rx_status (ENDP0, EP_RX_VALID); + } } } } @@ -856,17 +811,16 @@ static void handle_in0 (void) handle_datastage_in (); else if (dev_p->state == WAIT_STATUS_IN) { - if ((ctrl_p->bRequest == SET_ADDRESS) && - ((ctrl_p->bmRequestType & (REQUEST_TYPE | RECIPIENT)) + if ((dev_p->bRequest == SET_ADDRESS) && + ((dev_p->bmRequestType & (REQUEST_TYPE | RECIPIENT)) == (STANDARD_REQUEST | DEVICE_RECIPIENT))) { - st103_set_daddr (ctrl_p->wValue); - usb_cb_handle_event (USB_EVENT_ADDRESS, ctrl_p->wValue); + st103_set_daddr (dev_p->value); + usb_cb_handle_event (USB_EVENT_ADDRESS, dev_p->value); } else - usb_cb_ctrl_write_finish (ctrl_p->bmRequestType, - ctrl_p->bRequest, ctrl_p->wValue, - ctrl_p->wIndex, ctrl_p->wLength); + usb_cb_ctrl_write_finish (dev_p->bmRequestType, dev_p->bRequest, + dev_p->value); dev_p->state = STALLED; } @@ -1175,9 +1129,9 @@ void usb_lld_from_pmabuf (void *dst, uint16_t addr, size_t n) * BUFLEN: size of the data. */ int -usb_lld_answer_control (const void *buf, size_t buflen) +usb_lld_reply_request (const void *buf, size_t buflen, struct control_info *ctl) { - uint32_t len_asked = ctrl_p->wLength; + uint32_t len_asked = ctl->len; uint32_t len; data_p->addr = (void *)buf; @@ -1188,9 +1142,7 @@ usb_lld_answer_control (const void *buf, size_t buflen) data_p->len = len_asked; if (data_p->len != 0 && (data_p->len % USB_MAX_PACKET_SIZE) == 0) - data_p->require_zlp = TRUE; - else - data_p->require_zlp = FALSE; + data_p->require_zlp = 1; if (data_p->len < USB_MAX_PACKET_SIZE) { @@ -1207,7 +1159,7 @@ usb_lld_answer_control (const void *buf, size_t buflen) { usb_lld_to_pmabuf (data_p->addr, st103_get_tx_addr (ENDP0), len); data_p->len -= len; - data_p->offset += len; + data_p->addr += len; } st103_set_tx_count (ENDP0, len);