diff options
| author | sakumisu <[email protected]> | 2023-11-15 22:08:26 +0800 |
|---|---|---|
| committer | sakumisu <[email protected]> | 2023-11-16 19:56:52 +0800 |
| commit | 5bbe2a97f25ca780dde2bab0e9aafab46bac8913 (patch) | |
| tree | bece48da7a331c6fd7e1f95d0484d6bbe0fa102e /class | |
| parent | c1435548e7aab942dc2397718c692379803f26a1 (diff) | |
refactor urb, add ep & hport in urb to make hardware pipe more reusable
Diffstat (limited to 'class')
| -rw-r--r-- | class/audio/usbh_audio.c | 18 | ||||
| -rw-r--r-- | class/audio/usbh_audio.h | 4 | ||||
| -rw-r--r-- | class/cdc/usbd_cdc_ecm.c | 6 | ||||
| -rw-r--r-- | class/cdc/usbh_cdc_acm.c | 48 | ||||
| -rw-r--r-- | class/cdc/usbh_cdc_acm.h | 14 | ||||
| -rw-r--r-- | class/cdc/usbh_cdc_ecm.c | 54 | ||||
| -rw-r--r-- | class/cdc/usbh_cdc_ecm.h | 17 | ||||
| -rw-r--r-- | class/hid/usbh_hid.c | 16 | ||||
| -rw-r--r-- | class/hid/usbh_hid.h | 6 | ||||
| -rw-r--r-- | class/hub/usbh_hub.c | 79 | ||||
| -rw-r--r-- | class/msc/usbh_msc.c | 117 | ||||
| -rw-r--r-- | class/msc/usbh_msc.h | 12 | ||||
| -rw-r--r-- | class/video/usbh_video.c | 16 | ||||
| -rw-r--r-- | class/video/usbh_video.h | 4 | ||||
| -rw-r--r-- | class/wireless/usbd_rndis.c | 4 | ||||
| -rw-r--r-- | class/wireless/usbh_rndis.c | 225 | ||||
| -rw-r--r-- | class/wireless/usbh_rndis.h | 25 |
17 files changed, 418 insertions, 247 deletions
diff --git a/class/audio/usbh_audio.c b/class/audio/usbh_audio.c index a27cd456..eda75716 100644 --- a/class/audio/usbh_audio.c +++ b/class/audio/usbh_audio.c @@ -89,7 +89,7 @@ freq_found: setup->wIndex = intf; setup->wLength = 0; - ret = usbh_control_transfer(audio_class->hport->ep0, setup, NULL); + ret = usbh_control_transfer(audio_class->hport, setup, NULL); if (ret < 0) { return ret; } @@ -103,7 +103,7 @@ freq_found: setup->wLength = 3; memcpy(g_audio_buf, &samp_freq, 3); - ret = usbh_control_transfer(audio_class->hport->ep0, setup, g_audio_buf); + ret = usbh_control_transfer(audio_class->hport, setup, g_audio_buf); if (ret < 0) { return ret; } @@ -112,10 +112,10 @@ freq_found: mps = ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_MASK; if (ep_desc->bEndpointAddress & 0x80) { audio_class->isoin_mps = mps * (mult + 1); - usbh_hport_activate_epx(&audio_class->isoin, audio_class->hport, ep_desc); + USBH_EP_INIT(audio_class->isoin, ep_desc); } else { audio_class->isoout_mps = mps * (mult + 1); - usbh_hport_activate_epx(&audio_class->isoout, audio_class->hport, ep_desc); + USBH_EP_INIT(audio_class->isoout, ep_desc); } USB_LOG_INFO("Open audio module :%s, altsetting: %u\r\n", name, altsetting); @@ -147,12 +147,10 @@ int usbh_audio_close(struct usbh_audio *audio_class, const char *name) ep_desc = &audio_class->hport->config.intf[intf].altsetting[altsetting].ep[0].ep_desc; if (ep_desc->bEndpointAddress & 0x80) { if (audio_class->isoin) { - usbh_pipe_free(audio_class->isoin); audio_class->isoin = NULL; } } else { if (audio_class->isoout) { - usbh_pipe_free(audio_class->isoout); audio_class->isoout = NULL; } } @@ -163,7 +161,7 @@ int usbh_audio_close(struct usbh_audio *audio_class, const char *name) setup->wIndex = intf; setup->wLength = 0; - ret = usbh_control_transfer(audio_class->hport->ep0, setup, NULL); + ret = usbh_control_transfer(audio_class->hport, setup, NULL); return ret; } @@ -196,7 +194,7 @@ int usbh_audio_set_volume(struct usbh_audio *audio_class, const char *name, uint volume_hex = -0xDB00 / 100 * volume + 0xdb00; memcpy(g_audio_buf, &volume_hex, 2); - ret = usbh_control_transfer(audio_class->hport->ep0, setup, NULL); + ret = usbh_control_transfer(audio_class->hport, setup, NULL); return ret; } @@ -226,7 +224,7 @@ int usbh_audio_set_mute(struct usbh_audio *audio_class, const char *name, uint8_ setup->wLength = 1; memcpy(g_audio_buf, &mute, 1); - ret = usbh_control_transfer(audio_class->hport->ep0, setup, g_audio_buf); + ret = usbh_control_transfer(audio_class->hport, setup, g_audio_buf); return ret; } @@ -416,11 +414,9 @@ static int usbh_audio_ctrl_disconnect(struct usbh_hubport *hport, uint8_t intf) if (audio_class) { if (audio_class->isoin) { - usbh_pipe_free(audio_class->isoin); } if (audio_class->isoout) { - usbh_pipe_free(audio_class->isoout); } if (hport->config.intf[intf].devname[0] != '\0') { diff --git a/class/audio/usbh_audio.h b/class/audio/usbh_audio.h index dcfed604..f963dd0b 100644 --- a/class/audio/usbh_audio.h +++ b/class/audio/usbh_audio.h @@ -40,11 +40,11 @@ struct usbh_audio_module { struct usbh_audio { struct usbh_hubport *hport; + struct usb_endpoint_descriptor *isoin; /* ISO IN endpoint */ + struct usb_endpoint_descriptor *isoout; /* ISO OUT endpoint */ uint8_t ctrl_intf; /* interface number */ uint8_t minor; - usbh_pipe_t isoin; /* ISO IN endpoint */ - usbh_pipe_t isoout; /* ISO OUT endpoint */ uint16_t isoin_mps; uint16_t isoout_mps; bool is_opened; diff --git a/class/cdc/usbd_cdc_ecm.c b/class/cdc/usbd_cdc_ecm.c index 1ebdecf6..4a2dac00 100644 --- a/class/cdc/usbd_cdc_ecm.c +++ b/class/cdc/usbd_cdc_ecm.c @@ -19,9 +19,9 @@ static struct usbd_endpoint cdc_ecm_ep_data[3]; #define CDC_ECM_MAX_PACKET_SIZE 64 #endif -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_rx_buffer[CONFIG_CDC_ECM_ETH_MAX_SEGSZE]; -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_tx_buffer[CONFIG_CDC_ECM_ETH_MAX_SEGSZE]; -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_notify_buf[16]; +static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_rx_buffer[CONFIG_CDC_ECM_ETH_MAX_SEGSZE]; +static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_tx_buffer[CONFIG_CDC_ECM_ETH_MAX_SEGSZE]; +static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_notify_buf[16]; volatile uint8_t *g_cdc_ecm_rx_data_buffer = NULL; volatile uint32_t g_cdc_ecm_rx_data_length = 0; diff --git a/class/cdc/usbh_cdc_acm.c b/class/cdc/usbh_cdc_acm.c index a86c1298..faadd841 100644 --- a/class/cdc/usbh_cdc_acm.c +++ b/class/cdc/usbh_cdc_acm.c @@ -50,7 +50,7 @@ int usbh_cdc_acm_set_line_coding(struct usbh_cdc_acm *cdc_acm_class, struct cdc_ memcpy((uint8_t *)&g_cdc_line_coding, line_coding, sizeof(struct cdc_line_coding)); - return usbh_control_transfer(cdc_acm_class->hport->ep0, setup, (uint8_t *)&g_cdc_line_coding); + return usbh_control_transfer(cdc_acm_class->hport, setup, (uint8_t *)&g_cdc_line_coding); } int usbh_cdc_acm_get_line_coding(struct usbh_cdc_acm *cdc_acm_class, struct cdc_line_coding *line_coding) @@ -64,7 +64,7 @@ int usbh_cdc_acm_get_line_coding(struct usbh_cdc_acm *cdc_acm_class, struct cdc_ setup->wIndex = cdc_acm_class->ctrl_intf; setup->wLength = 7; - ret = usbh_control_transfer(cdc_acm_class->hport->ep0, setup, (uint8_t *)&g_cdc_line_coding); + ret = usbh_control_transfer(cdc_acm_class->hport, setup, (uint8_t *)&g_cdc_line_coding); if (ret < 0) { return ret; } @@ -85,7 +85,7 @@ int usbh_cdc_acm_set_line_state(struct usbh_cdc_acm *cdc_acm_class, bool dtr, bo cdc_acm_class->dtr = dtr; cdc_acm_class->rts = rts; - return usbh_control_transfer(cdc_acm_class->hport->ep0, setup, NULL); + return usbh_control_transfer(cdc_acm_class->hport, setup, NULL); } static int usbh_cdc_acm_connect(struct usbh_hubport *hport, uint8_t intf) @@ -124,15 +124,15 @@ static int usbh_cdc_acm_connect(struct usbh_hubport *hport, uint8_t intf) #ifdef CONFIG_USBHOST_CDC_ACM_NOTIFY ep_desc = &hport->config.intf[intf].altsetting[0].ep[0].ep_desc; - usbh_hport_activate_epx(&cdc_acm_class->intin, hport, ep_desc); + USBH_EP_INIT(cdc_acm_class->intin, ep_desc); #endif for (uint8_t i = 0; i < hport->config.intf[intf + 1].altsetting[0].intf_desc.bNumEndpoints; i++) { ep_desc = &hport->config.intf[intf + 1].altsetting[0].ep[i].ep_desc; if (ep_desc->bEndpointAddress & 0x80) { - usbh_hport_activate_epx(&cdc_acm_class->bulkin, hport, ep_desc); + USBH_EP_INIT(cdc_acm_class->bulkin, ep_desc); } else { - usbh_hport_activate_epx(&cdc_acm_class->bulkout, hport, ep_desc); + USBH_EP_INIT(cdc_acm_class->bulkout, ep_desc); } } @@ -152,13 +152,19 @@ static int usbh_cdc_acm_disconnect(struct usbh_hubport *hport, uint8_t intf) if (cdc_acm_class) { if (cdc_acm_class->bulkin) { - usbh_pipe_free(cdc_acm_class->bulkin); + usbh_kill_urb(&cdc_acm_class->bulkin_urb); } if (cdc_acm_class->bulkout) { - usbh_pipe_free(cdc_acm_class->bulkout); + usbh_kill_urb(&cdc_acm_class->bulkout_urb); } +#ifdef CONFIG_USBHOST_CDC_ACM_NOTIFY + if (cdc_acm_class->intin) { + usbh_kill_urb(&cdc_acm_class->intin_urb); + } +#endif + if (hport->config.intf[intf].devname[0] != '\0') { USB_LOG_INFO("Unregister CDC ACM Class:%s\r\n", hport->config.intf[intf].devname); usbh_cdc_acm_stop(cdc_acm_class); @@ -170,6 +176,32 @@ static int usbh_cdc_acm_disconnect(struct usbh_hubport *hport, uint8_t intf) return ret; } +int usbh_cdc_acm_bulk_in_transfer(struct usbh_cdc_acm *cdc_acm_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout) +{ + int ret; + struct usbh_urb *urb = &cdc_acm_class->bulkin_urb; + + usbh_bulk_urb_fill(urb, cdc_acm_class->hport, cdc_acm_class->bulkin, buffer, buflen, timeout, NULL, NULL); + ret = usbh_submit_urb(urb); + if (ret == 0) { + ret = urb->actual_length; + } + return ret; +} + +int usbh_cdc_acm_bulk_out_transfer(struct usbh_cdc_acm *cdc_acm_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout) +{ + int ret; + struct usbh_urb *urb = &cdc_acm_class->bulkout_urb; + + usbh_bulk_urb_fill(urb, cdc_acm_class->hport, cdc_acm_class->bulkout, buffer, buflen, timeout, NULL, NULL); + ret = usbh_submit_urb(urb); + if (ret == 0) { + ret = urb->actual_length; + } + return ret; +} + static int usbh_cdc_data_connect(struct usbh_hubport *hport, uint8_t intf) { return 0; diff --git a/class/cdc/usbh_cdc_acm.h b/class/cdc/usbh_cdc_acm.h index 3ffa64d0..f06b0ab3 100644 --- a/class/cdc/usbh_cdc_acm.h +++ b/class/cdc/usbh_cdc_acm.h @@ -10,6 +10,12 @@ struct usbh_cdc_acm { struct usbh_hubport *hport; + struct usb_endpoint_descriptor *bulkin; /* Bulk IN endpoint */ + struct usb_endpoint_descriptor *bulkout; /* Bulk OUT endpoint */ + struct usb_endpoint_descriptor *intin; /* INTR IN endpoint (optional) */ + struct usbh_urb bulkout_urb; + struct usbh_urb bulkin_urb; + struct usbh_urb intin_urb; struct cdc_line_coding linecoding; uint8_t ctrl_intf; /* Control interface number */ @@ -17,11 +23,6 @@ struct usbh_cdc_acm { bool dtr; bool rts; uint8_t minor; - usbh_pipe_t bulkin; /* Bulk IN endpoint */ - usbh_pipe_t bulkout; /* Bulk OUT endpoint */ -#ifdef CONFIG_USBHOST_CDC_ACM_NOTIFY - usbh_pipe_t intin; /* Interrupt IN endpoint (optional) */ -#endif }; #ifdef __cplusplus @@ -32,6 +33,9 @@ int usbh_cdc_acm_set_line_coding(struct usbh_cdc_acm *cdc_acm_class, struct cdc_ int usbh_cdc_acm_get_line_coding(struct usbh_cdc_acm *cdc_acm_class, struct cdc_line_coding *line_coding); int usbh_cdc_acm_set_line_state(struct usbh_cdc_acm *cdc_acm_class, bool dtr, bool rts); +int usbh_cdc_acm_bulk_in_transfer(struct usbh_cdc_acm *cdc_acm_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout); +int usbh_cdc_acm_bulk_out_transfer(struct usbh_cdc_acm *cdc_acm_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout); + void usbh_cdc_acm_run(struct usbh_cdc_acm *cdc_acm_class); void usbh_cdc_acm_stop(struct usbh_cdc_acm *cdc_acm_class); diff --git a/class/cdc/usbh_cdc_ecm.c b/class/cdc/usbh_cdc_ecm.c index d4546927..6ca59a38 100644 --- a/class/cdc/usbh_cdc_ecm.c +++ b/class/cdc/usbh_cdc_ecm.c @@ -20,9 +20,9 @@ #define CONFIG_USBHOST_CDC_ECM_PKT_FILTER 0x000C #define CONFIG_USBHOST_CDC_ECM_ETH_MAX_SEGSZE 1514U -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_rx_buffer[CONFIG_USBHOST_CDC_ECM_ETH_MAX_SEGSZE]; -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_tx_buffer[CONFIG_USBHOST_CDC_ECM_ETH_MAX_SEGSZE]; -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_inttx_buffer[16]; +static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_rx_buffer[CONFIG_USBHOST_CDC_ECM_ETH_MAX_SEGSZE]; +static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_tx_buffer[CONFIG_USBHOST_CDC_ECM_ETH_MAX_SEGSZE]; +static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_inttx_buffer[16]; static struct usbh_cdc_ecm g_cdc_ecm_class; @@ -36,21 +36,25 @@ static int usbh_cdc_ecm_set_eth_packet_filter(struct usbh_cdc_ecm *cdc_ecm_class setup->wIndex = cdc_ecm_class->ctrl_intf; setup->wLength = 0; - return usbh_control_transfer(cdc_ecm_class->hport->ep0, setup, NULL); + return usbh_control_transfer(cdc_ecm_class->hport, setup, NULL); } int usbh_cdc_ecm_get_notification(struct usbh_cdc_ecm *cdc_ecm_class) { int ret; - usbh_int_urb_fill(&cdc_ecm_class->intin_urb, cdc_ecm_class->intin, g_cdc_ecm_inttx_buffer, 16, USB_OSAL_WAITING_FOREVER, NULL, NULL); + usbh_int_urb_fill(&cdc_ecm_class->intin_urb, cdc_ecm_class->hport, cdc_ecm_class->intin, g_cdc_ecm_inttx_buffer, 16, USB_OSAL_WAITING_FOREVER, NULL, NULL); ret = usbh_submit_urb(&cdc_ecm_class->intin_urb); if (ret < 0) { return ret; } if (g_cdc_ecm_inttx_buffer[1] == CDC_ECM_NOTIFY_CODE_NETWORK_CONNECTION) { - cdc_ecm_class->connect_status = g_cdc_ecm_inttx_buffer[2]; + if (g_cdc_ecm_inttx_buffer[2] == CDC_ECM_NET_CONNECTED) { + cdc_ecm_class->connect_status = true; + } else { + cdc_ecm_class->connect_status = false; + } } else if (g_cdc_ecm_inttx_buffer[1] == CDC_ECM_NOTIFY_CODE_CONNECTION_SPEED_CHANGE) { memcpy(cdc_ecm_class->speed, &g_cdc_ecm_inttx_buffer[8], 8); } @@ -69,6 +73,8 @@ static int usbh_cdc_ecm_connect(struct usbh_hubport *hport, uint8_t intf) struct usbh_cdc_ecm *cdc_ecm_class = &g_cdc_ecm_class; + memset(cdc_ecm_class, 0, sizeof(struct usbh_cdc_ecm)); + cdc_ecm_class->hport = hport; cdc_ecm_class->ctrl_intf = intf; cdc_ecm_class->data_intf = intf + 1; @@ -105,7 +111,7 @@ get_mac: return -1; } - memset(mac_buffer, 0, 8); + memset(mac_buffer, 0, 12); ret = usbh_get_string_desc(cdc_ecm_class->hport, mac_str_idx, (uint8_t *)mac_buffer); if (ret < 0) { return ret; @@ -137,7 +143,7 @@ get_mac: /* enable int ep */ ep_desc = &hport->config.intf[intf].altsetting[0].ep[0].ep_desc; - usbh_hport_activate_epx(&cdc_ecm_class->intin, hport, ep_desc); + USBH_EP_INIT(cdc_ecm_class->intin, ep_desc); if (hport->config.intf[intf + 1].altsetting_num > 1) { altsetting = hport->config.intf[intf + 1].altsetting_num - 1; @@ -146,9 +152,9 @@ get_mac: ep_desc = &hport->config.intf[intf + 1].altsetting[altsetting].ep[i].ep_desc; if (ep_desc->bEndpointAddress & 0x80) { - usbh_hport_activate_epx(&cdc_ecm_class->bulkin, hport, ep_desc); + USBH_EP_INIT(cdc_ecm_class->bulkin, ep_desc); } else { - usbh_hport_activate_epx(&cdc_ecm_class->bulkout, hport, ep_desc); + USBH_EP_INIT(cdc_ecm_class->bulkout, ep_desc); } } @@ -159,9 +165,9 @@ get_mac: ep_desc = &hport->config.intf[intf + 1].altsetting[0].ep[i].ep_desc; if (ep_desc->bEndpointAddress & 0x80) { - usbh_hport_activate_epx(&cdc_ecm_class->bulkin, hport, ep_desc); + USBH_EP_INIT(cdc_ecm_class->bulkin, ep_desc); } else { - usbh_hport_activate_epx(&cdc_ecm_class->bulkout, hport, ep_desc); + USBH_EP_INIT(cdc_ecm_class->bulkout, ep_desc); } } } @@ -194,15 +200,15 @@ static int usbh_cdc_ecm_disconnect(struct usbh_hubport *hport, uint8_t intf) if (cdc_ecm_class) { if (cdc_ecm_class->bulkin) { - usbh_pipe_free(cdc_ecm_class->bulkin); + usbh_kill_urb(&cdc_ecm_class->bulkin_urb); } if (cdc_ecm_class->bulkout) { - usbh_pipe_free(cdc_ecm_class->bulkout); + usbh_kill_urb(&cdc_ecm_class->bulkout_urb); } if (cdc_ecm_class->intin) { - usbh_pipe_free(cdc_ecm_class->intin); + usbh_kill_urb(&cdc_ecm_class->intin_urb); } if (hport->config.intf[intf].devname[0] != '\0') { @@ -223,30 +229,25 @@ static void usbh_cdc_ecm_rx_thread(void *argument) err_t err; struct pbuf *p; struct netif *netif = (struct netif *)argument; - uint16_t ep_mps; // clang-format off find_class: // clang-format on + g_cdc_ecm_class.connect_status = false; while (usbh_find_class_instance("/dev/cdc_ether") == NULL) { usb_osal_msleep(1000); } - while (g_cdc_ecm_class.connect_status == CDC_ECM_NET_DISCONNECTED) { + while (g_cdc_ecm_class.connect_status == false) { ret = usbh_cdc_ecm_get_notification(&g_cdc_ecm_class); if (ret < 0) { goto find_class; } } - if (g_cdc_ecm_class.hport->speed == USB_SPEED_FULL) { - ep_mps = 64; - } else { - ep_mps = 512; - } g_cdc_ecm_rx_length = 0; while (1) { - usbh_bulk_urb_fill(&g_cdc_ecm_class.bulkin_urb, g_cdc_ecm_class.bulkin, &g_cdc_ecm_rx_buffer[g_cdc_ecm_rx_length], ep_mps, USB_OSAL_WAITING_FOREVER, NULL, NULL); + usbh_bulk_urb_fill(&g_cdc_ecm_class.bulkin_urb, g_cdc_ecm_class.hport, g_cdc_ecm_class.bulkin, &g_cdc_ecm_rx_buffer[g_cdc_ecm_rx_length], USB_GET_MAXPACKETSIZE(g_cdc_ecm_class.bulkin->wMaxPacketSize), USB_OSAL_WAITING_FOREVER, NULL, NULL); ret = usbh_submit_urb(&g_cdc_ecm_class.bulkin_urb); if (ret < 0) { goto find_class; @@ -254,13 +255,14 @@ find_class: g_cdc_ecm_rx_length += g_cdc_ecm_class.bulkin_urb.actual_length; - if (g_cdc_ecm_rx_length % ep_mps) { + if (g_cdc_ecm_rx_length % USB_GET_MAXPACKETSIZE(g_cdc_ecm_class.bulkin->wMaxPacketSize)) { USB_LOG_DBG("rxlen:%d\r\n", g_cdc_ecm_rx_length); p = pbuf_alloc(PBUF_RAW, g_cdc_ecm_rx_length, PBUF_POOL); if (p != NULL) { memcpy(p->payload, (uint8_t *)g_cdc_ecm_rx_buffer, g_cdc_ecm_rx_length); g_cdc_ecm_rx_length = 0; + err = netif->input(p, netif); if (err != ERR_OK) { pbuf_free(p); @@ -280,7 +282,7 @@ err_t usbh_cdc_ecm_linkoutput(struct netif *netif, struct pbuf *p) struct pbuf *q; uint8_t *buffer = g_cdc_ecm_tx_buffer; - if (g_cdc_ecm_class.connect_status == CDC_ECM_NET_DISCONNECTED) { + if (g_cdc_ecm_class.connect_status == false) { return ERR_BUF; } @@ -291,7 +293,7 @@ err_t usbh_cdc_ecm_linkoutput(struct netif *netif, struct pbuf *p) USB_LOG_DBG("txlen:%d\r\n", p->tot_len); - usbh_bulk_urb_fill(&g_cdc_ecm_class.bulkout_urb, g_cdc_ecm_class.bulkout, g_cdc_ecm_tx_buffer, p->tot_len, USB_OSAL_WAITING_FOREVER, NULL, NULL); + usbh_bulk_urb_fill(&g_cdc_ecm_class.bulkout_urb, g_cdc_ecm_class.hport, g_cdc_ecm_class.bulkout, g_cdc_ecm_tx_buffer, p->tot_len, USB_OSAL_WAITING_FOREVER, NULL, NULL); ret = usbh_submit_urb(&g_cdc_ecm_class.bulkout_urb); if (ret < 0) { return ERR_BUF; diff --git a/class/cdc/usbh_cdc_ecm.h b/class/cdc/usbh_cdc_ecm.h index 7e0e96c3..7d65da0b 100644 --- a/class/cdc/usbh_cdc_ecm.h +++ b/class/cdc/usbh_cdc_ecm.h @@ -13,20 +13,21 @@ struct usbh_cdc_ecm { struct usbh_hubport *hport; + struct usb_endpoint_descriptor *bulkin; /* Bulk IN endpoint */ + struct usb_endpoint_descriptor *bulkout; /* Bulk OUT endpoint */ + struct usb_endpoint_descriptor *intin; /* Interrupt IN endpoint */ + struct usbh_urb bulkout_urb; /* Bulk out endpoint */ + struct usbh_urb bulkin_urb; /* Bulk IN endpoint */ + struct usbh_urb intin_urb; /* Interrupt IN endpoint */ uint8_t ctrl_intf; /* Control interface number */ uint8_t data_intf; /* Data interface number */ uint8_t minor; + uint8_t mac[6]; - uint32_t max_segment_size; - uint8_t connect_status; + bool connect_status; + uint16_t max_segment_size; uint32_t speed[2]; - usbh_pipe_t bulkin; /* Bulk IN endpoint */ - usbh_pipe_t bulkout; /* Bulk OUT endpoint */ - usbh_pipe_t intin; /* Interrupt IN endpoint */ - struct usbh_urb bulkout_urb; - struct usbh_urb bulkin_urb; - struct usbh_urb intin_urb; ip_addr_t ipaddr; ip_addr_t netmask; diff --git a/class/hid/usbh_hid.c b/class/hid/usbh_hid.c index 8152af5f..b64ecab5 100644 --- a/class/hid/usbh_hid.c +++ b/class/hid/usbh_hid.c @@ -49,7 +49,7 @@ static int usbh_hid_get_report_descriptor(struct usbh_hid *hid_class, uint8_t *b setup->wIndex = hid_class->intf; setup->wLength = 128; - ret = usbh_control_transfer(hid_class->hport->ep0, setup, g_hid_buf); + ret = usbh_control_transfer(hid_class->hport, setup, g_hid_buf); if (ret < 0) { return ret; } @@ -67,7 +67,7 @@ int usbh_hid_set_idle(struct usbh_hid *hid_class, uint8_t report_id, uint8_t dur setup->wIndex = hid_class->intf; setup->wLength = 0; - return usbh_control_transfer(hid_class->hport->ep0, setup, NULL); + return usbh_control_transfer(hid_class->hport, setup, NULL); } int usbh_hid_get_idle(struct usbh_hid *hid_class, uint8_t *buffer) @@ -81,7 +81,7 @@ int usbh_hid_get_idle(struct usbh_hid *hid_class, uint8_t *buffer) setup->wIndex = hid_class->intf; setup->wLength = 1; - ret = usbh_control_transfer(hid_class->hport->ep0, setup, g_hid_buf); + ret = usbh_control_transfer(hid_class->hport, setup, g_hid_buf); if (ret < 0) { return ret; } @@ -99,7 +99,7 @@ int usbh_hid_set_protocol(struct usbh_hid *hid_class, uint8_t protocol) setup->wIndex = 0; setup->wLength = 0; - return usbh_control_transfer(hid_class->hport->ep0, setup, NULL); + return usbh_control_transfer(hid_class->hport, setup, NULL); } int usbh_hid_connect(struct usbh_hubport *hport, uint8_t intf) @@ -137,9 +137,9 @@ int usbh_hid_connect(struct usbh_hubport *hport, uint8_t intf) for (uint8_t i = 0; i < hport->config.intf[intf].altsetting[0].intf_desc.bNumEndpoints; i++) { ep_desc = &hport->config.intf[intf].altsetting[0].ep[i].ep_desc; if (ep_desc->bEndpointAddress & 0x80) { - usbh_hport_activate_epx(&hid_class->intin, hport, ep_desc); + USBH_EP_INIT(hid_class->intin, ep_desc); } else { - usbh_hport_activate_epx(&hid_class->intout, hport, ep_desc); + USBH_EP_INIT(hid_class->intout, ep_desc); } } @@ -159,11 +159,11 @@ int usbh_hid_disconnect(struct usbh_hubport *hport, uint8_t intf) if (hid_class) { if (hid_class->intin) { - usbh_pipe_free(hid_class->intin); + usbh_kill_urb(&hid_class->intin_urb); } if (hid_class->intout) { - usbh_pipe_free(hid_class->intout); + usbh_kill_urb(&hid_class->intout_urb); } if (hport->config.intf[intf].devname[0] != '\0') { diff --git a/class/hid/usbh_hid.h b/class/hid/usbh_hid.h index 9faf2023..72571dd2 100644 --- a/class/hid/usbh_hid.h +++ b/class/hid/usbh_hid.h @@ -10,12 +10,14 @@ struct usbh_hid { struct usbh_hubport *hport; + struct usb_endpoint_descriptor *intin; /* INTR IN endpoint */ + struct usb_endpoint_descriptor *intout; /* INTR OUT endpoint */ + struct usbh_urb intin_urb; /* INTR IN urb */ + struct usbh_urb intout_urb; /* INTR OUT urb */ uint8_t report_desc[128]; uint8_t intf; /* interface number */ uint8_t minor; - usbh_pipe_t intin; /* INTR IN endpoint */ - usbh_pipe_t intout; /* INTR OUT endpoint */ }; #ifdef __cplusplus diff --git a/class/hub/usbh_hub.c b/class/hub/usbh_hub.c index 930a9ffd..6c8020dd 100644 --- a/class/hub/usbh_hub.c +++ b/class/hub/usbh_hub.c @@ -5,14 +5,14 @@ */ #include "usbh_hub.h" -#define DEV_FORMAT "/dev/hub%d" +#define DEV_FORMAT "/dev/hub%d" #define HUB_DEBOUNCE_TIMEOUT 1500 #define HUB_DEBOUNCE_STEP 25 #define HUB_DEBOUNCE_STABLE 100 #define DELAY_TIME_AFTER_RESET 200 -#define EXTHUB_FIRST_INDEX 2 +#define EXTHUB_FIRST_INDEX 2 USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hub_buf[32]; USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hub_intbuf[CONFIG_USBHOST_MAX_EXTHUBS + 1][CONFIG_USB_ALIGN_SIZE]; @@ -24,10 +24,8 @@ usb_osal_mq_t hub_mq; struct usbh_hub roothub; -extern int usbh_hport_activate_ep0(struct usbh_hubport *hport); -extern int usbh_hport_deactivate_ep0(struct usbh_hubport *hport); +extern int usbh_free_devaddr(struct usbh_hubport *hport); extern int usbh_enumerate(struct usbh_hubport *hport); -static void usbh_hub_thread_wakeup(struct usbh_hub *hub); static const char *speed_table[] = { "error-speed", "low-speed", "full-speed", "high-speed", "wireless-speed", "super-speed", "superplus-speed" }; @@ -101,7 +99,7 @@ static int _usbh_hub_get_hub_descriptor(struct usbh_hub *hub, uint8_t *buffer) setup->wIndex = 0; setup->wLength = USB_SIZEOF_HUB_DESC; - ret = usbh_control_transfer(hub->parent->ep0, setup, g_hub_buf); + ret = usbh_control_transfer(hub->parent, setup, g_hub_buf); if (ret < 0) { return ret; } @@ -122,7 +120,7 @@ static int _usbh_hub_get_status(struct usbh_hub *hub, uint8_t *buffer) setup->wIndex = 0; setup->wLength = 2; - ret = usbh_control_transfer(hub->parent->ep0, setup, g_hub_buf); + ret = usbh_control_transfer(hub->parent, setup, g_hub_buf); if (ret < 0) { return ret; } @@ -145,7 +143,7 @@ static int _usbh_hub_get_portstatus(struct usbh_hub *hub, uint8_t port, struct h setup->wIndex = port; setup->wLength = 4; - ret = usbh_control_transfer(hub->parent->ep0, setup, g_hub_buf); + ret = usbh_control_transfer(hub->parent, setup, g_hub_buf); if (ret < 0) { return ret; } @@ -165,7 +163,7 @@ static int _usbh_hub_set_feature(struct usbh_hub *hub, uint8_t port, uint8_t fea setup->wIndex = port; setup->wLength = 0; - return usbh_control_transfer(hub->parent->ep0, setup, NULL); + return usbh_control_transfer(hub->parent, setup, NULL); } static int _usbh_hub_clear_feature(struct usbh_hub *hub, uint8_t port, uint8_t feature) @@ -180,7 +178,7 @@ static int _usbh_hub_clear_feature(struct usbh_hub *hub, uint8_t port, uint8_t f setup->wIndex = port; setup->wLength = 0; - return usbh_control_transfer(hub->parent->ep0, setup, NULL); + return usbh_control_transfer(hub->parent, setup, NULL); } static int _usbh_hub_set_depth(struct usbh_hub *hub, uint16_t depth) @@ -195,7 +193,7 @@ static int _usbh_hub_set_depth(struct usbh_hub *hub, uint16_t depth) setup->wIndex = 0; setup->wLength = 0; - return usbh_control_transfer(hub->parent->ep0, setup, NULL); + return usbh_control_transfer(hub->parent, setup, NULL); } #if CONFIG_USBHOST_MAX_EXTHUBS > 0 @@ -294,13 +292,31 @@ static int usbh_hub_set_depth(struct usbh_hub *hub, uint16_t depth) } } +static void usbh_hub_thread_wakeup(struct usbh_hub *hub) +{ + usb_osal_mq_send(hub_mq, (uintptr_t)hub); +} + +static void usbh_hubport_release(struct usbh_hubport *child) +{ + if (child->connected) { + child->connected = false; + usbh_free_devaddr(child); + for (uint8_t i = 0; i < child->config.config_desc.bNumInterfaces; i++) { + if (child->config.intf[i].class_driver && child->config.intf[i].class_driver->disconnect) { + CLASS_DISCONNECT(child, i); + } + } + child->config.config_desc.bNumInterfaces = 0; + } +} + #if CONFIG_USBHOST_MAX_EXTHUBS > 0 static void hub_int_complete_callback(void *arg, int nbytes) { struct usbh_hub *hub = (struct usbh_hub *)arg; - if (nbytes > 0) - { + if (nbytes > 0) { usbh_hub_thread_wakeup(hub); } } @@ -336,7 +352,7 @@ static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf) ep_desc = &hport->config.intf[intf].altsetting[0].ep[0].ep_desc; if (ep_desc->bEndpointAddress & 0x80) { - usbh_hport_activate_epx(&hub->intin, hport, ep_desc); + USBH_EP_INIT(hub->intin, ep_desc); } else { return -1; } @@ -376,7 +392,7 @@ static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf) USB_LOG_INFO("Register HUB Class:%s\r\n", hport->config.intf[intf].devname); hub->int_buffer = g_hub_intbuf[hub->index - 1]; - usbh_int_urb_fill(&hub->intin_urb, hub->intin, hub->int_buffer, 1, 0, hub_int_complete_callback, hub); + usbh_int_urb_fill(&hub->intin_urb, hub->parent, hub->intin, hub->int_buffer, 1, 0, hub_int_complete_callback, hub); usbh_submit_urb(&hub->intin_urb); return 0; } @@ -390,19 +406,12 @@ static int usbh_hub_disconnect(struct usbh_hubport *hport, uint8_t intf) if (hub) { if (hub->intin) { - usbh_pipe_free(hub->intin); + usbh_kill_urb(&hub->intin_urb); } for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) { child = &hub->child[port]; - usbh_hport_deactivate_ep0(child); - for (uint8_t i = 0; i < child->config.config_desc.bNumInterfaces; i++) { - if (child->config.intf[i].class_driver && child->config.intf[i].class_driver->disconnect) { - CLASS_DISCONNECT(child, i); - } - } - - child->config.config_desc.bNumInterfaces = 0; + usbh_hubport_release(child); child->parent = NULL; } @@ -417,27 +426,10 @@ static int usbh_hub_disconnect(struct usbh_hubport *hport, uint8_t intf) } #endif -static void usbh_hubport_release(struct usbh_hubport *child) -{ - if (child->connected) { - child->connected = false; - usbh_hport_deactivate_ep0(child); - for (uint8_t i = 0; i < child->config.config_desc.bNumInterfaces; i++) { - if (child->config.intf[i].class_driver && child->config.intf[i].class_driver->disconnect) { - CLASS_DISCONNECT(child, i); - } - } - child->config.config_desc.bNumInterfaces = 0; - } -} - static void usbh_hubport_enumerate_thread(void *argument) { struct usbh_hubport *child = (struct usbh_hubport *)argument; - /* Configure EP0 with the default maximum packet size */ - usbh_hport_activate_ep0(child); - if (usbh_enumerate(child) < 0) { /** release child sources */ usbh_hubport_release(child); @@ -662,11 +654,6 @@ static void usbh_roothub_register(void) usbh_hub_register(&roothub); } -static void usbh_hub_thread_wakeup(struct usbh_hub *hub) -{ - usb_osal_mq_send(hub_mq, (uintptr_t)hub); -} - void usbh_roothub_thread_wakeup(uint8_t port) { roothub.int_buffer = g_hub_intbuf[roothub.index - 1]; diff --git a/class/msc/usbh_msc.c b/class/msc/usbh_msc.c index d492be29..3ac62377 100644 --- a/class/msc/usbh_msc.c +++ b/class/msc/usbh_msc.c @@ -50,7 +50,7 @@ static int usbh_msc_get_maxlun(struct usbh_msc *msc_class, uint8_t *buffer) setup->wIndex = msc_class->intf; setup->wLength = 1; - return usbh_control_transfer(msc_class->hport->ep0, setup, buffer); + return usbh_control_transfer(msc_class->hport, setup, buffer); } static void usbh_msc_cbw_dump(struct CBW *cbw) @@ -87,9 +87,8 @@ static inline int usbh_msc_bulk_in_transfer(struct usbh_msc *msc_class, uint8_t { int ret; struct usbh_urb *urb = &msc_class->bulkin_urb; - memset(urb, 0, sizeof(struct usbh_urb)); - usbh_bulk_urb_fill(urb, msc_class->bulkin, buffer, buflen, timeout, NULL, NULL); + usbh_bulk_urb_fill(urb, msc_class->hport, msc_class->bulkin, buffer, buflen, timeout, NULL, NULL); ret = usbh_submit_urb(urb); if (ret == 0) { ret = urb->actual_length; @@ -101,9 +100,8 @@ static inline int usbh_msc_bulk_out_transfer(struct usbh_msc *msc_class, uint8_t { int ret; struct usbh_urb *urb = &msc_class->bulkout_urb; - memset(urb, 0, sizeof(struct usbh_urb)); - usbh_bulk_urb_fill(urb, msc_class->bulkout, buffer, buflen, timeout, NULL, NULL); + usbh_bulk_urb_fill(urb, msc_class->hport, msc_class->bulkout, buffer, buflen, timeout, NULL, NULL); ret = usbh_submit_urb(urb); if (ret == 0) { ret = urb->actual_length; @@ -111,7 +109,7 @@ static inline int usbh_msc_bulk_out_transfer(struct usbh_msc *msc_class, uint8_t return ret; } -int usbh_bulk_cbw_csw_xfer(struct usbh_msc *msc_class, struct CBW *cbw, struct CSW *csw, uint8_t *buffer) +static int usbh_bulk_cbw_csw_xfer(struct usbh_msc *msc_class, struct CBW *cbw, struct CSW *csw, uint8_t *buffer) { int nbytes; @@ -236,55 +234,7 @@ static inline int usbh_msc_scsi_readcapacity10(struct usbh_msc *msc_class) return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf, g_msc_buf); } -int usbh_msc_scsi_write10(struct usbh_msc *msc_class, uint32_t start_sector, const uint8_t *buffer, uint32_t nsectors) -{ - struct CBW *cbw; - - /* Construct the CBW */ - cbw = (struct CBW *)g_msc_buf; - memset(cbw, 0, USB_SIZEOF_MSC_CBW); - cbw->dSignature = MSC_CBW_Signature; - - cbw->dDataLength = (msc_class->blocksize * nsectors); - cbw->bCBLength = SCSICMD_WRITE10_SIZEOF; - cbw->CB[0] = SCSI_CMD_WRITE10; - - SET_BE32(&cbw->CB[2], start_sector); - SET_BE16(&cbw->CB[7], nsectors); - - return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf, (uint8_t *)buffer); -} - -int usbh_msc_scsi_read10(struct usbh_msc *msc_class, uint32_t start_sector, const uint8_t *buffer, uint32_t nsectors) -{ - struct CBW *cbw; - - /* Construct the CBW */ - cbw = (struct CBW *)g_msc_buf; - memset(cbw, 0, USB_SIZEOF_MSC_CBW); - cbw->dSignature = MSC_CBW_Signature; - - cbw->dDataLength = (msc_class->blocksize * nsectors); - cbw->bmFlags = 0x80; - cbw->bCBLength = SCSICMD_READ10_SIZEOF; - cbw->CB[0] = SCSI_CMD_READ10; - - SET_BE32(&cbw->CB[2], start_sector); - SET_BE16(&cbw->CB[7], nsectors); - - return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf, (uint8_t *)buffer); -} - -void usbh_msc_modeswitch_enable(struct usbh_msc_modeswitch_config *config) -{ - if (config) { - g_msc_modeswitch_config = config; - } else { - g_msc_modeswitch_config = NULL; - } -} - -void usbh_msc_modeswitch(struct usbh_msc *msc_class, const uint8_t *message) +static inline void usbh_msc_modeswitch(struct usbh_msc *msc_class, const uint8_t *message) { struct CBW *cbw; @@ -323,9 +273,9 @@ static int usbh_msc_connect(struct usbh_hubport *hport, uint8_t intf) for (uint8_t i = 0; i < hport->config.intf[intf].altsetting[0].intf_desc.bNumEndpoints; i++) { ep_desc = &hport->config.intf[intf].altsetting[0].ep[i].ep_desc; if (ep_desc->bEndpointAddress & 0x80) { - usbh_hport_activate_epx(&msc_class->bulkin, hport, ep_desc); + USBH_EP_INIT(msc_class->bulkin, ep_desc); } else { - usbh_hport_activate_epx(&msc_class->bulkout, hport, ep_desc); + USBH_EP_INIT(msc_class->bulkout, ep_desc); } } @@ -390,11 +340,11 @@ static int usbh_msc_disconnect(struct usbh_hubport *hport, uint8_t intf) if (msc_class) { if (msc_class->bulkin) { - usbh_pipe_free(msc_class->bulkin); + usbh_kill_urb(&msc_class->bulkin_urb); } if (msc_class->bulkout) { - usbh_pipe_free(msc_class->bulkout); + usbh_kill_urb(&msc_class->bulkout_urb); } if (hport->config.intf[intf].devname[0] != '\0') { @@ -408,6 +358,55 @@ static int usbh_msc_disconnect(struct usbh_hubport *hport, uint8_t intf) return ret; } + +int usbh_msc_scsi_write10(struct usbh_msc *msc_class, uint32_t start_sector, const uint8_t *buffer, uint32_t nsectors) +{ + struct CBW *cbw; + + /* Construct the CBW */ + cbw = (struct CBW *)g_msc_buf; + memset(cbw, 0, USB_SIZEOF_MSC_CBW); + cbw->dSignature = MSC_CBW_Signature; + + cbw->dDataLength = (msc_class->blocksize * nsectors); + cbw->bCBLength = SCSICMD_WRITE10_SIZEOF; + cbw->CB[0] = SCSI_CMD_WRITE10; + + SET_BE32(&cbw->CB[2], start_sector); + SET_BE16(&cbw->CB[7], nsectors); + + return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf, (uint8_t *)buffer); +} + +int usbh_msc_scsi_read10(struct usbh_msc *msc_class, uint32_t start_sector, const uint8_t *buffer, uint32_t nsectors) +{ + struct CBW *cbw; + + /* Construct the CBW */ + cbw = (struct CBW *)g_msc_buf; + memset(cbw, 0, USB_SIZEOF_MSC_CBW); + cbw->dSignature = MSC_CBW_Signature; + + cbw->dDataLength = (msc_class->blocksize * nsectors); + cbw->bmFlags = 0x80; + cbw->bCBLength = SCSICMD_READ10_SIZEOF; + cbw->CB[0] = SCSI_CMD_READ10; + + SET_BE32(&cbw->CB[2], start_sector); + SET_BE16(&cbw->CB[7], nsectors); + + return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf, (uint8_t *)buffer); +} + +void usbh_msc_modeswitch_enable(struct usbh_msc_modeswitch_config *config) +{ + if (config) { + g_msc_modeswitch_config = config; + } else { + g_msc_modeswitch_config = NULL; + } +} + __WEAK void usbh_msc_run(struct usbh_msc *msc_class) { } diff --git a/class/msc/usbh_msc.h b/class/msc/usbh_msc.h index 04cc9ceb..93c99f1a 100644 --- a/class/msc/usbh_msc.h +++ b/class/msc/usbh_msc.h @@ -11,15 +11,15 @@ struct usbh_msc { struct usbh_hubport *hport; + struct usb_endpoint_descriptor *bulkin; /* Bulk IN endpoint */ + struct usb_endpoint_descriptor *bulkout; /* Bulk OUT endpoint */ + struct usbh_urb bulkin_urb; /* Bulk IN urb */ + struct usbh_urb bulkout_urb; /* Bulk OUT urb */ uint8_t intf; /* Data interface number */ uint8_t sdchar; - usbh_pipe_t bulkin; /* Bulk IN endpoint */ - usbh_pipe_t bulkout; /* Bulk OUT endpoint */ - struct usbh_urb bulkin_urb; /* Bulk IN urb */ - struct usbh_urb bulkout_urb; /* Bulk OUT urb */ - uint32_t blocknum; /* Number of blocks on the USB mass storage device */ - uint16_t blocksize; /* Block size of USB mass storage device */ + uint32_t blocknum; /* Number of blocks on the USB mass storage device */ + uint16_t blocksize; /* Block size of USB mass storage device */ }; struct usbh_msc_modeswitch_config { diff --git a/class/video/usbh_video.c b/class/video/usbh_video.c index 8521d26c..d3404c0d 100644 --- a/class/video/usbh_video.c +++ b/class/video/usbh_video.c @@ -67,7 +67,7 @@ int usbh_video_get(struct usbh_video *video_class, uint8_t request, uint8_t intf retry = 0; while (1) { - ret = usbh_control_transfer(video_class->hport->ep0, setup, g_video_buf); + ret = usbh_control_transfer(video_class->hport, setup, g_video_buf); if (ret > 0) { break; } @@ -98,7 +98,7 @@ int usbh_video_set(struct usbh_video *video_class, uint8_t request, uint8_t intf memcpy(g_video_buf, buf, len); - ret = usbh_control_transfer(video_class->hport->ep0, setup, g_video_buf); + ret = usbh_control_transfer(video_class->hport, setup, g_video_buf); usb_osal_msleep(50); return ret; } @@ -233,7 +233,7 @@ int usbh_video_open(struct usbh_video *video_class, setup->wIndex = video_class->data_intf; setup->wLength = 0; - ret = usbh_control_transfer(video_class->hport->ep0, setup, NULL); + ret = usbh_control_transfer(video_class->hport, setup, NULL); if (ret < 0) { goto errout; } @@ -243,10 +243,10 @@ int usbh_video_open(struct usbh_video *video_class, mps = ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_MASK; if (ep_desc->bEndpointAddress & 0x80) { video_class->isoin_mps = mps * (mult + 1); - usbh_hport_activate_epx(&video_class->isoin, video_class->hport, ep_desc); + USBH_EP_INIT(video_class->isoin, ep_desc); } else { video_class->isoout_mps = mps * (mult + 1); - usbh_hport_activate_epx(&video_class->isoout, video_class->hport, ep_desc); + USBH_EP_INIT(video_class->isoout, ep_desc); } USB_LOG_INFO("Open video and select formatidx:%u, frameidx:%u, altsetting:%u\r\n", formatidx, frameidx, altsetting); @@ -269,12 +269,10 @@ int usbh_video_close(struct usbh_video *video_class) video_class->is_opened = false; if (video_class->isoin) { - usbh_pipe_free(video_class->isoin); video_class->isoin = NULL; } if (video_class->isoout) { - usbh_pipe_free(video_class->isoout); video_class->isoout = NULL; } @@ -284,7 +282,7 @@ int usbh_video_close(struct usbh_video *video_class) setup->wIndex = video_class->data_intf; setup->wLength = 0; - ret = usbh_control_transfer(video_class->hport->ep0, setup, NULL); + ret = usbh_control_transfer(video_class->hport, setup, NULL); if (ret < 0) { return ret; } @@ -455,11 +453,9 @@ static int usbh_video_ctrl_disconnect(struct usbh_hubport *hport, uint8_t intf) if (video_class) { if (video_class->isoin) { - usbh_pipe_free(video_class->isoin); } if (video_class->isoout) { - usbh_pipe_free(video_class->isoout); } if (hport->config.intf[intf].devname[0] != '\0') { diff --git a/class/video/usbh_video.h b/class/video/usbh_video.h index 3357c14c..f4e06d78 100644 --- a/class/video/usbh_video.h +++ b/class/video/usbh_video.h @@ -32,12 +32,12 @@ struct usbh_videostreaming { struct usbh_video { struct usbh_hubport *hport; + struct usb_endpoint_descriptor *isoin; /* ISO IN endpoint */ + struct usb_endpoint_descriptor *isoout; /* ISO OUT endpoint */ uint8_t ctrl_intf; /* interface number */ uint8_t data_intf; /* interface number */ uint8_t minor; - usbh_pipe_t isoin; /* ISO IN endpoint */ - usbh_pipe_t isoout; /* ISO OUT endpoint */ struct video_probe_and_commit_controls probe; struct video_probe_and_commit_controls commit; uint16_t isoin_mps; diff --git a/class/wireless/usbd_rndis.c b/class/wireless/usbd_rndis.c index ea00cbf5..5ddc3f24 100644 --- a/class/wireless/usbd_rndis.c +++ b/class/wireless/usbd_rndis.c @@ -45,8 +45,8 @@ struct usbd_rndis_priv { #define CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE 156 #endif -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_rx_buffer[CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE + 44]; -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_tx_buffer[CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE + 44]; +static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_rx_buffer[CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE + 44]; +static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_tx_buffer[CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE + 44]; USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t rndis_encapsulated_resp_buffer[CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE]; USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t NOTIFY_RESPONSE_AVAILABLE[8]; diff --git a/class/wireless/usbh_rndis.c b/class/wireless/usbh_rndis.c index 762fc6e9..2437da78 100644 --- a/class/wireless/usbh_rndis.c +++ b/class/wireless/usbh_rndis.c @@ -11,8 +11,33 @@ USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_buf[4096]; +#define CONFIG_USBHOST_RNDIS_ETH_MAX_FRAME_SIZE 1514 +#define CONFIG_USBHOST_RNDIS_ETH_MSG_SIZE (CONFIG_USBHOST_RNDIS_ETH_MAX_FRAME_SIZE + 44) + +/* eth rx size must be a multiple of 512 or 64 */ +#define CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE (2048) +#define CONFIG_USBHOST_RNDIS_ETH_MAX_TX_SIZE (2048) + +static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_rx_buffer[CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE]; +static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_tx_buffer[CONFIG_USBHOST_RNDIS_ETH_MAX_TX_SIZE]; +// static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_inttx_buffer[16]; + static struct usbh_rndis g_rndis_class; +static int usbh_rndis_get_notification(struct usbh_rndis *rndis_class) +{ + // int ret; + // struct usbh_urb *urb = &rndis_class->intin_urb; + + // usbh_int_urb_fill(urb, rndis_class->hport, rndis_class->intin, g_rndis_inttx_buffer, rndis_class->intin->wMaxPacketSize, USB_OSAL_WAITING_FOREVER, NULL, NULL); + // ret = usbh_submit_urb(urb); + // if (ret == 0) { + // ret = urb->actual_length; + // } + // return ret; + return 0; +} + static int usbh_rndis_init_msg_transfer(struct usbh_rndis *rndis_class) { struct usb_setup_packet *setup = rndis_class->hport->setup; @@ -35,13 +60,13 @@ static int usbh_rndis_init_msg_transfer(struct usbh_rndis *rndis_class) setup->wIndex = 0; setup->wLength = sizeof(rndis_initialize_msg_t); - ret = usbh_control_transfer(rndis_class->hport->ep0, setup, (uint8_t *)cmd); + ret = usbh_control_transfer(rndis_class->hport, setup, (uint8_t *)cmd); if (ret < 0) { USB_LOG_ERR("rndis_initialize_msg_t send error, ret: %d\r\n", ret); return ret; } - //ret = usbh_ep_intr_transfer() + usbh_rndis_get_notification(rndis_class); resp = (rndis_initialize_cmplt_t *)g_rndis_buf; @@ -51,7 +76,7 @@ static int usbh_rndis_init_msg_transfer(struct usbh_rndis *rndis_class) setup->wIndex = 0; setup->wLength = 4096; - ret = usbh_control_transfer(rndis_class->hport->ep0, setup, (uint8_t *)resp); + ret = usbh_control_transfer(rndis_class->hport, setup, (uint8_t *)resp); if (ret < 0) { USB_LOG_ERR("rndis_initialize_cmplt_t recv error, ret: %d\r\n", ret); return ret; @@ -83,13 +108,13 @@ int usbh_rndis_query_msg_transfer(struct usbh_rndis *rndis_class, uint32_t oid, setup->wIndex = 0; setup->wLength = query_len + sizeof(rndis_query_msg_t); - ret = usbh_control_transfer(rndis_class->hport->ep0, setup, (uint8_t *)cmd); + ret = usbh_control_transfer(rndis_class->hport, setup, (uint8_t *)cmd); if (ret < 0) { USB_LOG_ERR("oid:%08x send error, ret: %d\r\n", (unsigned int)oid, ret); return ret; } - //ret = usbh_ep_intr_transfer() + usbh_rndis_get_notification(rndis_class); resp = (rndis_query_cmplt_t *)g_rndis_buf; @@ -99,7 +124,7 @@ int usbh_rndis_query_msg_transfer(struct usbh_rndis *rndis_class, uint32_t oid, setup->wIndex = 0; setup->wLength = 4096; - ret = usbh_control_transfer(rndis_class->hport->ep0, setup, (uint8_t *)resp); + ret = usbh_control_transfer(rndis_class->hport, setup, (uint8_t *)resp); if (ret < 0) { USB_LOG_ERR("oid:%08x recv error, ret: %d\r\n", (unsigned int)oid, ret); return ret; @@ -135,13 +160,13 @@ static int usbh_rndis_set_msg_transfer(struct usbh_rndis *rndis_class, uint32_t setup->wIndex = 0; setup->wLength = info_len + sizeof(rndis_set_msg_t); - ret = usbh_control_transfer(rndis_class->hport->ep0, setup, (uint8_t *)cmd); + ret = usbh_control_transfer(rndis_class->hport, setup, (uint8_t *)cmd); if (ret < 0) { USB_LOG_ERR("oid:%08x send error, ret: %d\r\n", (unsigned int)oid, ret); return ret; } - //ret = usbh_ep_intr_transfer(rndis_class->hport->intin,buf,len,500); + usbh_rndis_get_notification(rndis_class); resp = (rndis_set_cmplt_t *)g_rndis_buf; @@ -151,7 +176,7 @@ static int usbh_rndis_set_msg_transfer(struct usbh_rndis *rndis_class, uint32_t setup->wIndex = 0; setup->wLength = 4096; - ret = usbh_control_transfer(rndis_class->hport->ep0, setup, (uint8_t *)resp); + ret = usbh_control_transfer(rndis_class->hport, setup, (uint8_t *)resp); if (ret < 0) { USB_LOG_ERR("oid:%08x recv error, ret: %d\r\n", (unsigned int)oid, ret); return ret; @@ -160,32 +185,22 @@ static int usbh_rndis_set_msg_transfer(struct usbh_rndis *rndis_class, uint32_t return ret; } -int usbh_rndis_bulk_out_transfer(struct usbh_rndis *rndis_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout) +static int usbh_rndis_get_connect_status(struct usbh_rndis *rndis_class) { int ret; - struct usbh_urb *urb = &rndis_class->bulkout_urb; - memset(urb, 0, sizeof(struct usbh_urb)); + uint8_t data[32]; + uint32_t data_len; - usbh_bulk_urb_fill(urb, rndis_class->bulkout, buffer, buflen, timeout, NULL, NULL); - ret = usbh_submit_urb(urb); - if (ret == 0) { - ret = urb->actual_length; + ret = usbh_rndis_query_msg_transfer(rndis_class, OID_GEN_MEDIA_CONNECT_STATUS, 4, data, &data_len); + if (ret < 0) { + return ret; } - return ret; -} - -int usbh_rndis_bulk_in_transfer(struct usbh_rndis *rndis_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout) -{ - int ret; - struct usbh_urb *urb = &rndis_class->bulkin_urb; - memset(urb, 0, sizeof(struct usbh_urb)); - - usbh_bulk_urb_fill(urb, rndis_class->bulkin, buffer, buflen, timeout, NULL, NULL); - ret = usbh_submit_urb(urb); - if (ret == 0) { - ret = urb->actual_length; + if (NDIS_MEDIA_STATE_CONNECTED == data[0]) { + rndis_class->link_status = true; + } else { + rndis_class->link_status = false; } - return ret; + return 0; } int usbh_rndis_keepalive(struct usbh_rndis *rndis_class) @@ -207,13 +222,13 @@ int usbh_rndis_keepalive(struct usbh_rndis *rndis_class) setup->wIndex = 0; setup->wLength = sizeof(rndis_keepalive_msg_t); - ret = usbh_control_transfer(rndis_class->hport->ep0, setup, (uint8_t *)cmd); + ret = usbh_control_transfer(rndis_class->hport, setup, (uint8_t *)cmd); if (ret < 0) { USB_LOG_ERR("keepalive send error, ret: %d\r\n", ret); return ret; } - //ret = usbh_ep_intr_transfer(rndis_class->hport->intin,buf,len,500); + usbh_rndis_get_notification(rndis_class); resp = (rndis_keepalive_cmplt_t *)g_rndis_buf; @@ -223,7 +238,7 @@ int usbh_rndis_keepalive(struct usbh_rndis *rndis_class) setup->wIndex = 0; setup->wLength = 4096; - ret = usbh_control_transfer(rndis_class->hport->ep0, setup, (uint8_t *)resp); + ret = usbh_control_transfer(rndis_class->hport, setup, (uint8_t *)resp); if (ret < 0) { USB_LOG_ERR("keepalive recv error, ret: %d\r\n", ret); return ret; @@ -254,17 +269,16 @@ static int usbh_rndis_connect(struct usbh_hubport *hport, uint8_t intf) hport->config.intf[intf].priv = rndis_class; hport->config.intf[intf + 1].priv = NULL; -#ifdef CONFIG_USBHOST_RNDIS_NOTIFY - ep_desc = &hport->config.intf[intf].altsetting[0].ep[0].ep_desc; - usbh_hport_activate_epx(&rndis_class->intin, hport, ep_desc); -#endif + // ep_desc = &hport->config.intf[intf].altsetting[0].ep[0].ep_desc; + // USBH_EP_INIT(rndis_class->intin, ep_desc); + for (uint8_t i = 0; i < hport->config.intf[intf + 1].altsetting[0].intf_desc.bNumEndpoints; i++) { ep_desc = &hport->config.intf[intf + 1].altsetting[0].ep[i].ep_desc; if (ep_desc->bEndpointAddress & 0x80) { - usbh_hport_activate_epx(&rndis_class->bulkin, hport, ep_desc); + USBH_EP_INIT(rndis_class->bulkin, ep_desc); } else { - usbh_hport_activate_epx(&rndis_class->bulkout, hport, ep_desc); + USBH_EP_INIT(rndis_class->bulkout, ep_desc); } } @@ -360,6 +374,14 @@ static int usbh_rndis_connect(struct usbh_hubport *hport, uint8_t intf) } USB_LOG_INFO("rndis set OID_802_3_MULTICAST_LIST success\r\n"); + USB_LOG_INFO("rndis MAC address %02x:%02x:%02x:%02x:%02x:%02x\r\n", + rndis_class->mac[0], + rndis_class->mac[1], + rndis_class->mac[2], + rndis_class->mac[3], + rndis_class->mac[4], + rndis_class->mac[5]); + memcpy(hport->config.intf[intf].devname, DEV_FORMAT, CONFIG_USBHOST_DEV_NAMELEN); USB_LOG_INFO("Register RNDIS Class:%s\r\n", hport->config.intf[intf].devname); @@ -378,13 +400,17 @@ static int usbh_rndis_disconnect(struct usbh_hubport *hport, uint8_t intf) if (rndis_class) { if (rndis_class->bulkin) { - usbh_pipe_free(rndis_class->bulkin); + usbh_kill_urb(&rndis_class->bulkin_urb); } if (rndis_class->bulkout) { - usbh_pipe_free(rndis_class->bulkout); + usbh_kill_urb(&rndis_class->bulkout_urb); } + // if (rndis_class->intin) { + // usbh_kill_urb(&rndis_class->intin_urb); + // } + if (hport->config.intf[intf].devname[0] != '\0') { USB_LOG_INFO("Unregister RNDIS Class:%s\r\n", hport->config.intf[intf].devname); usbh_rndis_stop(rndis_class); @@ -396,6 +422,123 @@ static int usbh_rndis_disconnect(struct usbh_hubport *hport, uint8_t intf) return ret; } +static void usbh_rndis_rx_thread(void *argument) +{ + uint32_t g_rndis_rx_length; + uint32_t pmg_offset; + uint32_t payload_offset; + int ret; + err_t err; + struct pbuf *p, *q; + rndis_data_packet_t *pmsg; + rndis_data_packet_t temp; + struct netif *netif = (struct netif *)argument; + + // clang-format off +find_class: + // clang-format on + g_rndis_class.link_status = false; + while (usbh_find_class_instance("/dev/rndis") == NULL) { + usb_osal_msleep(1000); + } + + while (g_rndis_class.link_status == false) { + ret = usbh_rndis_get_connect_status(&g_rndis_class); + if (ret < 0) { + goto find_class; + } + } + + while (1) { + g_rndis_rx_length = 0; + usbh_bulk_urb_fill(&g_rndis_class.bulkin_urb, g_rndis_class.hport, g_rndis_class.bulkin, g_rndis_rx_buffer, CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE, USB_OSAL_WAITING_FOREVER, NULL, NULL); + ret = usbh_submit_urb(&g_rndis_class.bulkin_urb); + if (ret < 0) { + goto find_class; + } + + g_rndis_rx_length = g_rndis_class.bulkin_urb.actual_length; + pmg_offset = 0; + while (g_rndis_rx_length > 0) { + USB_LOG_DBG("rxlen:%d\r\n", g_rndis_rx_length); + + pmsg = (rndis_data_packet_t *)(g_rndis_rx_buffer + pmg_offset); + + /* Not word-aligned case */ + if (pmg_offset & 0x3) { + memcpy(&temp, pmsg, sizeof(rndis_data_packet_t)); + pmsg = &temp; + } + + if (pmsg->MessageType == REMOTE_NDIS_PACKET_MSG) { + p = pbuf_alloc(PBUF_RAW, pmsg->DataLength, PBUF_POOL); + if (p != NULL) { + payload_offset = 0; + for (q = p; q != NULL; q = q->next) { + void *src = (void *)(g_rndis_rx_buffer + pmg_offset + sizeof(rndis_generic_msg_t) + pmsg->DataOffset + payload_offset); + memcpy(q->payload, src, q->len); + payload_offset += q->len; + } + + err = netif->input(p, netif); + if (err != ERR_OK) { + pbuf_free(p); + } + pmg_offset += pmsg->MessageLength; + g_rndis_rx_length -= pmsg->MessageLength; + } else { + USB_LOG_ERR("No memory to alloc pbuf for rndis rx\r\n"); + } + } + } + } +} + +err_t usbh_rndis_linkoutput(struct netif *netif, struct pbuf *p) +{ + int ret; + struct pbuf *q; + uint8_t *buffer; + rndis_data_packet_t *hdr; + + if (g_rndis_class.link_status == false) { + return ERR_BUF; + } + + hdr = (rndis_data_packet_t *)g_rndis_tx_buffer; + memset(hdr, 0, sizeof(rndis_data_packet_t)); + hdr->MessageType = REMOTE_NDIS_PACKET_MSG; + hdr->MessageLength = sizeof(rndis_data_packet_t) + p->tot_len; + hdr->DataOffset = sizeof(rndis_data_packet_t) - sizeof(rndis_generic_msg_t); + hdr->DataLength = p->tot_len; + + buffer = (uint8_t *)(g_rndis_tx_buffer + sizeof(rndis_data_packet_t)); + for (q = p; q != NULL; q = q->next) { + memcpy(buffer, q->payload, q->len); + buffer += q->len; + } + /* send */ + if ((hdr->MessageLength & 0x1FF) == 0) { + /* pad a dummy. */ + hdr->MessageLength += 1; + } + + USB_LOG_DBG("txlen:%d\r\n", hdr->MessageLength); + + usbh_bulk_urb_fill(&g_rndis_class.bulkout_urb, g_rndis_class.hport, g_rndis_class.bulkout, g_rndis_tx_buffer, hdr->MessageLength, USB_OSAL_WAITING_FOREVER, NULL, NULL); + ret = usbh_submit_urb(&g_rndis_class.bulkout_urb); + if (ret < 0) { + return ERR_BUF; + } + + return ERR_OK; +} + +void usbh_rndis_lwip_thread_init(struct netif *netif) +{ + usb_osal_thread_create("usbh_rndis_rx", 2560, CONFIG_USBHOST_PSC_PRIO + 1, usbh_rndis_rx_thread, netif); +} + __WEAK void usbh_rndis_run(struct usbh_rndis *rndis_class) { } diff --git a/class/wireless/usbh_rndis.h b/class/wireless/usbh_rndis.h index 8f3e2244..c55c113f 100644 --- a/class/wireless/usbh_rndis.h +++ b/class/wireless/usbh_rndis.h @@ -8,36 +8,45 @@ #include "usb_cdc.h" +#include "lwip/netif.h" +#include "lwip/pbuf.h" + struct usbh_rndis { struct usbh_hubport *hport; + struct usb_endpoint_descriptor *bulkin; /* Bulk IN endpoint */ + struct usb_endpoint_descriptor *bulkout; /* Bulk OUT endpoint */ + struct usb_endpoint_descriptor *intin; /* INTR endpoint */ + struct usbh_urb bulkin_urb; /* Bulk IN urb */ + struct usbh_urb bulkout_urb; /* Bulk OUT urb */ + struct usbh_urb intin_urb; /* INTR IN urb */ uint8_t ctrl_intf; /* Control interface number */ uint8_t data_intf; /* Data interface number */ uint8_t minor; - usbh_pipe_t bulkin; /* Bulk IN endpoint */ - usbh_pipe_t bulkout; /* Bulk OUT endpoint */ - usbh_pipe_t intin; /* Notify endpoint */ - struct usbh_urb bulkin_urb; /* Bulk IN urb */ - struct usbh_urb bulkout_urb; /* Bulk OUT urb */ + uint32_t request_id; uint32_t link_speed; bool link_status; uint8_t mac[6]; + + ip_addr_t ipaddr; + ip_addr_t netmask; + ip_addr_t gateway; }; #ifdef __cplusplus extern "C" { #endif -int usbh_rndis_bulk_out_transfer(struct usbh_rndis *rndis_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout); -int usbh_rndis_bulk_in_transfer(struct usbh_rndis *rndis_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout); - int usbh_rndis_keepalive(struct usbh_rndis *rndis_class); void usbh_rndis_run(struct usbh_rndis *rndis_class); void usbh_rndis_stop(struct usbh_rndis *rndis_class); +err_t usbh_rndis_linkoutput(struct netif *netif, struct pbuf *p); +void usbh_rndis_lwip_thread_init(struct netif *netif); + #ifdef __cplusplus } #endif |
