From a96a3eefe663c0faf4e1f5970ab8d3c13c5b225c Mon Sep 17 00:00:00 2001 From: Niibe Yutaka Date: Tue, 14 Jun 2016 14:29:17 +0900 Subject: [PATCH] Update Chopstx, follow the change of USB API --- ChangeLog | 31 +++++ chopstx | 2 +- regnual/regnual.c | 200 ++++++++++++++++++++----------- src/usb-ccid.c | 127 ++++++++++++++++---- src/usb-msc.c | 10 +- src/usb_ctrl.c | 292 ++++++++++++++++++++++++---------------------- src/usb_desc.c | 28 ++--- 7 files changed, 440 insertions(+), 250 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0fe540f..86ed5fb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,34 @@ +2016-06-14 Niibe Yutaka + + * regnual/regnual.c (usb_device_reset): Rename from + usb_cb_device_reset. + (usb_ctrl_write_finish): Rename from usb_cb_ctrl_write_finish. + (usb_setup): Rename from usb_cb_setup. + (usb_get_descriptor): Rename from usb_cb_get_descriptor. + (usb_set_configuration): New. + (usb_interrupt_handler): New. + + * src/usb-ccid.c (usb_tx_done): Rename from usb_cb_tx_done. + (usb_rx_ready): Rename from usb_cb_rx_ready. + (usb_event_handle): New. + (ccid_thread): Use usb_event_handle. + + * src/usb-msc.c (EP6_IN_Callback): Update to new USB API. + (EP6_OUT_Callback): Likewise. + + * src/usb_ctrl.c (usb_device_reset): Rename from + usb_cb_device_reset. + (vcom_port_data_setup): Update to new USB API. + (usb_ctrl_write_finish): Rename from usb_cb_ctrl_write_finish. + (usb_setup): Rename from usb_cb_setup. + (usb_set_configuration): New, based on usb_cb_handle_event. + (usb_set_interface): Rename from usb_cb_interface. + (usb_get_interface): New. + (usb_get_status_interface): New. + + * src/usb_desc.c (usb_get_descriptor): Rename from + usb_cb_get_descriptor. + 2016-06-02 Niibe Yutaka * regnual/regnual.c (usb_cb_tx_done): Follow the change of USB diff --git a/chopstx b/chopstx index 78718e5..a6541cb 160000 --- a/chopstx +++ b/chopstx @@ -1 +1 @@ -Subproject commit 78718e57df6f55c0670cdb6b70337204dd045dba +Subproject commit a6541cbcc650e86c893e5de2a8ca8c5607939c55 diff --git a/regnual/regnual.c b/regnual/regnual.c index 01cea34..e472669 100644 --- a/regnual/regnual.c +++ b/regnual/regnual.c @@ -109,10 +109,10 @@ static const uint8_t regnual_string_serial[] = { }; -void -usb_cb_device_reset (void) +static void +usb_device_reset (struct usb_dev *dev) { - usb_lld_reset (REGNUAL_FEATURE_INIT); + usb_lld_reset (dev, REGNUAL_FEATURE_INIT); /* Initialize Endpoint 0 */ usb_lld_setup_endpoint (ENDP0, EP_CONTROL, 0, ENDP0_RXADDR, ENDP0_TXADDR, @@ -169,95 +169,101 @@ static uint32_t calc_crc32 (void) } -void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, - struct req_args *arg) +static void +usb_ctrl_write_finish (struct usb_dev *dev) { - uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT); + struct device_req *arg = &dev->dev_req; + uint8_t type_rcp = arg->type & (REQUEST_TYPE|RECIPIENT); - if (type_rcp == (VENDOR_REQUEST | DEVICE_RECIPIENT) && USB_SETUP_SET (req)) + if (type_rcp == (VENDOR_REQUEST | DEVICE_RECIPIENT) + && USB_SETUP_SET (arg->type)) { - if (req_no == USB_REGNUAL_SEND && arg->value == 0) + if (arg->request == USB_REGNUAL_SEND && arg->value == 0) result = calc_crc32 (); - else if (req_no == USB_REGNUAL_FLASH) + else if (arg->request == USB_REGNUAL_FLASH) { uint32_t dst_addr = (0x08000000 + arg->value * 0x100); result = flash_write (dst_addr, (const uint8_t *)mem, 256); } - else if (req_no == USB_REGNUAL_PROTECT && arg->value == 0) + else if (arg->request == USB_REGNUAL_PROTECT && arg->value == 0) result = flash_protect (); - else if (req_no == USB_REGNUAL_FINISH && arg->value == 0) + else if (arg->request == USB_REGNUAL_FINISH && arg->value == 0) nvic_system_reset (); } } -int -usb_cb_setup (uint8_t req, uint8_t req_no, struct req_args *arg) +static int +usb_setup (struct usb_dev *dev) { - uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT); + struct device_req *arg = &dev->dev_req; + uint8_t type_rcp = arg->type & (REQUEST_TYPE|RECIPIENT); if (type_rcp == (VENDOR_REQUEST | DEVICE_RECIPIENT)) { - if (USB_SETUP_GET (req)) + if (USB_SETUP_GET (arg->type)) { - if (req_no == USB_REGNUAL_MEMINFO) + if (arg->request == USB_REGNUAL_MEMINFO) { const uint8_t *mem_info[2]; mem_info[0] = (const uint8_t *)FLASH_START; mem_info[1] = (const uint8_t *)flash_end; - return usb_lld_reply_request (mem_info, sizeof (mem_info), arg); + return usb_lld_ctrl_send (dev, mem_info, sizeof (mem_info)); } - else if (req_no == USB_REGNUAL_RESULT) - return usb_lld_reply_request (&result, sizeof (uint32_t), arg); + else if (arg->request == USB_REGNUAL_RESULT) + return usb_lld_ctrl_send (dev, &result, sizeof (uint32_t)); } else /* SETUP_SET */ { - if (req_no == USB_REGNUAL_SEND) + if (arg->request == USB_REGNUAL_SEND) { if (arg->value != 0 || arg->index + arg->len > 256) - return USB_UNSUPPORT; + return -1; if (arg->index + arg->len < 256) memset ((uint8_t *)mem + arg->index + arg->len, 0xff, 256 - (arg->index + arg->len)); - usb_lld_set_data_to_recv (mem + arg->index, arg->len); - return USB_SUCCESS; + return usb_lld_ctrl_recv (dev, mem + arg->index, arg->len); } - else if (req_no == USB_REGNUAL_FLASH && arg->len == 0 + else if (arg->request == USB_REGNUAL_FLASH && arg->len == 0 && arg->index == 0) { uint32_t dst_addr = (0x08000000 + arg->value * 0x100); if (dst_addr + 256 <= flash_end) - return USB_SUCCESS; + return usb_lld_ctrl_ack (dev); } - else if (req_no == USB_REGNUAL_PROTECT && arg->len == 0 + else if (arg->request == USB_REGNUAL_PROTECT && arg->len == 0 && arg->value == 0 && arg->index == 0) - return USB_SUCCESS; - else if (req_no == USB_REGNUAL_FINISH && arg->len == 0 + return usb_lld_ctrl_ack (dev); + else if (arg->request == USB_REGNUAL_FINISH && arg->len == 0 && arg->value == 0 && arg->index == 0) - return USB_SUCCESS; + return usb_lld_ctrl_ack (dev); } } - return USB_UNSUPPORT; + return -1; } -int -usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index, - struct req_args *arg) +static int +usb_get_descriptor (struct usb_dev *dev) { + struct device_req *arg = &dev->dev_req; + uint8_t rcp = arg->type & RECIPIENT; + uint8_t desc_type = (arg->value >> 8); + uint8_t desc_index = (arg->value & 0xff); + if (rcp != DEVICE_RECIPIENT) - return USB_UNSUPPORT; + return -1; if (desc_type == DEVICE_DESCRIPTOR) - return usb_lld_reply_request (regnual_device_desc, - sizeof (regnual_device_desc), arg); + return usb_lld_ctrl_send (dev, regnual_device_desc, + sizeof (regnual_device_desc)); else if (desc_type == CONFIG_DESCRIPTOR) - return usb_lld_reply_request (regnual_config_desc, - sizeof (regnual_config_desc), arg); + return usb_lld_ctrl_send (dev, regnual_config_desc, + sizeof (regnual_config_desc)); else if (desc_type == STRING_DESCRIPTOR) { const uint8_t *str; @@ -282,47 +288,40 @@ usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index, size = sizeof (regnual_string_serial); break; default: - return USB_UNSUPPORT; + return -1; } - return usb_lld_reply_request (str, size, arg); + return usb_lld_ctrl_send (dev, str, size); } - return USB_UNSUPPORT; + return -1; } -int usb_cb_handle_event (uint8_t event_type, uint16_t value) +static int +usb_set_configuration (struct usb_dev *dev) { - (void)value; + uint8_t current_conf; - switch (event_type) + current_conf = usb_lld_current_configuration (dev); + if (current_conf == 0) { - case USB_EVENT_ADDRESS: - case USB_EVENT_CONFIG: - return USB_SUCCESS; - default: - break; + if (dev->dev_req.value != 1) + return -1; + + usb_lld_set_configuration (dev, 1); + } + else if (current_conf != dev->dev_req.value) + { + if (dev->dev_req.value != 0) + return -1; + + usb_lld_set_configuration (dev, 0); } - return USB_UNSUPPORT; + /* Do nothing when current_conf == value */ + return usb_lld_ctrl_ack (dev); } -int usb_cb_interface (uint8_t cmd, struct req_args *arg) -{ - (void)cmd; (void)arg; - return USB_UNSUPPORT; -} - -void usb_cb_rx_ready (uint8_t ep_num) -{ - (void)ep_num; -} - -void usb_cb_tx_done (uint8_t ep_num, uint32_t len) -{ - (void)ep_num; - (void)len; -} static void wait (int count) { @@ -357,6 +356,7 @@ static void nvic_enable_intr (uint8_t irq_num) } #define USB_LP_CAN1_RX0_IRQn 20 +static struct usb_dev dev; int main (int argc, char *argv[]) @@ -372,7 +372,7 @@ main (int argc, char *argv[]) * USB interrupt is disabled by NVIC setting. * We enable the interrupt again by nvic_enable_intr. */ - usb_lld_init (REGNUAL_FEATURE_INIT); + usb_lld_init (&dev, REGNUAL_FEATURE_INIT); nvic_enable_intr (USB_LP_CAN1_RX0_IRQn); while (1) @@ -383,3 +383,69 @@ main (int argc, char *argv[]) wait (WAIT); } } + +void +usb_interrupt_handler (void) +{ + uint8_t ep_num; + int e; + + e = usb_lld_event_handler (&dev); + ep_num = USB_EVENT_ENDP (e); + + if (ep_num == 0) + switch (USB_EVENT_ID (e)) + { + case USB_EVENT_DEVICE_RESET: + usb_device_reset (&dev); + break; + + case USB_EVENT_DEVICE_ADDRESSED: + break; + + case USB_EVENT_GET_DESCRIPTOR: + if (usb_get_descriptor (&dev) < 0) + usb_lld_ctrl_error (&dev); + break; + + case USB_EVENT_SET_CONFIGURATION: + if (usb_set_configuration (&dev) < 0) + usb_lld_ctrl_error (&dev); + break; + + case USB_EVENT_SET_INTERFACE: + usb_lld_ctrl_error (&dev); + break; + + case USB_EVENT_CTRL_REQUEST: + /* Device specific device request. */ + if (usb_setup (&dev) < 0) + usb_lld_ctrl_error (&dev); + break; + + case USB_EVENT_GET_STATUS_INTERFACE: + usb_lld_ctrl_error (&dev); + break; + + case USB_EVENT_GET_INTERFACE: + usb_lld_ctrl_error (&dev); + break; + + case USB_EVENT_SET_FEATURE_DEVICE: + case USB_EVENT_SET_FEATURE_ENDPOINT: + case USB_EVENT_CLEAR_FEATURE_DEVICE: + case USB_EVENT_CLEAR_FEATURE_ENDPOINT: + usb_lld_ctrl_ack (&dev); + break; + + case USB_EVENT_CTRL_WRITE_FINISH: + /* Control WRITE transfer finished. */ + usb_ctrl_write_finish (&dev); + break; + + case USB_EVENT_OK: + case USB_EVENT_DEVICE_SUSPEND: + default: + break; + } +} diff --git a/src/usb-ccid.c b/src/usb-ccid.c index 163965d..fcd3753 100644 --- a/src/usb-ccid.c +++ b/src/usb-ccid.c @@ -358,10 +358,11 @@ static void get_sw1sw2 (struct ep_in *epi, size_t len) * Tx done callback */ static void -EP1_IN_Callback (void) +EP1_IN_Callback (uint16_t len) { struct ep_in *epi = &endpoint_in; + (void)len; if (epi->buf == NULL) if (epi->tx_done) epi->notify (epi); @@ -635,10 +636,9 @@ ccid_prepare_receive (struct ccid *c) */ static void -EP1_OUT_Callback (void) +EP1_OUT_Callback (uint16_t len) { struct ep_out *epo = &endpoint_out; - size_t len = usb_lld_rx_data_len (epo->ep_num); int offset = 0; int cont; size_t orig_len = len; @@ -675,13 +675,13 @@ EP1_OUT_Callback (void) } -extern void EP6_IN_Callback (void); +extern void EP6_IN_Callback (uint16_t len); -void -usb_cb_rx_ready (uint8_t ep_num) +static void +usb_rx_ready (uint8_t ep_num, uint16_t len) { if (ep_num == ENDP1) - EP1_OUT_Callback (); + EP1_OUT_Callback (len); #ifdef DEBUG else if (ep_num == ENDP5) { @@ -692,12 +692,11 @@ usb_cb_rx_ready (uint8_t ep_num) #endif } -void -usb_cb_tx_done (uint8_t ep_num, uint32_t len) +static void +usb_tx_done (uint8_t ep_num, uint16_t len) { - (void)len; if (ep_num == ENDP1) - EP1_IN_Callback (); + EP1_IN_Callback (len); else if (ep_num == ENDP2) { /* INTERRUPT Transfer done */ @@ -712,7 +711,7 @@ usb_cb_tx_done (uint8_t ep_num, uint32_t len) #endif #ifdef PINPAD_SUPPORT else if (ep_num == ENDP6) - EP6_IN_Callback (); + EP6_IN_Callback (len); #endif } @@ -1391,14 +1390,102 @@ ccid_notify_slot_change (struct ccid *c) #define INTR_REQ_USB 20 +extern uint32_t bDeviceState; +extern void usb_device_reset (struct usb_dev *dev); +extern int usb_setup (struct usb_dev *dev); +extern void usb_ctrl_write_finish (struct usb_dev *dev); +extern int usb_set_configuration (struct usb_dev *dev); +extern int usb_set_interface (struct usb_dev *dev); +extern int usb_get_interface (struct usb_dev *dev); +extern int usb_get_status_interface (struct usb_dev *dev); + +extern int usb_get_descriptor (struct usb_dev *dev); + +static void +usb_event_handle (struct usb_dev *dev) +{ + uint8_t ep_num; + int e; + + e = usb_lld_event_handler (dev); + ep_num = USB_EVENT_ENDP (e); + + if (ep_num != 0) + { + if (USB_EVENT_TXRX (e)) + usb_tx_done (ep_num, USB_EVENT_LEN (e)); + else + usb_rx_ready (ep_num, USB_EVENT_LEN (e)); + } + else + switch (USB_EVENT_ID (e)) + { + case USB_EVENT_DEVICE_RESET: + usb_device_reset (dev); + break; + + case USB_EVENT_DEVICE_ADDRESSED: + bDeviceState = ADDRESSED; + break; + + case USB_EVENT_GET_DESCRIPTOR: + if (usb_get_descriptor (dev) < 0) + usb_lld_ctrl_error (dev); + break; + + case USB_EVENT_SET_CONFIGURATION: + if (usb_set_configuration (dev) < 0) + usb_lld_ctrl_error (dev); + break; + + case USB_EVENT_SET_INTERFACE: + if (usb_set_interface (dev) < 0) + usb_lld_ctrl_error (dev); + break; + + case USB_EVENT_CTRL_REQUEST: + /* Device specific device request. */ + if (usb_setup (dev) < 0) + usb_lld_ctrl_error (dev); + break; + + case USB_EVENT_GET_STATUS_INTERFACE: + if (usb_get_status_interface (dev) < 0) + usb_lld_ctrl_error (dev); + break; + + case USB_EVENT_GET_INTERFACE: + if (usb_get_interface (dev) < 0) + usb_lld_ctrl_error (dev); + break; + + case USB_EVENT_SET_FEATURE_DEVICE: + case USB_EVENT_SET_FEATURE_ENDPOINT: + case USB_EVENT_CLEAR_FEATURE_DEVICE: + case USB_EVENT_CLEAR_FEATURE_ENDPOINT: + usb_lld_ctrl_ack (dev); + break; + + case USB_EVENT_CTRL_WRITE_FINISH: + /* Control WRITE transfer finished. */ + usb_ctrl_write_finish (dev); + break; + + case USB_EVENT_OK: + case USB_EVENT_DEVICE_SUSPEND: + default: + break; + } +} + void * ccid_thread (void *arg) { - extern uint32_t bDeviceState; chopstx_intr_t interrupt; uint32_t timeout; eventmask_t m; chopstx_poll_cond_t poll_desc; + struct usb_dev dev; struct ep_in *epi = &endpoint_in; struct ep_out *epo = &endpoint_out; @@ -1410,9 +1497,9 @@ ccid_thread (void *arg) eventflag_init (&ccid.ccid_comm); eventflag_init (&ccid.openpgp_comm); - usb_lld_init (USB_INITIAL_FEATURE); + usb_lld_init (&dev, USB_INITIAL_FEATURE); chopstx_claim_irq (&interrupt, INTR_REQ_USB); - usb_interrupt_handler (); /* For old SYS < 3.0 */ + usb_event_handle (&dev); /* For old SYS < 3.0 */ device_reset: epi_init (epi, ENDP1, notify_tx, c); @@ -1425,10 +1512,8 @@ ccid_thread (void *arg) eventflag_prepare_poll (&c->ccid_comm, &poll_desc); chopstx_poll (NULL, 2, &interrupt, &poll_desc); if (interrupt.ready) - { - usb_interrupt_handler (); - continue; - } + usb_event_handle (&dev); + m = eventflag_get (&c->ccid_comm); /* Ignore event while not-configured. */ } @@ -1443,7 +1528,7 @@ ccid_thread (void *arg) chopstx_poll (&timeout, 2, &interrupt, &poll_desc); if (interrupt.ready) { - usb_interrupt_handler (); + usb_event_handle (&dev); continue; } @@ -1553,7 +1638,7 @@ ccid_thread (void *arg) while (bDeviceState != UNCONNECTED) { chopstx_poll (NULL, 1, &interrupt); - usb_interrupt_handler (); + usb_event_handle (&dev); } return NULL; diff --git a/src/usb-msc.c b/src/usb-msc.c index 43c2643..1cb94b2 100644 --- a/src/usb-msc.c +++ b/src/usb-msc.c @@ -86,13 +86,12 @@ static void usb_start_transmit (const uint8_t *p, size_t n) /* "Data Transmitted" callback */ void -EP6_IN_Callback (void) +EP6_IN_Callback (uint16_t len) { - size_t n; + size_t n = len; chopstx_mutex_lock (msc_mutex); - n = (size_t)usb_lld_tx_data_len (ENDP6); ep6_in.txbuf += n; ep6_in.txcnt += n; ep6_in.txsize -= n; @@ -132,14 +131,13 @@ static void usb_start_receive (uint8_t *p, size_t n) /* "Data Received" call back */ void -EP6_OUT_Callback (void) +EP6_OUT_Callback (uint16_t len) { - size_t n; + size_t n = len; int err = 0; chopstx_mutex_lock (msc_mutex); - n = (size_t)usb_lld_rx_data_len (ENDP6); if (n > ep6_out.rxsize) { /* buffer overflow */ err = 1; diff --git a/src/usb_ctrl.c b/src/usb_ctrl.c index aac942c..6464edb 100644 --- a/src/usb_ctrl.c +++ b/src/usb_ctrl.c @@ -61,47 +61,25 @@ static struct line_coding line_coding = { #define CDC_CTRL_DTR 0x0001 static int -vcom_port_data_setup (uint8_t req, uint8_t req_no, struct req_args *arg) +vcom_port_data_setup (struct usb_dev *dev) { - if (USB_SETUP_GET (req)) + struct device_req *arg = &dev->dev_req; + + if (USB_SETUP_GET (arg->type)) { - if (req_no == USB_CDC_REQ_GET_LINE_CODING) - return usb_lld_reply_request (&line_coding, sizeof(line_coding), arg); + if (arg->request == USB_CDC_REQ_GET_LINE_CODING) + return usb_lld_ctrl_send (dev, &line_coding, sizeof (line_coding)); } else /* USB_SETUP_SET (req) */ { - if (req_no == USB_CDC_REQ_SET_LINE_CODING) - { - usb_lld_set_data_to_recv (&line_coding, sizeof(line_coding)); - return USB_SUCCESS; - } - else if (req_no == USB_CDC_REQ_SET_CONTROL_LINE_STATE) - { - uint8_t connected_saved = stdout.connected; - - if ((arg->value & CDC_CTRL_DTR) != 0) - { - if (stdout.connected == 0) - /* It's Open call */ - stdout.connected++; - } - else - { - if (stdout.connected) - /* Close call */ - stdout.connected = 0; - } - - chopstx_mutex_lock (&stdout.m_dev); - if (stdout.connected != connected_saved) - chopstx_cond_signal (&stdout.cond_dev); - chopstx_mutex_unlock (&stdout.m_dev); - - return USB_SUCCESS; - } + if (arg->request == USB_CDC_REQ_SET_LINE_CODING + && arg->len == sizeof (line_coding)) + return usb_lld_ctrl_recv (dev, &line_coding, sizeof (line_coding)); + else if (arg->request == USB_CDC_REQ_SET_CONTROL_LINE_STATE) + return usb_lld_ctrl_ack (dev); } - return USB_UNSUPPORT; + return -1; } #endif @@ -195,11 +173,11 @@ gnuk_setup_endpoints_for_interface (uint16_t interface, int stop) } void -usb_cb_device_reset (void) +usb_device_reset (struct usb_dev *dev) { int i; - usb_lld_reset (USB_INITIAL_FEATURE); + usb_lld_reset (dev, USB_INITIAL_FEATURE); /* Initialize Endpoint 0 */ usb_lld_setup_endpoint (ENDP0, EP_CONTROL, 0, ENDP0_RXADDR, ENDP0_TXADDR, @@ -240,7 +218,7 @@ static uint32_t rbit (uint32_t v) } /* After calling this function, CRC module remain enabled. */ -static int download_check_crc32 (const uint32_t *end_p) +static int download_check_crc32 (struct usb_dev *dev, const uint32_t *end_p) { uint32_t crc32 = *end_p; const uint32_t *p; @@ -252,60 +230,60 @@ static int download_check_crc32 (const uint32_t *end_p) CRC->DR = rbit (*p); if ((rbit (CRC->DR) ^ crc32) == 0xffffffff) - return USB_SUCCESS; + return usb_lld_ctrl_ack (dev); - return USB_UNSUPPORT; + return -1; } int -usb_cb_setup (uint8_t req, uint8_t req_no, struct req_args *arg) +usb_setup (struct usb_dev *dev) { - uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT); + struct device_req *arg = &dev->dev_req; + uint8_t type_rcp = arg->type & (REQUEST_TYPE|RECIPIENT); if (type_rcp == (VENDOR_REQUEST | DEVICE_RECIPIENT)) { - if (USB_SETUP_GET (req)) + if (USB_SETUP_GET (arg->type)) { - if (req_no == USB_FSIJ_GNUK_MEMINFO) - return usb_lld_reply_request (mem_info, sizeof (mem_info), arg); + if (arg->request == USB_FSIJ_GNUK_MEMINFO) + return usb_lld_ctrl_send (dev, mem_info, sizeof (mem_info)); } else /* SETUP_SET */ { uint8_t *addr = (uint8_t *)(0x20000000 + arg->value * 0x100 + arg->index); - if (req_no == USB_FSIJ_GNUK_DOWNLOAD) + if (arg->request == USB_FSIJ_GNUK_DOWNLOAD) { if (*ccid_state_p != CCID_STATE_EXITED) - return USB_UNSUPPORT; + return -1; if (addr < &_regnual_start || addr + arg->len > __heap_end__) - return USB_UNSUPPORT; + return -1; if (arg->index + arg->len < 256) memset (addr + arg->index + arg->len, 0, 256 - (arg->index + arg->len)); - usb_lld_set_data_to_recv (addr, arg->len); - return USB_SUCCESS; + return usb_lld_ctrl_recv (dev, addr, arg->len); } - else if (req_no == USB_FSIJ_GNUK_EXEC && arg->len == 0) + else if (arg->request == USB_FSIJ_GNUK_EXEC && arg->len == 0) { if (*ccid_state_p != CCID_STATE_EXITED) - return USB_UNSUPPORT; + return -1; if (((uint32_t)addr & 0x03)) - return USB_UNSUPPORT; + return -1; - return download_check_crc32 ((uint32_t *)addr); + return download_check_crc32 (dev, (uint32_t *)addr); } - else if (req_no == USB_FSIJ_GNUK_CARD_CHANGE && arg->len == 0) + else if (arg->request == USB_FSIJ_GNUK_CARD_CHANGE && arg->len == 0) { if (arg->value != 0 && arg->value != 1 && arg->value != 2) - return USB_UNSUPPORT; + return -1; ccid_card_change_signal (arg->value); - return USB_SUCCESS; + return usb_lld_ctrl_ack (dev); } } } @@ -313,88 +291,85 @@ usb_cb_setup (uint8_t req, uint8_t req_no, struct req_args *arg) { if (arg->index == CCID_INTERFACE) { - if (USB_SETUP_GET (req)) + if (USB_SETUP_GET (arg->type)) { - if (req_no == USB_CCID_REQ_GET_CLOCK_FREQUENCIES) - return usb_lld_reply_request (freq_table, sizeof (freq_table), - arg); - else if (req_no == USB_CCID_REQ_GET_DATA_RATES) - return usb_lld_reply_request (data_rate_table, - sizeof (data_rate_table), arg); + if (arg->request == USB_CCID_REQ_GET_CLOCK_FREQUENCIES) + return usb_lld_ctrl_send (dev, freq_table, sizeof (freq_table)); + else if (arg->request == USB_CCID_REQ_GET_DATA_RATES) + return usb_lld_ctrl_send (dev, data_rate_table, + sizeof (data_rate_table)); } else { - if (req_no == USB_CCID_REQ_ABORT) + if (arg->request == USB_CCID_REQ_ABORT) /* wValue: bSeq, bSlot */ /* Abortion is not supported in Gnuk */ - return USB_UNSUPPORT; + return -1; } } #ifdef HID_CARD_CHANGE_SUPPORT else if (arg->index == HID_INTERFACE) { - switch (req_no) + switch (arg->request) { case USB_HID_REQ_GET_IDLE: - return usb_lld_reply_request (&hid_idle_rate, 1, arg); + return usb_lld_ctrl_send (dev, &hid_idle_rate, 1); case USB_HID_REQ_SET_IDLE: - usb_lld_set_data_to_recv (&hid_idle_rate, 1); - return USB_SUCCESS; + return usb_lld_ctrl_recv (dev, &hid_idle_rate, 1); case USB_HID_REQ_GET_REPORT: /* Request of LED status and key press */ - return usb_lld_reply_request (&hid_report, 2, arg); + return usb_lld_ctrl_send (dev, &hid_report, 2); case USB_HID_REQ_SET_REPORT: /* Received LED set request */ if (arg->len == 1) - usb_lld_set_data_to_recv (&hid_report, arg->len); - return USB_SUCCESS; + return usb_lld_ctrl_recv (dev, &hid_report, arg->len); + else + return usb_lld_ctrl_ack (dev); case USB_HID_REQ_GET_PROTOCOL: case USB_HID_REQ_SET_PROTOCOL: /* This driver doesn't support boot protocol. */ - return USB_UNSUPPORT; + return -1; default: - return USB_UNSUPPORT; + return -1; } } #endif #ifdef ENABLE_VIRTUAL_COM_PORT else if (arg->index == VCOM_INTERFACE_0) - return vcom_port_data_setup (req, req_no, arg); + return vcom_port_data_setup (dev); #endif #ifdef PINPAD_DND_SUPPORT else if (arg->index == MSC_INTERFACE) { if (USB_SETUP_GET (req)) { - if (req_no == MSC_GET_MAX_LUN_COMMAND) - return usb_lld_reply_request (lun_table, sizeof (lun_table), - arg); + if (arg->request == MSC_GET_MAX_LUN_COMMAND) + return usb_lld_ctrl_send (dev, lun_table, sizeof (lun_table)); } else - if (req_no == MSC_MASS_STORAGE_RESET_COMMAND) - /* Should call resetting MSC thread, something like msc_reset() */ - return USB_SUCCESS; + if (arg->request == MSC_MASS_STORAGE_RESET_COMMAND) + return usb_lld_ctrl_ack (dev); } #endif } - return USB_UNSUPPORT; + return -1; } void -usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, struct req_args *arg) +usb_ctrl_write_finish (struct usb_dev *dev) { - uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT); + struct device_req *arg = &dev->dev_req; + uint8_t type_rcp = arg->type & (REQUEST_TYPE|RECIPIENT); - (void)arg; if (type_rcp == (VENDOR_REQUEST | DEVICE_RECIPIENT)) { - if (USB_SETUP_SET (req) && req_no == USB_FSIJ_GNUK_EXEC) + if (USB_SETUP_SET (arg->type) && arg->request == USB_FSIJ_GNUK_EXEC) { if (*ccid_state_p != CCID_STATE_EXITED) return; @@ -404,10 +379,36 @@ usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, struct req_args *arg) led_blink (LED_GNUK_EXEC); /* Notify the main. */ } } -#ifdef HID_CARD_CHANGE_SUPPORT +#if defined(HID_CARD_CHANGE_SUPPORT) || defined (ENABLE_VIRTUAL_COM_PORT) else if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT)) { - if (arg->index == HID_INTERFACE && req_no == USB_HID_REQ_SET_REPORT) +# if defined(ENABLE_VIRTUAL_COM_PORT) + if (arg->index == VCOM_INTERFACE_0 && USB_SETUP_SET (arg->type) + && arg->request == USB_CDC_REQ_SET_CONTROL_LINE_STATE) + { + uint8_t connected_saved = stdout.connected; + + if ((arg->value & CDC_CTRL_DTR) != 0) + { + if (stdout.connected == 0) + /* It's Open call */ + stdout.connected++; + } + else + { + if (stdout.connected) + /* Close call */ + stdout.connected = 0; + } + + chopstx_mutex_lock (&stdout.m_dev); + if (stdout.connected != connected_saved) + chopstx_cond_signal (&stdout.cond_dev); + chopstx_mutex_unlock (&stdout.m_dev); + } +# endif +# if defined(HID_CARD_CHANGE_SUPPORT) + if (arg->index == HID_INTERFACE && arg->request == USB_HID_REQ_SET_REPORT) { if ((hid_report ^ hid_report_saved) & HID_LED_STATUS_CARDCHANGE) ccid_card_change_signal (CARD_CHANGE_TOGGLE); @@ -415,78 +416,85 @@ usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, struct req_args *arg) hid_report_saved = hid_report; } } +# endif #endif } -int usb_cb_handle_event (uint8_t event_type, uint16_t value) +int +usb_set_configuration (struct usb_dev *dev) { int i; uint8_t current_conf; - switch (event_type) + current_conf = usb_lld_current_configuration (dev); + if (current_conf == 0) { - case USB_EVENT_ADDRESS: + if (dev->dev_req.value != 1) + return -1; + + usb_lld_set_configuration (dev, 1); + for (i = 0; i < NUM_INTERFACES; i++) + gnuk_setup_endpoints_for_interface (i, 0); + bDeviceState = CONFIGURED; + } + else if (current_conf != dev->dev_req.value) + { + if (dev->dev_req.value != 0) + return -1; + + usb_lld_set_configuration (dev, 0); + for (i = 0; i < NUM_INTERFACES; i++) + gnuk_setup_endpoints_for_interface (i, 1); bDeviceState = ADDRESSED; - return USB_SUCCESS; - case USB_EVENT_CONFIG: - current_conf = usb_lld_current_configuration (); - if (current_conf == 0) - { - if (value != 1) - return USB_UNSUPPORT; - - usb_lld_set_configuration (value); - for (i = 0; i < NUM_INTERFACES; i++) - gnuk_setup_endpoints_for_interface (i, 0); - bDeviceState = CONFIGURED; - } - else if (current_conf != value) - { - if (value != 0) - return USB_UNSUPPORT; - - usb_lld_set_configuration (0); - for (i = 0; i < NUM_INTERFACES; i++) - gnuk_setup_endpoints_for_interface (i, 1); - bDeviceState = ADDRESSED; - ccid_usb_reset (1); - } - /* Do nothing when current_conf == value */ - return USB_SUCCESS; - default: - break; + ccid_usb_reset (1); } - return USB_UNSUPPORT; + /* Do nothing when current_conf == value */ + return usb_lld_ctrl_ack (dev); } -int usb_cb_interface (uint8_t cmd, struct req_args *arg) + +int +usb_set_interface (struct usb_dev *dev) { - const uint8_t zero = 0; - uint16_t interface = arg->index; - uint16_t alt = arg->value; + uint16_t interface = dev->dev_req.index; + uint16_t alt = dev->dev_req.value; if (interface >= NUM_INTERFACES) - return USB_UNSUPPORT; + return -1; - switch (cmd) + if (alt != 0) + return -1; + else { - case USB_SET_INTERFACE: - if (alt != 0) - return USB_UNSUPPORT; - else - { - gnuk_setup_endpoints_for_interface (interface, 0); - ccid_usb_reset (0); - return USB_SUCCESS; - } - - case USB_GET_INTERFACE: - return usb_lld_reply_request (&zero, 1, arg); - - case USB_QUERY_INTERFACE: - default: - return USB_SUCCESS; + gnuk_setup_endpoints_for_interface (interface, 0); + ccid_usb_reset (0); + return usb_lld_ctrl_ack (dev); } } + + +int +usb_get_interface (struct usb_dev *dev) +{ + const uint8_t zero = 0; + uint16_t interface = dev->dev_req.index; + + if (interface >= NUM_INTERFACES) + return -1; + + return usb_lld_ctrl_send (dev, &zero, 1); +} + +int +usb_get_status_interface (struct usb_dev *dev) +{ + const uint16_t status_info = 0; + uint16_t interface = dev->dev_req.index; + + if (interface >= NUM_INTERFACES) + return -1; + + return usb_lld_ctrl_send (dev, &status_info, 2); +} diff --git a/src/usb_desc.c b/src/usb_desc.c index 57636ad..a5a1594 100644 --- a/src/usb_desc.c +++ b/src/usb_desc.c @@ -345,21 +345,24 @@ static const struct desc string_descriptors[] = { #define USB_DT_REPORT 0x22 int -usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index, - struct req_args *arg) +usb_get_descriptor (struct usb_dev *dev) { + struct device_req *arg = &dev->dev_req; + uint8_t rcp = arg->type & RECIPIENT; + uint8_t desc_type = (arg->value >> 8); + uint8_t desc_index = (arg->value & 0xff); + if (rcp == DEVICE_RECIPIENT) { if (desc_type == DEVICE_DESCRIPTOR) - return usb_lld_reply_request (device_desc, sizeof (device_desc), arg); + return usb_lld_ctrl_send (dev, device_desc, sizeof (device_desc)); else if (desc_type == CONFIG_DESCRIPTOR) - return usb_lld_reply_request (config_desc, sizeof (config_desc), arg); + return usb_lld_ctrl_send (dev, config_desc, sizeof (config_desc)); else if (desc_type == STRING_DESCRIPTOR) { if (desc_index < NUM_STRING_DESC) - return usb_lld_reply_request (string_descriptors[desc_index].desc, - string_descriptors[desc_index].size, - arg); + return usb_lld_ctrl_send (dev, string_descriptors[desc_index].desc, + string_descriptors[desc_index].size); #ifdef USE_SYS3 else if (desc_index == NUM_STRING_DESC) { @@ -377,7 +380,7 @@ usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index, } usbbuf[0] = len = i*2 + 2; usbbuf[1] = STRING_DESCRIPTOR; - return usb_lld_reply_request (usbbuf, len, arg); + return usb_lld_ctrl_send (dev, usbbuf, len); } #endif } @@ -388,14 +391,13 @@ usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index, if (arg->index == HID_INTERFACE) { if (desc_type == USB_DT_HID) - return usb_lld_reply_request (config_desc+CCID_TOTAL_LENGTH+9, 9, - arg); + return usb_lld_ctrl_send (dev, config_desc+CCID_TOTAL_LENGTH+9, 9); else if (desc_type == USB_DT_REPORT) - return usb_lld_reply_request (hid_report_desc, HID_REPORT_DESC_SIZE, - arg); + return usb_lld_ctrl_send (dev, hid_report_desc, + HID_REPORT_DESC_SIZE); } } #endif - return USB_UNSUPPORT; + return -1; }