summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsakumisu <[email protected]>2023-11-15 22:08:26 +0800
committersakumisu <[email protected]>2023-11-16 19:56:52 +0800
commit5bbe2a97f25ca780dde2bab0e9aafab46bac8913 (patch)
treebece48da7a331c6fd7e1f95d0484d6bbe0fa102e
parentc1435548e7aab942dc2397718c692379803f26a1 (diff)
refactor urb, add ep & hport in urb to make hardware pipe more reusable
-rw-r--r--class/audio/usbh_audio.c18
-rw-r--r--class/audio/usbh_audio.h4
-rw-r--r--class/cdc/usbd_cdc_ecm.c6
-rw-r--r--class/cdc/usbh_cdc_acm.c48
-rw-r--r--class/cdc/usbh_cdc_acm.h14
-rw-r--r--class/cdc/usbh_cdc_ecm.c54
-rw-r--r--class/cdc/usbh_cdc_ecm.h17
-rw-r--r--class/hid/usbh_hid.c16
-rw-r--r--class/hid/usbh_hid.h6
-rw-r--r--class/hub/usbh_hub.c79
-rw-r--r--class/msc/usbh_msc.c117
-rw-r--r--class/msc/usbh_msc.h12
-rw-r--r--class/video/usbh_video.c16
-rw-r--r--class/video/usbh_video.h4
-rw-r--r--class/wireless/usbd_rndis.c4
-rw-r--r--class/wireless/usbh_rndis.c225
-rw-r--r--class/wireless/usbh_rndis.h25
-rw-r--r--common/usb_def.h3
-rw-r--r--common/usb_hc.h48
-rw-r--r--core/usbh_core.c127
-rw-r--r--core/usbh_core.h138
-rw-r--r--demo/usb_host.c138
-rw-r--r--port/dwc2/usb_hc_dwc2.c400
-rw-r--r--port/ehci/usb_ehci_priv.h33
-rw-r--r--port/ehci/usb_hc_ehci.c332
-rw-r--r--port/musb/usb_hc_musb.c356
26 files changed, 1070 insertions, 1170 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
diff --git a/common/usb_def.h b/common/usb_def.h
index 31cb2b8e..8fc76d17 100644
--- a/common/usb_def.h
+++ b/common/usb_def.h
@@ -221,6 +221,7 @@
#define USB_ENDPOINT_TYPE_BULK (2 << USB_ENDPOINT_TYPE_SHIFT)
#define USB_ENDPOINT_TYPE_INTERRUPT (3 << USB_ENDPOINT_TYPE_SHIFT)
#define USB_ENDPOINT_TYPE_MASK (3 << USB_ENDPOINT_TYPE_SHIFT)
+#define USB_GET_ENDPOINT_TYPE(x) ((x & USB_ENDPOINT_TYPE_MASK) >> USB_ENDPOINT_TYPE_SHIFT)
#define USB_ENDPOINT_SYNC_SHIFT 2
#define USB_ENDPOINT_SYNC_NO_SYNCHRONIZATION (0 << USB_ENDPOINT_SYNC_SHIFT)
@@ -245,6 +246,8 @@
#define USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_ONE (1 << USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_SHIFT)
#define USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_TWO (2 << USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_SHIFT)
#define USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_MASK (3 << USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_SHIFT)
+#define USB_GET_MAXPACKETSIZE(x) ((x & USB_MAXPACKETSIZE_MASK) >> USB_MAXPACKETSIZE_SHIFT)
+#define USB_GET_MULT(x) ((x & USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_MASK) >> USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_SHIFT)
/* bDevCapabilityType in Device Capability Descriptor */
#define USB_DEVICE_CAPABILITY_WIRELESS_USB 1
diff --git a/common/usb_hc.h b/common/usb_hc.h
index 95215841..2596a50c 100644
--- a/common/usb_hc.h
+++ b/common/usb_hc.h
@@ -13,21 +13,6 @@ extern "C" {
#endif
typedef void (*usbh_complete_callback_t)(void *arg, int nbytes);
-typedef void *usbh_pipe_t;
-
-/**
- * @brief USB Endpoint Configuration.
- *
- * Structure containing the USB endpoint configuration.
- */
-struct usbh_endpoint_cfg {
- struct usbh_hubport *hport;
- uint8_t ep_addr; /* Endpoint addr with direction */
- uint8_t ep_type; /* Endpoint type */
- uint16_t ep_mps; /* Endpoint max packet size */
- uint8_t ep_interval; /* Endpoint interval */
- uint8_t mult; /* Endpoint additional transcation */
-};
/**
* @brief USB Iso Configuration.
@@ -47,7 +32,10 @@ struct usbh_iso_frame_packet {
* Structure containing the USB Urb configuration.
*/
struct usbh_urb {
- usbh_pipe_t pipe;
+ void *hcpriv;
+ struct usbh_hubport *hport;
+ struct usb_endpoint_descriptor *ep;
+ uint8_t data_toggle;
struct usb_setup_packet *setup;
uint8_t *transfer_buffer;
uint32_t transfer_buffer_length;
@@ -89,34 +77,6 @@ uint16_t usbh_get_frame_number(void);
int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf);
/**
- * @brief reconfig endpoint pipe.
- *
- * @param pipe A memory allocated for pipe.
- * @param dev_addr device address.
- * @param ep_mps endpoint max packet size.
- * @param mult endpoint additional transcation
- * @return On success will return 0, and others indicate fail.
- */
-int usbh_ep_pipe_reconfigure(usbh_pipe_t pipe, uint8_t dev_addr, uint8_t ep_mps, uint8_t mult);
-
-/**
- * @brief Allocate pipe for endpoint
- *
- * @param pipe A memory location provided by the caller in which to save the allocated pipe.
- * @param ep_cfg Describes the endpoint info to be allocated.
- * @return On success will return 0, and others indicate fail.
- */
-int usbh_pipe_alloc(usbh_pipe_t *pipe, const struct usbh_endpoint_cfg *ep_cfg);
-
-/**
- * @brief Free a pipe in which saves endpoint info.
- *
- * @param pipe A memory location provided by the caller in which to free the allocated endpoint info.
- * @return On success will return 0, and others indicate fail.
- */
-int usbh_pipe_free(usbh_pipe_t pipe);
-
-/**
* @brief Submit a usb transfer request to an endpoint.
*
* If timeout is not zero, this function will be in poll transfer mode,
diff --git a/core/usbh_core.c b/core/usbh_core.c
index baecb438..025d0ecf 100644
--- a/core/usbh_core.c
+++ b/core/usbh_core.c
@@ -64,7 +64,7 @@ static int usbh_allocate_devaddr(struct usbh_devaddr_map *devgen)
}
}
-static int usbh_free_devaddr(struct usbh_devaddr_map *devgen, uint8_t devaddr)
+static int __usbh_free_devaddr(struct usbh_devaddr_map *devgen, uint8_t devaddr)
{
int index;
int bitno;
@@ -340,57 +340,18 @@ static int usbh_get_default_mps(int speed)
}
}
-int usbh_hport_activate_ep0(struct usbh_hubport *hport)
-{
- struct usbh_endpoint_cfg ep0_cfg = { 0 };
-
- ep0_cfg.ep_addr = 0x00;
- ep0_cfg.ep_interval = 0x00;
- ep0_cfg.ep_mps = usbh_get_default_mps(hport->speed);
- ep0_cfg.ep_type = USB_ENDPOINT_TYPE_CONTROL;
- ep0_cfg.hport = hport;
-
- usbh_pipe_alloc(&hport->ep0, &ep0_cfg);
- return 0;
-}
-
-int usbh_hport_deactivate_ep0(struct usbh_hubport *hport)
+int usbh_free_devaddr(struct usbh_hubport *hport)
{
#ifndef CONFIG_USBHOST_XHCI
if (hport->dev_addr > 0) {
- usbh_free_devaddr(&g_usbh_bus.devgen, hport->dev_addr);
+ __usbh_free_devaddr(&g_usbh_bus.devgen, hport->dev_addr);
}
#endif
- if (hport->ep0) {
- usbh_pipe_free(hport->ep0);
- }
- hport->ep0 = NULL;
hport->dev_addr = 0;
return 0;
}
-int usbh_hport_activate_epx(usbh_pipe_t *pipe, struct usbh_hubport *hport, struct usb_endpoint_descriptor *ep_desc)
-{
- struct usbh_endpoint_cfg ep_cfg = { 0 };
-
- ep_cfg.ep_addr = ep_desc->bEndpointAddress;
- ep_cfg.ep_type = ep_desc->bmAttributes & USB_ENDPOINT_TYPE_MASK;
- ep_cfg.ep_mps = ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_MASK;
- ep_cfg.ep_interval = ep_desc->bInterval;
- ep_cfg.mult = (ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_MASK) >> USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_SHIFT;
- ep_cfg.hport = hport;
-
- USB_LOG_INFO("Ep=%02x Attr=%02u Mps=%d Interval=%02u Mult=%02u\r\n",
- ep_cfg.ep_addr,
- ep_desc->bmAttributes,
- ep_cfg.ep_mps,
- ep_cfg.ep_interval,
- ep_cfg.mult);
-
- return usbh_pipe_alloc(pipe, &ep_cfg);
-}
-
int usbh_get_string_desc(struct usbh_hubport *hport, uint8_t index, uint8_t *output)
{
struct usb_setup_packet *setup = hport->setup;
@@ -408,7 +369,7 @@ int usbh_get_string_desc(struct usbh_hubport *hport, uint8_t index, uint8_t *out
setup->wIndex = 0x0409;
setup->wLength = 255;
- ret = usbh_control_transfer(hport->ep0, setup, ep0_request_buffer);
+ ret = usbh_control_transfer(hport, setup, ep0_request_buffer);
if (ret < 0) {
return ret;
}
@@ -436,7 +397,7 @@ int usbh_set_interface(struct usbh_hubport *hport, uint8_t intf, uint8_t altsett
setup->wIndex = altsetting;
setup->wLength = 0;
- return usbh_control_transfer(hport->ep0, setup, NULL);
+ return usbh_control_transfer(hport, setup, NULL);
}
int usbh_enumerate(struct usbh_hubport *hport)
@@ -444,12 +405,25 @@ int usbh_enumerate(struct usbh_hubport *hport)
struct usb_interface_descriptor *intf_desc;
struct usb_setup_packet *setup;
struct usb_device_descriptor *dev_desc;
+ struct usb_endpoint_descriptor *ep;
int dev_addr;
uint16_t ep_mps;
int ret;
hport->setup = &g_setup[hport->parent->index - 1][hport->port - 1];
setup = hport->setup;
+ ep = &hport->ep0;
+
+ /* Config EP0 mps from speed */
+ ep->bEndpointAddress = 0x00;
+ ep->bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT;
+ ep->bmAttributes = USB_ENDPOINT_TYPE_CONTROL;
+ ep->wMaxPacketSize = usbh_get_default_mps(hport->speed);
+ ep->bInterval = 0;
+ ep->bLength = 7;
+
+ /* Configure EP0 with zero address */
+ hport->dev_addr = 0;
/* Read the first 8 bytes of the device descriptor */
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
@@ -458,7 +432,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
setup->wIndex = 0;
setup->wLength = 8;
- ret = usbh_control_transfer(hport->ep0, setup, ep0_request_buffer);
+ ret = usbh_control_transfer(hport, setup, ep0_request_buffer);
if (ret < 0) {
USB_LOG_ERR("Failed to get device descriptor,errorcode:%d\r\n", ret);
goto errout;
@@ -479,7 +453,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
dev_desc->bDeviceProtocol, ep_mps);
/* Reconfigure EP0 with the correct maximum packet size */
- usbh_ep_pipe_reconfigure(hport->ep0, 0, ep_mps, 0);
+ ep->wMaxPacketSize = ep_mps;
#ifdef CONFIG_USBHOST_XHCI
extern int usbh_get_xhci_devaddr(usbh_pipe_t * pipe);
@@ -506,7 +480,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
setup->wIndex = 0;
setup->wLength = 0;
- ret = usbh_control_transfer(hport->ep0, setup, NULL);
+ ret = usbh_control_transfer(hport, setup, NULL);
if (ret < 0) {
USB_LOG_ERR("Failed to set devaddr,errorcode:%d\r\n", ret);
goto errout;
@@ -515,12 +489,9 @@ int usbh_enumerate(struct usbh_hubport *hport)
/* Wait device set address completely */
usb_osal_msleep(2);
- /* Assign the function address to the port */
+ /*Reconfigure EP0 with the correct address */
hport->dev_addr = dev_addr;
- /* And reconfigure EP0 with the correct address */
- usbh_ep_pipe_reconfigure(hport->ep0, dev_addr, ep_mps, 0);
-
/* Read the full device descriptor */
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
setup->bRequest = USB_REQUEST_GET_DESCRIPTOR;
@@ -528,7 +499,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
setup->wIndex = 0;
setup->wLength = USB_SIZEOF_DEVICE_DESC;
- ret = usbh_control_transfer(hport->ep0, setup, ep0_request_buffer);
+ ret = usbh_control_transfer(hport, setup, ep0_request_buffer);
if (ret < 0) {
USB_LOG_ERR("Failed to get full device descriptor,errorcode:%d\r\n", ret);
goto errout;
@@ -547,7 +518,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
setup->wIndex = 0;
setup->wLength = USB_SIZEOF_CONFIG_DESC;
- ret = usbh_control_transfer(hport->ep0, setup, ep0_request_buffer);
+ ret = usbh_control_transfer(hport, setup, ep0_request_buffer);
if (ret < 0) {
USB_LOG_ERR("Failed to get config descriptor,errorcode:%d\r\n", ret);
goto errout;
@@ -564,7 +535,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
setup->wIndex = 0;
setup->wLength = wTotalLength;
- ret = usbh_control_transfer(hport->ep0, setup, ep0_request_buffer);
+ ret = usbh_control_transfer(hport, setup, ep0_request_buffer);
if (ret < 0) {
USB_LOG_ERR("Failed to get full config descriptor,errorcode:%d\r\n", ret);
goto errout;
@@ -623,7 +594,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
setup->wIndex = 0;
setup->wLength = 0;
- ret = usbh_control_transfer(hport->ep0, setup, NULL);
+ ret = usbh_control_transfer(hport, setup, NULL);
if (ret < 0) {
USB_LOG_ERR("Failed to set configuration,errorcode:%d\r\n", ret);
goto errout;
@@ -670,27 +641,6 @@ errout:
return ret;
}
-void *usbh_find_class_instance(const char *devname)
-{
- struct usbh_hubport *hport;
- usb_slist_t *hub_list;
-
- usb_slist_for_each(hub_list, &hub_class_head)
- {
- struct usbh_hub *hub = usb_slist_entry(hub_list, struct usbh_hub, list);
- for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
- hport = &hub->child[port];
- if (hport->connected) {
- for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) {
- if ((strncmp(hport->config.intf[itf].devname, devname, CONFIG_USBHOST_DEV_NAMELEN) == 0) && hport->config.intf[itf].priv)
- return hport->config.intf[itf].priv;
- }
- }
- }
- }
- return NULL;
-}
-
int usbh_initialize(void)
{
memset(&g_usbh_bus, 0, sizeof(struct usbh_bus));
@@ -717,7 +667,7 @@ int usbh_initialize(void)
return 0;
}
-int usbh_control_transfer(usbh_pipe_t pipe, struct usb_setup_packet *setup, uint8_t *buffer)
+int usbh_control_transfer(struct usbh_hubport *hport, struct usb_setup_packet *setup, uint8_t *buffer)
{
struct usbh_urb *urb;
int ret;
@@ -725,7 +675,7 @@ int usbh_control_transfer(usbh_pipe_t pipe, struct usb_setup_packet *setup, uint
urb = usb_malloc(sizeof(struct usbh_urb));
memset(urb, 0, sizeof(struct usbh_urb));
- usbh_control_urb_fill(urb, pipe, setup, buffer, setup->wLength, CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT, NULL, NULL);
+ usbh_control_urb_fill(urb, hport, setup, buffer, setup->wLength, CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT, NULL, NULL);
ret = usbh_submit_urb(urb);
if (ret == 0) {
@@ -735,6 +685,27 @@ int usbh_control_transfer(usbh_pipe_t pipe, struct usb_setup_packet *setup, uint
return ret;
}
+void *usbh_find_class_instance(const char *devname)
+{
+ struct usbh_hubport *hport;
+ usb_slist_t *hub_list;
+
+ usb_slist_for_each(hub_list, &hub_class_head)
+ {
+ struct usbh_hub *hub = usb_slist_entry(hub_list, struct usbh_hub, list);
+ for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
+ hport = &hub->child[port];
+ if (hport->connected) {
+ for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) {
+ if ((strncmp(hport->config.intf[itf].devname, devname, CONFIG_USBHOST_DEV_NAMELEN) == 0) && hport->config.intf[itf].priv)
+ return hport->config.intf[itf].priv;
+ }
+ }
+ }
+ }
+ return NULL;
+}
+
int lsusb(int argc, char **argv)
{
usb_slist_t *i;
diff --git a/core/usbh_core.h b/core/usbh_core.h
index d5a7c6ea..5f538329 100644
--- a/core/usbh_core.h
+++ b/core/usbh_core.h
@@ -32,8 +32,8 @@ extern "C" {
#define USB_CLASS_MATCH_INTF_SUBCLASS 0x0008
#define USB_CLASS_MATCH_INTF_PROTOCOL 0x0010
-#define CLASS_CONNECT(hport, i) ((hport)->config.intf[i].class_driver->connect(hport, i))
-#define CLASS_DISCONNECT(hport, i) ((hport)->config.intf[i].class_driver->disconnect(hport, i))
+#define CLASS_CONNECT(hport, i) ((hport)->config.intf[i].class_driver->connect(hport, i))
+#define CLASS_DISCONNECT(hport, i) ((hport)->config.intf[i].class_driver->disconnect(hport, i))
#ifdef __ARMCC_VERSION /* ARM C Compiler */
#define CLASS_INFO_DEFINE __attribute__((section("usbh_class_info"))) __USED __ALIGNED(1)
@@ -44,57 +44,16 @@ extern "C" {
#define CLASS_INFO_DEFINE __attribute__((section("usbh_class_info"))) __USED __ALIGNED(1)
#endif
-static inline void usbh_control_urb_fill(struct usbh_urb *urb,
- usbh_pipe_t pipe,
- struct usb_setup_packet *setup,
- uint8_t *transfer_buffer,
- uint32_t transfer_buffer_length,
- uint32_t timeout,
- usbh_complete_callback_t complete,
- void *arg)
-{
- urb->pipe = pipe;
- urb->setup = setup;
- urb->transfer_buffer = transfer_buffer;
- urb->transfer_buffer_length = transfer_buffer_length;
- urb->timeout = timeout;
- urb->complete = complete;
- urb->arg = arg;
-}
-
-static inline void usbh_bulk_urb_fill(struct usbh_urb *urb,
- usbh_pipe_t pipe,
- uint8_t *transfer_buffer,
- uint32_t transfer_buffer_length,
- uint32_t timeout,
- usbh_complete_callback_t complete,
- void *arg)
-{
- urb->pipe = pipe;
- urb->setup = NULL;
- urb->transfer_buffer = transfer_buffer;
- urb->transfer_buffer_length = transfer_buffer_length;
- urb->timeout = timeout;
- urb->complete = complete;
- urb->arg = arg;
-}
-
-static inline void usbh_int_urb_fill(struct usbh_urb *urb,
- usbh_pipe_t pipe,
- uint8_t *transfer_buffer,
- uint32_t transfer_buffer_length,
- uint32_t timeout,
- usbh_complete_callback_t complete,
- void *arg)
-{
- urb->pipe = pipe;
- urb->setup = NULL;
- urb->transfer_buffer = transfer_buffer;
- urb->transfer_buffer_length = transfer_buffer_length;
- urb->timeout = timeout;
- urb->complete = complete;
- urb->arg = arg;
-}
+#define USBH_EP_INIT(ep, ep_desc) \
+ do { \
+ ep = ep_desc; \
+ USB_LOG_INFO("Ep=%02x Attr=%02u Mps=%d Interval=%02u Mult=%02u\r\n", \
+ ep_desc->bEndpointAddress, \
+ USB_GET_ENDPOINT_TYPE(ep_desc->bmAttributes), \
+ USB_GET_MAXPACKETSIZE(ep_desc->wMaxPacketSize), \
+ ep_desc->bInterval, \
+ USB_GET_MULT(ep_desc->bmAttributes)); \
+ } while (0)
struct usbh_class_info {
uint8_t match_flags; /* Used for product specific matches; range is inclusive */
@@ -140,7 +99,7 @@ struct usbh_hubport {
uint8_t port; /* Hub port index */
uint8_t dev_addr; /* device address */
uint8_t speed; /* device speed */
- usbh_pipe_t ep0; /* control ep pipe info */
+ struct usb_endpoint_descriptor ep0;
struct usb_device_descriptor device_desc;
struct usbh_configuration config;
const char *iManufacturer;
@@ -161,7 +120,7 @@ struct usbh_hub {
bool is_roothub;
uint8_t index;
uint8_t hub_addr;
- usbh_pipe_t intin;
+ struct usb_endpoint_descriptor *intin;
uint8_t *int_buffer;
struct usbh_urb intin_urb;
struct usb_hub_descriptor hub_desc;
@@ -169,17 +128,62 @@ struct usbh_hub {
struct usbh_hubport *parent;
};
-/**
- * @brief Activates an endpoint for a USB host pipe on a specific hub port.
- *
- * This function is responsible for activating the specified endpoint
- * described by the given endpoint descriptor on the USB host pipe.
- * @param pipe Pointer to the USB host pipe structure.
- * @param hport Pointer to the USB hub port structure.
- * @param ep_desc Pointer to the USB endpoint descriptor.
- * @return On success will return 0, and others indicate fail.
- */
-int usbh_hport_activate_epx(usbh_pipe_t *pipe, struct usbh_hubport *hport, struct usb_endpoint_descriptor *ep_desc);
+static inline void usbh_control_urb_fill(struct usbh_urb *urb,
+ struct usbh_hubport *hport,
+ struct usb_setup_packet *setup,
+ uint8_t *transfer_buffer,
+ uint32_t transfer_buffer_length,
+ uint32_t timeout,
+ usbh_complete_callback_t complete,
+ void *arg)
+{
+ urb->hport = hport;
+ urb->ep = &hport->ep0;
+ urb->setup = setup;
+ urb->transfer_buffer = transfer_buffer;
+ urb->transfer_buffer_length = transfer_buffer_length;
+ urb->timeout = timeout;
+ urb->complete = complete;
+ urb->arg = arg;
+}
+
+static inline void usbh_bulk_urb_fill(struct usbh_urb *urb,
+ struct usbh_hubport *hport,
+ struct usb_endpoint_descriptor *ep,
+ uint8_t *transfer_buffer,
+ uint32_t transfer_buffer_length,
+ uint32_t timeout,
+ usbh_complete_callback_t complete,
+ void *arg)
+{
+ urb->hport = hport;
+ urb->ep = ep;
+ urb->setup = NULL;
+ urb->transfer_buffer = transfer_buffer;
+ urb->transfer_buffer_length = transfer_buffer_length;
+ urb->timeout = timeout;
+ urb->complete = complete;
+ urb->arg = arg;
+}
+
+static inline void usbh_int_urb_fill(struct usbh_urb *urb,
+ struct usbh_hubport *hport,
+ struct usb_endpoint_descriptor *ep,
+ uint8_t *transfer_buffer,
+ uint32_t transfer_buffer_length,
+ uint32_t timeout,
+ usbh_complete_callback_t complete,
+ void *arg)
+{
+ urb->hport = hport;
+ urb->ep = ep;
+ urb->setup = NULL;
+ urb->transfer_buffer = transfer_buffer;
+ urb->transfer_buffer_length = transfer_buffer_length;
+ urb->timeout = timeout;
+ urb->complete = complete;
+ urb->arg = arg;
+}
/**
* @brief Submit an control transfer to an endpoint.
@@ -191,7 +195,7 @@ int usbh_hport_activate_epx(usbh_pipe_t *pipe, struct usbh_hubport *hport, struc
* @param buffer buffer used for sending the request and for returning any responses.
* @return On success will return 0, and others indicate fail.
*/
-int usbh_control_transfer(usbh_pipe_t pipe, struct usb_setup_packet *setup, uint8_t *buffer);
+int usbh_control_transfer(struct usbh_hubport *hport, struct usb_setup_packet *setup, uint8_t *buffer);
/**
* @brief Retrieves a USB string descriptor from a specific hub port.
diff --git a/demo/usb_host.c b/demo/usb_host.c
index 9d156fc3..e25764d4 100644
--- a/demo/usb_host.c
+++ b/demo/usb_host.c
@@ -12,13 +12,11 @@
#define TEST_USBH_AUDIO 0
#define TEST_USBH_VIDEO 0
#define TEST_USBH_CDC_ECM 0
+#define TEST_USBH_RNDIS 0
#if TEST_USBH_CDC_ACM
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t cdc_buffer[512];
-struct usbh_urb cdc_bulkin_urb;
-struct usbh_urb cdc_bulkout_urb;
-
void usbh_cdc_acm_callback(void *arg, int nbytes)
{
//struct usbh_cdc_acm *cdc_acm_class = (struct usbh_cdc_acm *)arg;
@@ -48,31 +46,19 @@ find_class:
}
memset(cdc_buffer, 0, 512);
- usbh_bulk_urb_fill(&cdc_bulkin_urb, cdc_acm_class->bulkin, cdc_buffer, 64, 3000, NULL, NULL);
- ret = usbh_submit_urb(&cdc_bulkin_urb);
- if (ret < 0) {
- USB_LOG_RAW("bulk in error,ret:%d\r\n", ret);
- } else {
- USB_LOG_RAW("recv over:%d\r\n", cdc_bulkin_urb.actual_length);
- for (size_t i = 0; i < cdc_bulkin_urb.actual_length; i++) {
- USB_LOG_RAW("0x%02x ", cdc_buffer[i]);
- }
- }
-
- USB_LOG_RAW("\r\n");
const uint8_t data1[10] = { 0x02, 0x00, 0x00, 0x00, 0x02, 0x02, 0x08, 0x14 };
- memcpy(cdc_buffer, data1, 8);
- usbh_bulk_urb_fill(&cdc_bulkout_urb, cdc_acm_class->bulkout, cdc_buffer, 8, 3000, NULL, NULL);
- ret = usbh_submit_urb(&cdc_bulkout_urb);
+ memcpy(cdc_buffer, data1, 10);
+ usbh_bulk_urb_fill(&cdc_acm_class->bulkout_urb, cdc_acm_class->hport, cdc_acm_class->bulkout, cdc_buffer, 10, 3000, NULL, NULL);
+ ret = usbh_submit_urb(&cdc_acm_class->bulkout_urb);
if (ret < 0) {
USB_LOG_RAW("bulk out error,ret:%d\r\n", ret);
} else {
- USB_LOG_RAW("send over:%d\r\n", cdc_bulkout_urb.actual_length);
+ USB_LOG_RAW("send over:%d\r\n", cdc_acm_class->bulkout_urb.actual_length);
}
- usbh_bulk_urb_fill(&cdc_bulkin_urb, cdc_acm_class->bulkin, cdc_buffer, 64, 3000, usbh_cdc_acm_callback, cdc_acm_class);
- ret = usbh_submit_urb(&cdc_bulkin_urb);
+ usbh_bulk_urb_fill(&cdc_acm_class->bulkin_urb, cdc_acm_class->hport, cdc_acm_class->bulkin, cdc_buffer, cdc_acm_class->bulkin->wMaxPacketSize, 3000, usbh_cdc_acm_callback, cdc_acm_class);
+ ret = usbh_submit_urb(&cdc_acm_class->bulkin_urb);
if (ret < 0) {
USB_LOG_RAW("bulk in error,ret:%d\r\n", ret);
} else {
@@ -92,18 +78,16 @@ find_class:
#if TEST_USBH_HID
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t hid_buffer[128];
-struct usbh_urb hid_intin_urb;
-
void usbh_hid_callback(void *arg, int nbytes)
{
- //struct usbh_hid *hid_class = (struct usbh_hid *)arg;
+ struct usbh_hid *hid_class = (struct usbh_hid *)arg;
if (nbytes > 0) {
for (size_t i = 0; i < nbytes; i++) {
USB_LOG_RAW("0x%02x ", hid_buffer[i]);
}
USB_LOG_RAW("nbytes:%d\r\n", nbytes);
- usbh_submit_urb(&hid_intin_urb);
+ usbh_submit_urb(&hid_class->intin_urb);
}
}
@@ -122,8 +106,8 @@ find_class:
usb_osal_msleep(1500);
continue;
}
- usbh_int_urb_fill(&hid_intin_urb, hid_class->intin, hid_buffer, 8, 0, usbh_hid_callback, hid_class);
- ret = usbh_submit_urb(&hid_intin_urb);
+ usbh_int_urb_fill(&hid_class->intin_urb, hid_class->hport, hid_class->intin, hid_buffer, hid_class->intin->wMaxPacketSize, 0, usbh_hid_callback, hid_class);
+ ret = usbh_submit_urb(&hid_class->intin_urb);
if (ret < 0) {
usb_osal_msleep(1500);
goto find_class;
@@ -441,6 +425,98 @@ void usbh_cdc_ecm_stop(struct usbh_cdc_ecm *cdc_ecm_class)
}
#endif
+#if TEST_USBH_RNDIS
+
+#include "usbh_rndis.h"
+
+#include "netif/etharp.h"
+#include "lwip/netif.h"
+#include "lwip/pbuf.h"
+#include "lwip/tcpip.h"
+#if LWIP_DHCP
+#include "lwip/dhcp.h"
+#endif
+
+#include "FreeRTOS.h"
+#include "task.h"
+#include "semphr.h"
+#include "timers.h"
+
+struct netif g_rndis_netif;
+
+TimerHandle_t timer_handle;
+
+static void rndis_dev_keepalive_timeout(TimerHandle_t xTimer)
+{
+ struct usbh_rndis *rndis_class = (struct usbh_rndis *)pvTimerGetTimerID(xTimer);
+ usbh_rndis_keepalive(rndis_class);
+}
+
+void timer_init(struct usbh_rndis *rndis_class)
+{
+ timer_handle = xTimerCreate((const char *)NULL, (TickType_t)3000, (UBaseType_t)pdTRUE, (void *const)rndis_class, (TimerCallbackFunction_t)rndis_dev_keepalive_timeout);
+ if (NULL != timer_handle) {
+ xTimerStart(timer_handle, 0);
+ } else {
+ printf("timer creation failed!.\n");
+ for (;;) {
+ ;
+ }
+ }
+}
+
+static err_t usbh_rndis_if_init(struct netif *netif)
+{
+ LWIP_ASSERT("netif != NULL", (netif != NULL));
+
+ netif->mtu = 1500;
+ netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP;
+ netif->state = NULL;
+ netif->name[0] = 'E';
+ netif->name[1] = 'X';
+ netif->output = etharp_output;
+ netif->linkoutput = usbh_rndis_linkoutput;
+ return ERR_OK;
+}
+
+void usbh_rndis_run(struct usbh_rndis *rndis_class)
+{
+ struct netif *netif = &g_rndis_netif;
+
+ netif->hwaddr_len = 6;
+ memcpy(netif->hwaddr, rndis_class->mac, 6);
+
+ IP4_ADDR(&rndis_class->ipaddr, 0, 0, 0, 0);
+ IP4_ADDR(&rndis_class->netmask, 0, 0, 0, 0);
+ IP4_ADDR(&rndis_class->gateway, 0, 0, 0, 0);
+
+ netif = netif_add(netif, &rndis_class->ipaddr, &rndis_class->netmask, &rndis_class->gateway, NULL, usbh_rndis_if_init, tcpip_input);
+ netif_set_default(netif);
+ while (!netif_is_up(netif)) {
+ }
+
+ timer_init(rndis_class);
+
+#if LWIP_DHCP
+ dhcp_start(netif);
+#endif
+}
+
+void usbh_rndis_stop(struct usbh_rndis *rndis_class)
+{
+ struct netif *netif = &g_rndis_netif;
+#if LWIP_DHCP
+ dhcp_stop(netif);
+ dhcp_cleanup(netif);
+#endif
+ netif_set_down(netif);
+ netif_remove(netif);
+
+ xTimerStop(timer_handle, 0);
+ xTimerDelete(timer_handle, 0);
+}
+#endif
+
void usbh_cdc_acm_run(struct usbh_cdc_acm *cdc_acm_class)
{
}
@@ -500,10 +576,14 @@ void usbh_class_test(void)
#error "if you want to use iso, please contact with me"
usb_osal_thread_create("usbh_video", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_video_thread, NULL);
#endif
-#if TEST_USBH_CDC_ECM
+#if TEST_USBH_CDC_ECM || TEST_USBH_RNDIS
/* Initialize the LwIP stack */
tcpip_init(NULL, NULL);
-
+#endif
+#if TEST_USBH_CDC_ECM
usbh_cdc_ecm_lwip_thread_init(&g_cdc_ecm_netif);
#endif
+#if TEST_USBH_RNDIS
+ usbh_rndis_lwip_thread_init(&g_rndis_netif);
+#endif
} \ No newline at end of file
diff --git a/port/dwc2/usb_hc_dwc2.c b/port/dwc2/usb_hc_dwc2.c
index 440c1139..d276fd19 100644
--- a/port/dwc2/usb_hc_dwc2.c
+++ b/port/dwc2/usb_hc_dwc2.c
@@ -30,24 +30,13 @@
#define USB_OTG_HC(i) ((USB_OTG_HostChannelTypeDef *)(USB_BASE + USB_OTG_HOST_CHANNEL_BASE + ((i)*USB_OTG_HOST_CHANNEL_SIZE)))
#define USB_OTG_FIFO(i) *(__IO uint32_t *)(USB_BASE + USB_OTG_FIFO_BASE + ((i)*USB_OTG_FIFO_SIZE))
-struct dwc2_pipe {
- uint8_t dev_addr;
- uint8_t ep_addr;
- uint8_t ep_type;
- uint8_t ep_interval;
- uint8_t speed;
- uint16_t ep_mps;
- uint8_t data_pid;
- uint8_t chidx;
- volatile uint8_t ep0_state;
+struct dwc2_chan {
+ uint8_t ep0_state;
uint16_t num_packets;
uint32_t xferlen;
+ uint8_t chidx;
bool inuse;
- uint32_t xfrd;
- int errorcode;
- volatile bool waiter;
usb_osal_sem_t waitsem;
- struct usbh_hubport *hport;
struct usbh_urb *urb;
uint32_t iso_frame_idx;
};
@@ -56,7 +45,7 @@ struct dwc2_hcd {
volatile bool port_csc;
volatile bool port_pec;
volatile bool port_occ;
- struct dwc2_pipe pipe_pool[CONFIG_USBHOST_PIPE_NUM];
+ struct dwc2_chan chan_pool[CONFIG_USBHOST_PIPE_NUM];
} g_dwc2_hcd;
#define DWC2_EP0_STATE_SETUP 0
@@ -173,7 +162,7 @@ static inline void dwc2_drivebus(uint8_t state)
}
}
-static void dwc2_pipe_init(uint8_t ch_num, uint8_t devaddr, uint8_t ep_addr, uint8_t ep_type, uint16_t ep_mps, uint8_t speed)
+static void dwc2_chan_init(uint8_t ch_num, uint8_t devaddr, uint8_t ep_addr, uint8_t ep_type, uint16_t ep_mps, uint8_t speed)
{
uint32_t regval;
@@ -236,7 +225,7 @@ static void dwc2_pipe_init(uint8_t ch_num, uint8_t devaddr, uint8_t ep_addr, uin
}
/* For IN channel HCTSIZ.XferSize is expected to be an integer multiple of ep_mps size.*/
-static inline void dwc2_pipe_transfer(uint8_t ch_num, uint8_t ep_addr, uint32_t *buf, uint32_t size, uint8_t num_packets, uint8_t pid)
+static inline void dwc2_chan_transfer(uint8_t ch_num, uint8_t ep_addr, uint32_t *buf, uint32_t size, uint8_t num_packets, uint8_t pid)
{
__IO uint32_t tmpreg;
uint8_t is_oddframe;
@@ -361,13 +350,13 @@ static inline uint32_t dwc2_get_glb_intstatus(void)
return tmpreg;
}
-static int dwc2_pipe_alloc(void)
+static int dwc2_chan_alloc(void)
{
int chidx;
for (chidx = 0; chidx < CONFIG_USBHOST_PIPE_NUM; chidx++) {
- if (!g_dwc2_hcd.pipe_pool[chidx].inuse) {
- g_dwc2_hcd.pipe_pool[chidx].inuse = true;
+ if (!g_dwc2_hcd.chan_pool[chidx].inuse) {
+ g_dwc2_hcd.chan_pool[chidx].inuse = true;
return chidx;
}
}
@@ -375,9 +364,9 @@ static int dwc2_pipe_alloc(void)
return -1;
}
-static void dwc2_pipe_free(struct dwc2_pipe *pipe)
+static void dwc2_chan_free(struct dwc2_chan *chan)
{
- pipe->inuse = false;
+ chan->inuse = false;
}
static uint8_t dwc2_calculate_packet_num(uint32_t input_size, uint8_t ep_addr, uint16_t ep_mps, uint32_t *output_size)
@@ -403,46 +392,60 @@ static uint8_t dwc2_calculate_packet_num(uint32_t input_size, uint8_t ep_addr, u
return num_packets;
}
-static void dwc2_control_pipe_init(struct dwc2_pipe *chan, struct usb_setup_packet *setup, uint8_t *buffer, uint32_t buflen)
+static void dwc2_control_urb_init(uint8_t chidx, struct usbh_urb *urb, struct usb_setup_packet *setup, uint8_t *buffer, uint32_t buflen)
{
+ struct dwc2_chan *chan;
+
+ chan = &g_dwc2_hcd.chan_pool[chidx];
+
if (chan->ep0_state == DWC2_EP0_STATE_SETUP) /* fill setup */
{
- chan->num_packets = dwc2_calculate_packet_num(8, 0x00, chan->ep_mps, &chan->xferlen);
- dwc2_pipe_init(chan->chidx, chan->dev_addr, 0x00, USB_ENDPOINT_TYPE_CONTROL, chan->ep_mps, chan->speed);
- dwc2_pipe_transfer(chan->chidx, 0x00, (uint32_t *)setup, chan->xferlen, chan->num_packets, HC_PID_SETUP);
+ chan->num_packets = dwc2_calculate_packet_num(8, 0x00, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
+ dwc2_chan_init(chidx, urb->hport->dev_addr, 0x00, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
+ dwc2_chan_transfer(chidx, 0x00, (uint32_t *)setup, chan->xferlen, chan->num_packets, HC_PID_SETUP);
} else if (chan->ep0_state == DWC2_EP0_STATE_INDATA) /* fill in data */
{
- chan->num_packets = dwc2_calculate_packet_num(setup->wLength, 0x80, chan->ep_mps, &chan->xferlen);
- dwc2_pipe_init(chan->chidx, chan->dev_addr, 0x80, USB_ENDPOINT_TYPE_CONTROL, chan->ep_mps, chan->speed);
- dwc2_pipe_transfer(chan->chidx, 0x80, (uint32_t *)buffer, chan->xferlen, chan->num_packets, HC_PID_DATA1);
+ chan->num_packets = dwc2_calculate_packet_num(setup->wLength, 0x80, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
+ dwc2_chan_init(chidx, urb->hport->dev_addr, 0x80, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
+ dwc2_chan_transfer(chidx, 0x80, (uint32_t *)buffer, chan->xferlen, chan->num_packets, HC_PID_DATA1);
} else if (chan->ep0_state == DWC2_EP0_STATE_OUTDATA) /* fill out data */
{
- chan->num_packets = dwc2_calculate_packet_num(setup->wLength, 0x00, chan->ep_mps, &chan->xferlen);
- dwc2_pipe_init(chan->chidx, chan->dev_addr, 0x00, USB_ENDPOINT_TYPE_CONTROL, chan->ep_mps, chan->speed);
- dwc2_pipe_transfer(chan->chidx, 0x00, (uint32_t *)buffer, chan->xferlen, chan->num_packets, HC_PID_DATA1);
+ chan->num_packets = dwc2_calculate_packet_num(setup->wLength, 0x00, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
+ dwc2_chan_init(chidx, urb->hport->dev_addr, 0x00, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
+ dwc2_chan_transfer(chidx, 0x00, (uint32_t *)buffer, chan->xferlen, chan->num_packets, HC_PID_DATA1);
} else if (chan->ep0_state == DWC2_EP0_STATE_INSTATUS) /* fill in status */
{
- chan->num_packets = dwc2_calculate_packet_num(0, 0x80, chan->ep_mps, &chan->xferlen);
- dwc2_pipe_init(chan->chidx, chan->dev_addr, 0x80, USB_ENDPOINT_TYPE_CONTROL, chan->ep_mps, chan->speed);
- dwc2_pipe_transfer(chan->chidx, 0x80, NULL, chan->xferlen, chan->num_packets, HC_PID_DATA1);
+ chan->num_packets = dwc2_calculate_packet_num(0, 0x80, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
+ dwc2_chan_init(chidx, urb->hport->dev_addr, 0x80, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
+ dwc2_chan_transfer(chidx, 0x80, NULL, chan->xferlen, chan->num_packets, HC_PID_DATA1);
} else if (chan->ep0_state == DWC2_EP0_STATE_OUTSTATUS) /* fill out status */
{
- chan->num_packets = dwc2_calculate_packet_num(0, 0x00, chan->ep_mps, &chan->xferlen);
- dwc2_pipe_init(chan->chidx, chan->dev_addr, 0x00, USB_ENDPOINT_TYPE_CONTROL, chan->ep_mps, chan->speed);
- dwc2_pipe_transfer(chan->chidx, 0x00, NULL, chan->xferlen, chan->num_packets, HC_PID_DATA1);
+ chan->num_packets = dwc2_calculate_packet_num(0, 0x00, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
+ dwc2_chan_init(chidx, urb->hport->dev_addr, 0x00, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
+ dwc2_chan_transfer(chidx, 0x00, NULL, chan->xferlen, chan->num_packets, HC_PID_DATA1);
}
}
-static void dwc2_bulk_intr_pipe_init(struct dwc2_pipe *chan, uint8_t *buffer, uint32_t buflen)
+static void dwc2_bulk_intr_urb_init(uint8_t chidx, struct usbh_urb *urb, uint8_t *buffer, uint32_t buflen)
{
- chan->num_packets = dwc2_calculate_packet_num(buflen, chan->ep_addr, chan->ep_mps, &chan->xferlen);
- dwc2_pipe_transfer(chan->chidx, chan->ep_addr, (uint32_t *)buffer, chan->xferlen, chan->num_packets, chan->data_pid);
+ struct dwc2_chan *chan;
+
+ chan = &g_dwc2_hcd.chan_pool[chidx];
+
+ chan->num_packets = dwc2_calculate_packet_num(buflen, urb->ep->bEndpointAddress, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
+ dwc2_chan_init(chidx, urb->hport->dev_addr, urb->ep->bEndpointAddress, USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes), USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
+ dwc2_chan_transfer(chidx, urb->ep->bEndpointAddress, (uint32_t *)buffer, chan->xferlen, chan->num_packets, urb->data_toggle);
}
-static void dwc2_iso_pipe_init(struct dwc2_pipe *chan, struct usbh_iso_frame_packet *iso_packet)
+static void dwc2_iso_urb_init(uint8_t chidx, struct usbh_urb *urb, struct usbh_iso_frame_packet *iso_packet)
{
- chan->num_packets = dwc2_calculate_packet_num(iso_packet->transfer_buffer_length, chan->ep_addr, chan->ep_mps, &chan->xferlen);
- dwc2_pipe_transfer(chan->chidx, chan->ep_addr, (uint32_t *)iso_packet->transfer_buffer, chan->xferlen, chan->num_packets, HC_PID_DATA0);
+ struct dwc2_chan *chan;
+
+ chan = &g_dwc2_hcd.chan_pool[chidx];
+
+ chan->num_packets = dwc2_calculate_packet_num(iso_packet->transfer_buffer_length, urb->ep->bEndpointAddress, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
+ dwc2_chan_init(chidx, urb->hport->dev_addr, urb->ep->bEndpointAddress, USB_ENDPOINT_TYPE_ISOCHRONOUS, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
+ dwc2_chan_transfer(chidx, urb->ep->bEndpointAddress, (uint32_t *)iso_packet->transfer_buffer, chan->xferlen, chan->num_packets, HC_PID_DATA0);
}
__WEAK void usb_hc_low_level_init(void)
@@ -456,7 +459,7 @@ int usb_hc_init(void)
memset(&g_dwc2_hcd, 0, sizeof(struct dwc2_hcd));
for (uint8_t chidx = 0; chidx < CONFIG_USBHOST_PIPE_NUM; chidx++) {
- g_dwc2_hcd.pipe_pool[chidx].waitsem = usb_osal_sem_create(0);
+ g_dwc2_hcd.chan_pool[chidx].waitsem = usb_osal_sem_create(0);
}
usb_hc_low_level_init();
@@ -681,137 +684,58 @@ int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf)
return 0;
}
-int usbh_ep_pipe_reconfigure(usbh_pipe_t pipe, uint8_t dev_addr, uint8_t ep_mps, uint8_t mult)
-{
- struct dwc2_pipe *chan;
-
- chan = (struct dwc2_pipe *)pipe;
-
- chan->dev_addr = dev_addr;
- chan->ep_mps = ep_mps;
-
- return 0;
-}
-
-int usbh_pipe_alloc(usbh_pipe_t *pipe, const struct usbh_endpoint_cfg *ep_cfg)
-{
- struct dwc2_pipe *chan;
- int chidx;
- usb_osal_sem_t waitsem;
-
- chidx = dwc2_pipe_alloc();
- if (chidx == -1) {
- return -ENOMEM;
- }
-
- chan = &g_dwc2_hcd.pipe_pool[chidx];
-
- /* store variables */
- waitsem = chan->waitsem;
-
- memset(chan, 0, sizeof(struct dwc2_pipe));
-
- chan->chidx = chidx;
- chan->ep_addr = ep_cfg->ep_addr;
- chan->ep_type = ep_cfg->ep_type;
- chan->ep_mps = ep_cfg->ep_mps;
- chan->ep_interval = ep_cfg->ep_interval;
- chan->speed = ep_cfg->hport->speed;
- chan->dev_addr = ep_cfg->hport->dev_addr;
- chan->hport = ep_cfg->hport;
-
- if (ep_cfg->ep_type == USB_ENDPOINT_TYPE_CONTROL) {
- chan->data_pid = HC_PID_DATA1;
- } else {
- dwc2_pipe_init(chidx, chan->dev_addr, ep_cfg->ep_addr, ep_cfg->ep_type, ep_cfg->ep_mps, chan->speed);
- chan->data_pid = HC_PID_DATA0;
- }
-
- if (chan->speed == USB_SPEED_HIGH) {
- chan->ep_interval = (1 << (chan->ep_interval - 1));
- }
-
- /* restore variables */
- chan->inuse = true;
- chan->waitsem = waitsem;
-
- *pipe = (usbh_pipe_t)chan;
-
- return 0;
-}
-
-int usbh_pipe_free(usbh_pipe_t pipe)
-{
- struct dwc2_pipe *chan;
- struct usbh_urb *urb;
-
- chan = (struct dwc2_pipe *)pipe;
-
- if (!chan) {
- return -EINVAL;
- }
-
- urb = chan->urb;
-
- if (urb) {
- usbh_kill_urb(urb);
- }
-
- dwc2_pipe_free(chan);
- return 0;
-}
-
int usbh_submit_urb(struct usbh_urb *urb)
{
- struct dwc2_pipe *pipe;
+ struct dwc2_chan *chan;
size_t flags;
int ret = 0;
+ int chidx;
- if (!urb || !urb->pipe) {
+ if (!urb || !urb->hport || !urb->ep) {
return -EINVAL;
}
- pipe = urb->pipe;
-
/* dma addr must be aligned 4 bytes */
if ((((uint32_t)urb->setup) & 0x03) || (((uint32_t)urb->transfer_buffer) & 0x03)) {
return -EINVAL;
}
- if (!(USB_OTG_HPRT & USB_OTG_HPRT_PCSTS) || !pipe->hport->connected) {
+ if (!(USB_OTG_HPRT & USB_OTG_HPRT_PCSTS) || !urb->hport->connected) {
return -ENODEV;
}
- if (pipe->urb) {
+ if (urb->errorcode == -EBUSY) {
return -EBUSY;
}
flags = usb_osal_enter_critical_section();
- pipe->waiter = false;
- pipe->xfrd = 0;
- pipe->urb = urb;
- pipe->errorcode = -EBUSY;
+ chidx = dwc2_chan_alloc();
+ if (chidx == -1) {
+ usb_osal_leave_critical_section(flags);
+ return -ENOMEM;
+ }
+
+ chan = &g_dwc2_hcd.chan_pool[chidx];
+ chan->chidx = chidx;
+ chan->urb = urb;
+
+ urb->hcpriv = chan;
urb->errorcode = -EBUSY;
urb->actual_length = 0;
- if (urb->timeout > 0) {
- pipe->waiter = true;
- }
usb_osal_leave_critical_section(flags);
- switch (pipe->ep_type) {
+ switch (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes)) {
case USB_ENDPOINT_TYPE_CONTROL:
- pipe->ep0_state = DWC2_EP0_STATE_SETUP;
- dwc2_control_pipe_init(pipe, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
+ chan->ep0_state = DWC2_EP0_STATE_SETUP;
+ dwc2_control_urb_init(chidx, urb, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
break;
case USB_ENDPOINT_TYPE_BULK:
case USB_ENDPOINT_TYPE_INTERRUPT:
- dwc2_bulk_intr_pipe_init(pipe, urb->transfer_buffer, urb->transfer_buffer_length);
+ dwc2_bulk_intr_urb_init(chidx, urb, urb->transfer_buffer, urb->transfer_buffer_length);
break;
case USB_ENDPOINT_TYPE_ISOCHRONOUS:
- pipe->iso_frame_idx = 0;
- dwc2_iso_pipe_init(pipe, &urb->iso_packet[pipe->iso_frame_idx]);
break;
default:
break;
@@ -819,41 +743,44 @@ int usbh_submit_urb(struct usbh_urb *urb)
if (urb->timeout > 0) {
/* wait until timeout or sem give */
- ret = usb_osal_sem_take(pipe->waitsem, urb->timeout);
+ ret = usb_osal_sem_take(chan->waitsem, urb->timeout);
if (ret < 0) {
goto errout_timeout;
}
-
+ urb->timeout = 0;
ret = urb->errorcode;
}
return ret;
errout_timeout:
- pipe->waiter = false;
usbh_kill_urb(urb);
return ret;
}
int usbh_kill_urb(struct usbh_urb *urb)
{
- struct dwc2_pipe *pipe;
+ struct dwc2_chan *chan;
size_t flags;
- pipe = urb->pipe;
-
- if (!urb || !pipe) {
+ if (!urb || !urb->hcpriv) {
return -EINVAL;
}
flags = usb_osal_enter_critical_section();
- dwc2_halt(pipe->chidx);
- CLEAR_HC_INT(pipe->chidx, USB_OTG_HCINT_CHH);
- pipe->urb = NULL;
+ chan = (struct dwc2_chan *)urb->hcpriv;
- if (pipe->waiter) {
- pipe->waiter = false;
+ dwc2_halt(chan->chidx);
+ CLEAR_HC_INT(chan->chidx, USB_OTG_HCINT_CHH);
+
+ chan->urb = NULL;
+ urb->hcpriv = NULL;
+
+ dwc2_chan_free(chan);
+
+ if (urb->timeout) {
+ urb->timeout = 0;
urb->errorcode = -ESHUTDOWN;
- usb_osal_sem_give(pipe->waitsem);
+ usb_osal_sem_give(chan->waitsem);
}
usb_osal_leave_critical_section(flags);
@@ -861,16 +788,19 @@ int usbh_kill_urb(struct usbh_urb *urb)
return 0;
}
-static inline void dwc2_pipe_waitup(struct dwc2_pipe *pipe)
+static inline void dwc2_urb_waitup(struct usbh_urb *urb)
{
- struct usbh_urb *urb;
+ struct dwc2_chan *chan;
+
+ chan = (struct dwc2_chan *)urb->hcpriv;
+ chan->urb = NULL;
+ urb->hcpriv = NULL;
- urb = pipe->urb;
- pipe->urb = NULL;
+ dwc2_chan_free(chan);
- if (pipe->waiter) {
- pipe->waiter = false;
- usb_osal_sem_give(pipe->waitsem);
+ if (urb->timeout) {
+ urb->timeout = 0;
+ usb_osal_sem_give(chan->waitsem);
}
if (urb->complete) {
@@ -885,214 +815,191 @@ static inline void dwc2_pipe_waitup(struct dwc2_pipe *pipe)
static void dwc2_inchan_irq_handler(uint8_t ch_num)
{
uint32_t chan_intstatus;
- struct dwc2_pipe *chan;
+ struct dwc2_chan *chan;
struct usbh_urb *urb;
chan_intstatus = (USB_OTG_HC(ch_num)->HCINT) & (USB_OTG_HC((uint32_t)ch_num)->HCINTMSK);
- chan = &g_dwc2_hcd.pipe_pool[ch_num];
+ chan = &g_dwc2_hcd.chan_pool[ch_num];
urb = chan->urb;
//printf("s1:%08x\r\n", chan_intstatus);
if ((chan_intstatus & USB_OTG_HCINT_XFRC) == USB_OTG_HCINT_XFRC) {
- chan->errorcode = 0;
+ urb->errorcode = 0;
USB_UNMASK_HALT_HC_INT(ch_num);
dwc2_halt(ch_num);
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_XFRC);
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
} else if ((chan_intstatus & USB_OTG_HCINT_AHBERR) == USB_OTG_HCINT_AHBERR) {
- chan->errorcode = -EIO;
+ urb->errorcode = -EIO;
USB_UNMASK_HALT_HC_INT(ch_num);
dwc2_halt(ch_num);
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_AHBERR);
} else if ((chan_intstatus & USB_OTG_HCINT_STALL) == USB_OTG_HCINT_STALL) {
- chan->errorcode = -EPERM;
+ urb->errorcode = -EPERM;
USB_UNMASK_HALT_HC_INT(ch_num);
dwc2_halt(ch_num);
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_STALL);
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
} else if ((chan_intstatus & USB_OTG_HCINT_NAK) == USB_OTG_HCINT_NAK) {
- chan->errorcode = -EAGAIN;
+ urb->errorcode = -EAGAIN;
USB_UNMASK_HALT_HC_INT(ch_num);
dwc2_halt(ch_num);
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
} else if ((chan_intstatus & USB_OTG_HCINT_ACK) == USB_OTG_HCINT_ACK) {
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_ACK);
} else if ((chan_intstatus & USB_OTG_HCINT_NYET) == USB_OTG_HCINT_NYET) {
- chan->errorcode = -EAGAIN;
+ urb->errorcode = -EAGAIN;
USB_UNMASK_HALT_HC_INT(ch_num);
dwc2_halt(ch_num);
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NYET);
} else if ((chan_intstatus & USB_OTG_HCINT_TXERR) == USB_OTG_HCINT_TXERR) {
- chan->errorcode = -EIO;
+ urb->errorcode = -EIO;
USB_UNMASK_HALT_HC_INT(ch_num);
dwc2_halt(ch_num);
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_TXERR);
} else if ((chan_intstatus & USB_OTG_HCINT_BBERR) == USB_OTG_HCINT_BBERR) {
- chan->errorcode = -EIO;
+ urb->errorcode = -EIO;
USB_UNMASK_HALT_HC_INT(ch_num);
dwc2_halt(ch_num);
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_BBERR);
} else if ((chan_intstatus & USB_OTG_HCINT_FRMOR) == USB_OTG_HCINT_FRMOR) {
- chan->errorcode = -EPIPE;
+ urb->errorcode = -EPIPE;
USB_UNMASK_HALT_HC_INT(ch_num);
dwc2_halt(ch_num);
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_FRMOR);
} else if ((chan_intstatus & USB_OTG_HCINT_DTERR) == USB_OTG_HCINT_DTERR) {
- chan->errorcode = -EIO;
+ urb->errorcode = -EIO;
USB_UNMASK_HALT_HC_INT(ch_num);
dwc2_halt(ch_num);
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_DTERR);
} else if ((chan_intstatus & USB_OTG_HCINT_CHH) == USB_OTG_HCINT_CHH) {
USB_MASK_HALT_HC_INT(ch_num);
-
- if (urb == NULL) {
- goto chhout;
- }
-
- urb->errorcode = chan->errorcode;
+ CLEAR_HC_INT(ch_num, USB_OTG_HCINT_CHH);
if (urb->errorcode == 0) {
uint32_t count = chan->xferlen - (USB_OTG_HC(ch_num)->HCTSIZ & USB_OTG_HCTSIZ_XFRSIZ); /* how many size has received */
uint32_t has_used_packets = chan->num_packets - ((USB_OTG_HC(ch_num)->HCTSIZ & USB_OTG_DIEPTSIZ_PKTCNT) >> 19); /* how many packets have used */
- chan->xfrd += count;
+ urb->actual_length += count;
if ((has_used_packets % 2) == 1) /* toggle in odd numbers */
{
- if (chan->data_pid == HC_PID_DATA0) {
- chan->data_pid = HC_PID_DATA1;
+ if (urb->data_toggle == HC_PID_DATA0) {
+ urb->data_toggle = HC_PID_DATA1;
} else {
- chan->data_pid = HC_PID_DATA0;
+ urb->data_toggle = HC_PID_DATA0;
}
}
- if (chan->ep_type == 0x00) {
+ if (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_CONTROL) {
if (chan->ep0_state == DWC2_EP0_STATE_INDATA) {
chan->ep0_state = DWC2_EP0_STATE_OUTSTATUS;
- dwc2_control_pipe_init(chan, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
+ dwc2_control_urb_init(ch_num, urb, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
} else if (chan->ep0_state == DWC2_EP0_STATE_INSTATUS) {
chan->ep0_state = DWC2_EP0_STATE_SETUP;
- urb->actual_length = chan->xfrd;
- dwc2_pipe_waitup(chan);
- }
- } else if (chan->ep_type == USB_ENDPOINT_TYPE_ISOCHRONOUS) {
- urb->iso_packet[chan->iso_frame_idx].actual_length = chan->xfrd;
- urb->iso_packet[chan->iso_frame_idx].errorcode = urb->errorcode;
- chan->iso_frame_idx++;
-
- if (chan->iso_frame_idx == urb->num_of_iso_packets) {
- dwc2_pipe_waitup(chan);
- } else {
- dwc2_iso_pipe_init(chan, &urb->iso_packet[chan->iso_frame_idx]);
+ dwc2_urb_waitup(urb);
}
+ } else if (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_ISOCHRONOUS) {
} else {
- urb->actual_length = chan->xfrd;
- dwc2_pipe_waitup(chan);
+ dwc2_urb_waitup(urb);
}
} else if (urb->errorcode == -EAGAIN) {
/* re-activate the channel */
- if (chan->ep_type == 0x00) {
- dwc2_control_pipe_init(chan, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
- } else if ((chan->ep_type == 0x03) || (chan->ep_type == 0x02)) {
- dwc2_bulk_intr_pipe_init(chan, urb->transfer_buffer, urb->transfer_buffer_length);
+ if (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_CONTROL) {
+ dwc2_control_urb_init(ch_num, urb, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
+ } else if ((USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_BULK) || (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_INTERRUPT)) {
+ dwc2_bulk_intr_urb_init(ch_num, urb, urb->transfer_buffer, urb->transfer_buffer_length);
} else {
}
} else {
- dwc2_pipe_waitup(chan);
+ dwc2_urb_waitup(urb);
}
- chhout:
- CLEAR_HC_INT(ch_num, USB_OTG_HCINT_CHH);
}
}
static void dwc2_outchan_irq_handler(uint8_t ch_num)
{
uint32_t chan_intstatus;
- struct dwc2_pipe *chan;
+ struct dwc2_chan *chan;
struct usbh_urb *urb;
uint16_t buflen;
chan_intstatus = (USB_OTG_HC(ch_num)->HCINT) & (USB_OTG_HC((uint32_t)ch_num)->HCINTMSK);
- chan = &g_dwc2_hcd.pipe_pool[ch_num];
+ chan = &g_dwc2_hcd.chan_pool[ch_num];
urb = chan->urb;
//printf("s2:%08x\r\n", chan_intstatus);
if ((chan_intstatus & USB_OTG_HCINT_XFRC) == USB_OTG_HCINT_XFRC) {
- chan->errorcode = 0;
+ urb->errorcode = 0;
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_XFRC);
dwc2_halt(ch_num);
USB_UNMASK_HALT_HC_INT(ch_num);
} else if ((chan_intstatus & USB_OTG_HCINT_AHBERR) == USB_OTG_HCINT_AHBERR) {
- chan->errorcode = -EIO;
+ urb->errorcode = -EIO;
USB_UNMASK_HALT_HC_INT(ch_num);
dwc2_halt(ch_num);
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_AHBERR);
} else if ((chan_intstatus & USB_OTG_HCINT_STALL) == USB_OTG_HCINT_STALL) {
- chan->errorcode = -EPERM;
+ urb->errorcode = -EPERM;
USB_UNMASK_HALT_HC_INT(ch_num);
dwc2_halt(ch_num);
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_STALL);
} else if ((chan_intstatus & USB_OTG_HCINT_NAK) == USB_OTG_HCINT_NAK) {
- chan->errorcode = -EAGAIN;
+ urb->errorcode = -EAGAIN;
USB_UNMASK_HALT_HC_INT(ch_num);
dwc2_halt(ch_num);
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
} else if ((chan_intstatus & USB_OTG_HCINT_ACK) == USB_OTG_HCINT_ACK) {
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_ACK);
} else if ((chan_intstatus & USB_OTG_HCINT_NYET) == USB_OTG_HCINT_NYET) {
- chan->errorcode = -EAGAIN;
+ urb->errorcode = -EAGAIN;
USB_UNMASK_HALT_HC_INT(ch_num);
dwc2_halt(ch_num);
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NYET);
} else if ((chan_intstatus & USB_OTG_HCINT_TXERR) == USB_OTG_HCINT_TXERR) {
- chan->errorcode = -EIO;
+ urb->errorcode = -EIO;
USB_UNMASK_HALT_HC_INT(ch_num);
dwc2_halt(ch_num);
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_TXERR);
} else if ((chan_intstatus & USB_OTG_HCINT_BBERR) == USB_OTG_HCINT_BBERR) {
- chan->errorcode = -EIO;
+ urb->errorcode = -EIO;
USB_UNMASK_HALT_HC_INT(ch_num);
dwc2_halt(ch_num);
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_BBERR);
} else if ((chan_intstatus & USB_OTG_HCINT_FRMOR) == USB_OTG_HCINT_FRMOR) {
- chan->errorcode = -EPIPE;
+ urb->errorcode = -EPIPE;
USB_UNMASK_HALT_HC_INT(ch_num);
dwc2_halt(ch_num);
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_FRMOR);
} else if ((chan_intstatus & USB_OTG_HCINT_DTERR) == USB_OTG_HCINT_DTERR) {
- chan->errorcode = -EIO;
+ urb->errorcode = -EIO;
USB_UNMASK_HALT_HC_INT(ch_num);
dwc2_halt(ch_num);
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_DTERR);
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
} else if ((chan_intstatus & USB_OTG_HCINT_CHH) == USB_OTG_HCINT_CHH) {
USB_MASK_HALT_HC_INT(ch_num);
-
- if (urb == NULL) {
- goto chhout;
- }
-
- urb->errorcode = chan->errorcode;
+ CLEAR_HC_INT(ch_num, USB_OTG_HCINT_CHH);
if (urb->errorcode == 0) {
uint32_t count = USB_OTG_HC(ch_num)->HCTSIZ & USB_OTG_HCTSIZ_XFRSIZ; /* how many size has sent */
uint32_t has_used_packets = chan->num_packets - ((USB_OTG_HC(ch_num)->HCTSIZ & USB_OTG_DIEPTSIZ_PKTCNT) >> 19); /* how many packets have used */
- chan->xfrd += count;
+ urb->actual_length += count;
if (has_used_packets % 2) /* toggle in odd numbers */
{
- if (chan->data_pid == HC_PID_DATA0) {
- chan->data_pid = HC_PID_DATA1;
+ if (urb->data_toggle == HC_PID_DATA0) {
+ urb->data_toggle = HC_PID_DATA1;
} else {
- chan->data_pid = HC_PID_DATA0;
+ urb->data_toggle = HC_PID_DATA0;
}
}
- if (chan->ep_type == 0x00) {
+ if (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_CONTROL) {
if (chan->ep0_state == DWC2_EP0_STATE_SETUP) {
if (urb->setup->wLength) {
if (urb->setup->bmRequestType & 0x80) {
@@ -1103,42 +1010,29 @@ static void dwc2_outchan_irq_handler(uint8_t ch_num)
} else {
chan->ep0_state = DWC2_EP0_STATE_INSTATUS;
}
- dwc2_control_pipe_init(chan, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
+ dwc2_control_urb_init(ch_num, urb, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
} else if (chan->ep0_state == DWC2_EP0_STATE_OUTDATA) {
chan->ep0_state = DWC2_EP0_STATE_INSTATUS;
- dwc2_control_pipe_init(chan, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
+ dwc2_control_urb_init(ch_num, urb, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
} else if (chan->ep0_state == DWC2_EP0_STATE_OUTSTATUS) {
chan->ep0_state = DWC2_EP0_STATE_SETUP;
- urb->actual_length = chan->xfrd;
- dwc2_pipe_waitup(chan);
- }
- } else if (chan->ep_type == USB_ENDPOINT_TYPE_ISOCHRONOUS) {
- urb->iso_packet[chan->iso_frame_idx].actual_length = chan->xfrd;
- urb->iso_packet[chan->iso_frame_idx].errorcode = urb->errorcode;
- chan->iso_frame_idx++;
-
- if (chan->iso_frame_idx == urb->num_of_iso_packets) {
- dwc2_pipe_waitup(chan);
- } else {
- dwc2_iso_pipe_init(chan, &urb->iso_packet[chan->iso_frame_idx]);
+ dwc2_urb_waitup(urb);
}
+ } else if (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_ISOCHRONOUS) {
} else {
- urb->actual_length = chan->xfrd;
- dwc2_pipe_waitup(chan);
+ dwc2_urb_waitup(urb);
}
} else if (urb->errorcode == -EAGAIN) {
/* re-activate the channel */
- if (chan->ep_type == 0x00) {
- dwc2_control_pipe_init(chan, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
- } else if ((chan->ep_type == 0x03) || (chan->ep_type == 0x02)) {
- dwc2_bulk_intr_pipe_init(chan, urb->transfer_buffer, urb->transfer_buffer_length);
+ if (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_CONTROL) {
+ dwc2_control_urb_init(ch_num, urb, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
+ } else if ((USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_BULK) || (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_INTERRUPT)) {
+ dwc2_bulk_intr_urb_init(ch_num, urb, urb->transfer_buffer, urb->transfer_buffer_length);
} else {
}
} else {
- dwc2_pipe_waitup(chan);
+ dwc2_urb_waitup(urb);
}
- chhout:
- CLEAR_HC_INT(ch_num, USB_OTG_HCINT_CHH);
}
}
diff --git a/port/ehci/usb_ehci_priv.h b/port/ehci/usb_ehci_priv.h
index ce968401..5348872c 100644
--- a/port/ehci/usb_ehci_priv.h
+++ b/port/ehci/usb_ehci_priv.h
@@ -33,34 +33,12 @@
extern uint8_t usbh_get_port_speed(const uint8_t port);
-struct ehci_qh_hw;
-struct ehci_itd_hw;
-struct ehci_pipe {
- uint8_t dev_addr;
- uint8_t ep_addr;
- uint8_t ep_type;
- uint8_t ep_interval;
- uint8_t speed;
- uint8_t mult;
- uint16_t ep_mps;
- bool toggle;
- bool inuse;
- uint32_t xfrd;
- bool waiter;
- usb_osal_sem_t waitsem;
- struct usbh_hubport *hport;
- struct usbh_urb *urb;
- uint8_t mf_unmask;
- uint8_t mf_valid;
- uint8_t iso_packet_idx;
- uint8_t remain_itd_num;
-};
-
struct ehci_qh_hw {
struct ehci_qh hw;
uint32_t first_qtd;
struct usbh_urb *urb;
uint8_t remove_in_iaad;
+ usb_osal_sem_t waitsem;
} __attribute__((aligned(32)));
struct ehci_qtd_hw {
@@ -72,8 +50,10 @@ struct ehci_qtd_hw {
struct ehci_itd_hw {
struct ehci_itd hw;
struct usbh_urb *urb;
- struct ehci_pipe *pipe;
uint16_t start_frame;
+ uint8_t mf_unmask;
+ uint8_t mf_valid;
+ uint32_t pkt_idx[8];
usb_slist_t list;
} __attribute__((aligned(32)));
@@ -81,14 +61,13 @@ struct ehci_hcd {
bool ehci_qh_used[CONFIG_USB_EHCI_QH_NUM];
bool ehci_qtd_used[CONFIG_USB_EHCI_QTD_NUM];
bool ehci_itd_used[CONFIG_USB_EHCI_ITD_NUM];
- struct ehci_pipe pipe_pool[CONFIG_USB_EHCI_QH_NUM];
};
extern struct ehci_hcd g_ehci_hcd;
extern uint32_t g_framelist[];
-int ehci_iso_pipe_init(struct ehci_pipe *pipe, struct usbh_urb *urb);
+int ehci_iso_urb_init(struct usbh_urb *urb);
void ehci_remove_itd_urb(struct usbh_urb *urb);
void ehci_scan_isochronous_list(void);
-#endif \ No newline at end of file
+#endif
diff --git a/port/ehci/usb_hc_ehci.c b/port/ehci/usb_hc_ehci.c
index 7e6e9469..a37226c4 100644
--- a/port/ehci/usb_hc_ehci.c
+++ b/port/ehci/usb_hc_ehci.c
@@ -27,6 +27,7 @@ USB_NOCACHE_RAM_SECTION uint32_t g_framelist[CONFIG_USB_EHCI_FRAME_LIST_SIZE] __
static struct ehci_qh_hw *ehci_qh_alloc(void)
{
struct ehci_qh_hw *qh;
+ usb_osal_sem_t waitsem;
size_t flags;
for (uint32_t i = 0; i < CONFIG_USB_EHCI_QH_NUM; i++) {
@@ -36,10 +37,12 @@ static struct ehci_qh_hw *ehci_qh_alloc(void)
usb_osal_leave_critical_section(flags);
qh = &ehci_qh_pool[i];
+ waitsem = qh->waitsem;
memset(qh, 0, sizeof(struct ehci_qh_hw));
qh->hw.hlp = QTD_LIST_END;
qh->hw.overlay.next_qtd = QTD_LIST_END;
qh->hw.overlay.alt_next_qtd = QTD_LIST_END;
+ qh->waitsem = waitsem;
return qh;
}
}
@@ -100,24 +103,6 @@ static void ehci_qtd_free(struct ehci_qtd_hw *qtd)
}
}
-static struct ehci_pipe *ehci_pipe_alloc(void)
-{
- int pipe;
-
- for (pipe = 0; pipe < CONFIG_USB_EHCI_QH_NUM; pipe++) {
- if (!g_ehci_hcd.pipe_pool[pipe].inuse) {
- g_ehci_hcd.pipe_pool[pipe].inuse = true;
- return &g_ehci_hcd.pipe_pool[pipe];
- }
- }
- return NULL;
-}
-
-static void ehci_pipe_free(struct ehci_pipe *pipe)
-{
- pipe->inuse = false;
-}
-
static inline void ehci_qh_add_head(struct ehci_qh_hw *head, struct ehci_qh_hw *n)
{
n->hw.hlp = head->hw.hlp;
@@ -312,7 +297,7 @@ static void ehci_qtd_fill(struct ehci_qtd_hw *qtd, uint32_t bufaddr, size_t bufl
qtd->total_len = buflen;
}
-static struct ehci_qh_hw *ehci_control_pipe_init(struct ehci_pipe *pipe, struct usb_setup_packet *setup, uint8_t *buffer, uint32_t buflen)
+static struct ehci_qh_hw *ehci_control_urb_init(struct usbh_urb *urb, struct usb_setup_packet *setup, uint8_t *buffer, uint32_t buflen)
{
struct ehci_qh_hw *qh = NULL;
struct ehci_qtd_hw *qtd_setup = NULL;
@@ -344,15 +329,15 @@ static struct ehci_qh_hw *ehci_control_pipe_init(struct ehci_pipe *pipe, struct
}
ehci_qh_fill(qh,
- pipe->dev_addr,
- pipe->ep_addr,
- pipe->ep_type,
- pipe->ep_mps,
+ urb->hport->dev_addr,
+ urb->ep->bEndpointAddress,
+ USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes),
+ USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize),
+ 0,
0,
- pipe->ep_interval,
- pipe->hport->speed,
- pipe->hport->parent->hub_addr,
- pipe->hport->port);
+ urb->hport->speed,
+ urb->hport->parent->hub_addr,
+ urb->hport->port);
/* fill setup qtd */
token = QTD_TOKEN_STATUS_ACTIVE |
@@ -361,7 +346,7 @@ static struct ehci_qh_hw *ehci_control_pipe_init(struct ehci_pipe *pipe, struct
((uint32_t)8 << QTD_TOKEN_NBYTES_SHIFT);
ehci_qtd_fill(qtd_setup, (uintptr_t)setup, 8, token);
- qtd_setup->urb = pipe->urb;
+ qtd_setup->urb = urb;
/* fill data qtd */
if (setup->wLength > 0) {
@@ -377,7 +362,7 @@ static struct ehci_qh_hw *ehci_control_pipe_init(struct ehci_pipe *pipe, struct
((uint32_t)buflen << QTD_TOKEN_NBYTES_SHIFT);
ehci_qtd_fill(qtd_data, (uintptr_t)buffer, buflen, token);
- qtd_data->urb = pipe->urb;
+ qtd_data->urb = urb;
qtd_setup->hw.next_qtd = EHCI_PTR2ADDR(qtd_data);
qtd_data->hw.next_qtd = EHCI_PTR2ADDR(qtd_status);
} else {
@@ -397,7 +382,7 @@ static struct ehci_qh_hw *ehci_control_pipe_init(struct ehci_pipe *pipe, struct
((uint32_t)0 << QTD_TOKEN_NBYTES_SHIFT);
ehci_qtd_fill(qtd_status, 0, 0, token);
- qtd_status->urb = pipe->urb;
+ qtd_status->urb = urb;
qtd_status->hw.next_qtd = QTD_LIST_END;
/* update qh first qtd */
@@ -409,7 +394,8 @@ static struct ehci_qh_hw *ehci_control_pipe_init(struct ehci_pipe *pipe, struct
flags = usb_osal_enter_critical_section();
- qh->urb = pipe->urb;
+ qh->urb = urb;
+ urb->hcpriv = qh;
/* add qh into async list */
ehci_qh_add_head(&g_async_qh_head, qh);
@@ -419,7 +405,7 @@ static struct ehci_qh_hw *ehci_control_pipe_init(struct ehci_pipe *pipe, struct
return qh;
}
-static struct ehci_qh_hw *ehci_bulk_pipe_init(struct ehci_pipe *pipe, uint8_t *buffer, uint32_t buflen)
+static struct ehci_qh_hw *ehci_bulk_urb_init(struct usbh_urb *urb, uint8_t *buffer, uint32_t buflen)
{
struct ehci_qh_hw *qh = NULL;
struct ehci_qtd_hw *qtd = NULL;
@@ -447,15 +433,15 @@ static struct ehci_qh_hw *ehci_bulk_pipe_init(struct ehci_pipe *pipe, uint8_t *b
}
ehci_qh_fill(qh,
- pipe->dev_addr,
- pipe->ep_addr,
- pipe->ep_type,
- pipe->ep_mps,
+ urb->hport->dev_addr,
+ urb->ep->bEndpointAddress,
+ USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes),
+ USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize),
0,
- pipe->ep_interval,
- pipe->hport->speed,
- pipe->hport->parent->hub_addr,
- pipe->hport->port);
+ 0,
+ urb->hport->speed,
+ urb->hport->parent->hub_addr,
+ urb->hport->port);
while (buflen >= 0) {
qtd = ehci_qtd_alloc();
@@ -468,7 +454,7 @@ static struct ehci_qh_hw *ehci_bulk_pipe_init(struct ehci_pipe *pipe, uint8_t *b
buflen = 0;
}
- if (pipe->ep_addr & 0x80) {
+ if (urb->ep->bEndpointAddress & 0x80) {
token = QTD_TOKEN_PID_IN;
} else {
token = QTD_TOKEN_PID_OUT;
@@ -483,7 +469,7 @@ static struct ehci_qh_hw *ehci_bulk_pipe_init(struct ehci_pipe *pipe, uint8_t *b
}
ehci_qtd_fill(qtd, (uintptr_t)buffer, xfer_len, token);
- qtd->urb = pipe->urb;
+ qtd->urb = urb;
qtd->hw.next_qtd = QTD_LIST_END;
buffer += xfer_len;
@@ -504,7 +490,7 @@ static struct ehci_qh_hw *ehci_bulk_pipe_init(struct ehci_pipe *pipe, uint8_t *b
qh->hw.overlay.next_qtd = EHCI_PTR2ADDR(first_qtd);
/* update data toggle */
- if (pipe->toggle) {
+ if (urb->data_toggle) {
qh->hw.overlay.token = QTD_TOKEN_TOGGLE;
} else {
qh->hw.overlay.token = 0;
@@ -515,7 +501,8 @@ static struct ehci_qh_hw *ehci_bulk_pipe_init(struct ehci_pipe *pipe, uint8_t *b
flags = usb_osal_enter_critical_section();
- qh->urb = pipe->urb;
+ qh->urb = urb;
+ urb->hcpriv = qh;
/* add qh into async list */
ehci_qh_add_head(&g_async_qh_head, qh);
@@ -525,7 +512,7 @@ static struct ehci_qh_hw *ehci_bulk_pipe_init(struct ehci_pipe *pipe, uint8_t *b
return qh;
}
-static struct ehci_qh_hw *ehci_intr_pipe_init(struct ehci_pipe *pipe, uint8_t *buffer, uint32_t buflen)
+static struct ehci_qh_hw *ehci_intr_urb_init(struct usbh_urb *urb, uint8_t *buffer, uint32_t buflen)
{
struct ehci_qh_hw *qh = NULL;
struct ehci_qtd_hw *qtd = NULL;
@@ -553,15 +540,15 @@ static struct ehci_qh_hw *ehci_intr_pipe_init(struct ehci_pipe *pipe, uint8_t *b
}
ehci_qh_fill(qh,
- pipe->dev_addr,
- pipe->ep_addr,
- pipe->ep_type,
- pipe->ep_mps,
- pipe->mult + 1,
- pipe->ep_interval,
- pipe->hport->speed,
- pipe->hport->parent->hub_addr,
- pipe->hport->port);
+ urb->hport->dev_addr,
+ urb->ep->bEndpointAddress,
+ USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes),
+ USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize),
+ USB_GET_MULT(urb->ep->wMaxPacketSize) + 1,
+ urb->ep->bInterval,
+ urb->hport->speed,
+ urb->hport->parent->hub_addr,
+ urb->hport->port);
while (buflen >= 0) {
qtd = ehci_qtd_alloc();
@@ -574,7 +561,7 @@ static struct ehci_qh_hw *ehci_intr_pipe_init(struct ehci_pipe *pipe, uint8_t *b
buflen = 0;
}
- if (pipe->ep_addr & 0x80) {
+ if (urb->ep->bEndpointAddress & 0x80) {
token = QTD_TOKEN_PID_IN;
} else {
token = QTD_TOKEN_PID_OUT;
@@ -589,7 +576,7 @@ static struct ehci_qh_hw *ehci_intr_pipe_init(struct ehci_pipe *pipe, uint8_t *b
}
ehci_qtd_fill(qtd, (uintptr_t)buffer, xfer_len, token);
- qtd->urb = pipe->urb;
+ qtd->urb = urb;
qtd->hw.next_qtd = QTD_LIST_END;
buffer += xfer_len;
@@ -610,7 +597,7 @@ static struct ehci_qh_hw *ehci_intr_pipe_init(struct ehci_pipe *pipe, uint8_t *b
qh->hw.overlay.next_qtd = EHCI_PTR2ADDR(first_qtd);
/* update data toggle */
- if (pipe->toggle) {
+ if (urb->data_toggle) {
qh->hw.overlay.token = QTD_TOKEN_TOGGLE;
} else {
qh->hw.overlay.token = 0;
@@ -621,12 +608,13 @@ static struct ehci_qh_hw *ehci_intr_pipe_init(struct ehci_pipe *pipe, uint8_t *b
flags = usb_osal_enter_critical_section();
- qh->urb = pipe->urb;
+ qh->urb = urb;
+ urb->hcpriv = qh;
/* add qh into periodic list */
- if (pipe->speed == USB_SPEED_HIGH) {
- ehci_qh_add_head(ehci_get_periodic_qhead(pipe->ep_interval), qh);
+ if (urb->hport->speed == USB_SPEED_HIGH) {
+ ehci_qh_add_head(ehci_get_periodic_qhead(urb->ep->bInterval), qh);
} else {
- ehci_qh_add_head(ehci_get_periodic_qhead(pipe->ep_interval * 8), qh);
+ ehci_qh_add_head(ehci_get_periodic_qhead(urb->ep->bInterval * 8), qh);
}
EHCI_HCOR->usbcmd |= EHCI_USBCMD_PSEN;
@@ -635,16 +623,20 @@ static struct ehci_qh_hw *ehci_intr_pipe_init(struct ehci_pipe *pipe, uint8_t *b
return qh;
}
-void ehci_pipe_waitup(struct ehci_pipe *pipe)
+static void ehci_urb_waitup(struct usbh_urb *urb)
{
- struct usbh_urb *urb;
+ struct ehci_qh_hw *qh;
+
+ qh = (struct ehci_qh_hw *)urb->hcpriv;
+ qh->urb = NULL;
+ urb->hcpriv = NULL;
- urb = pipe->urb;
- pipe->urb = NULL;
+ qh->remove_in_iaad = 0;
+ ehci_qh_free(qh);
- if (pipe->waiter) {
- pipe->waiter = false;
- usb_osal_sem_give(pipe->waitsem);
+ if (urb->timeout) {
+ urb->timeout = 0;
+ usb_osal_sem_give(qh->waitsem);
}
if (urb->complete) {
@@ -676,7 +668,6 @@ static void ehci_qh_scan_qtds(struct ehci_qh_hw *qhead, struct ehci_qh_hw *qh)
static void ehci_check_qh(struct ehci_qh_hw *qhead, struct ehci_qh_hw *qh)
{
struct usbh_urb *urb;
- struct ehci_pipe *pipe;
struct ehci_qtd_hw *qtd;
uint32_t token;
@@ -688,31 +679,30 @@ static void ehci_check_qh(struct ehci_qh_hw *qhead, struct ehci_qh_hw *qh)
}
urb = qh->urb;
- pipe = urb->pipe;
if ((token & QTD_TOKEN_STATUS_ERRORS) == 0) {
- qtd = EHCI_ADDR2QTD(qh->first_qtd);
+ qtd = EHCI_ADDR2QTD(qh->first_qtd);
- while (qtd) {
- if (qtd->hw.token & QTD_TOKEN_STATUS_ACTIVE) {
- return;
- }
- qtd = EHCI_ADDR2QTD(qtd->hw.next_qtd);
- }
+ while (qtd) {
+ if ((qtd->hw.token & QTD_TOKEN_STATUS_ACTIVE) == QTD_TOKEN_STATUS_ACTIVE) {
+ return;
+ }
+ qtd = EHCI_ADDR2QTD(qtd->hw.next_qtd);
+ }
if (token & QTD_TOKEN_TOGGLE) {
- pipe->toggle = true;
+ urb->data_toggle = true;
} else {
- pipe->toggle = false;
+ urb->data_toggle = false;
}
urb->errorcode = 0;
} else {
if (token & QTD_TOKEN_STATUS_BABBLE) {
urb->errorcode = -EPERM;
- pipe->toggle = 0;
+ urb->data_toggle = 0;
} else if (token & QTD_TOKEN_STATUS_HALTED) {
urb->errorcode = -EPERM;
- pipe->toggle = 0;
+ urb->data_toggle = 0;
} else if (token & (QTD_TOKEN_STATUS_DBERR | QTD_TOKEN_STATUS_XACTERR)) {
urb->errorcode = -EIO;
}
@@ -720,10 +710,8 @@ static void ehci_check_qh(struct ehci_qh_hw *qhead, struct ehci_qh_hw *qh)
ehci_qh_scan_qtds(qhead, qh);
- if (pipe->ep_type == USB_ENDPOINT_TYPE_INTERRUPT) {
- qh->remove_in_iaad = 0;
- ehci_qh_free(qh);
- ehci_pipe_waitup(pipe);
+ if (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_INTERRUPT) {
+ ehci_urb_waitup(urb);
} else {
qh->remove_in_iaad = 1;
@@ -806,10 +794,8 @@ int usb_hc_init(void)
}
for (uint8_t index = 0; index < CONFIG_USB_EHCI_QH_NUM; index++) {
- struct ehci_pipe *pipe;
-
- pipe = &g_ehci_hcd.pipe_pool[index];
- pipe->waitsem = usb_osal_sem_create(0);
+ qh = &ehci_qh_pool[index];
+ qh->waitsem = usb_osal_sem_create(0);
}
memset(&g_async_qh_head, 0, sizeof(struct ehci_qh_hw));
@@ -1068,144 +1054,57 @@ int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf)
return 0;
}
-int usbh_ep_pipe_reconfigure(usbh_pipe_t pipe, uint8_t dev_addr, uint8_t ep_mps, uint8_t mult)
-{
- struct ehci_pipe *ppipe = (struct ehci_pipe *)pipe;
-
- ppipe->dev_addr = dev_addr;
- ppipe->ep_mps = ep_mps;
- ppipe->mult = mult;
-
- return 0;
-}
-
-int usbh_pipe_alloc(usbh_pipe_t *pipe, const struct usbh_endpoint_cfg *ep_cfg)
-{
- struct ehci_pipe *ppipe;
- usb_osal_sem_t waitsem;
-
- ppipe = ehci_pipe_alloc();
- if (ppipe == NULL) {
- return -ENOMEM;
- }
-
- /* store variables */
- waitsem = ppipe->waitsem;
-
- memset(ppipe, 0, sizeof(struct ehci_pipe));
-
- ppipe->ep_addr = ep_cfg->ep_addr;
- ppipe->ep_type = ep_cfg->ep_type;
- ppipe->ep_mps = ep_cfg->ep_mps;
- ppipe->ep_interval = ep_cfg->ep_interval;
- ppipe->mult = ep_cfg->mult;
- ppipe->speed = ep_cfg->hport->speed;
- ppipe->dev_addr = ep_cfg->hport->dev_addr;
- ppipe->hport = ep_cfg->hport;
-
-#ifdef CONFIG_USB_EHCI_ISO
- if ((ppipe->speed == USB_SPEED_HIGH) && (ppipe->ep_type == USB_ENDPOINT_TYPE_ISOCHRONOUS)) {
- if (ep_cfg->ep_interval == 0x01) { /* transfer interval 1 mf */
- ppipe->mf_unmask = 0xff;
- ppipe->mf_valid = 8;
- } else if (ep_cfg->ep_interval == 0x02) { /* transfer interval 2 mf */
- ppipe->mf_unmask = 0x55;
- ppipe->mf_valid = 4;
- } else if (ep_cfg->ep_interval == 0x03) { /* transfer interval 4 mf */
- ppipe->mf_unmask = 0x44;
- ppipe->mf_valid = 2;
- } else if (ep_cfg->ep_interval == 0x04) { /* transfer interval 8 mf */
- ppipe->mf_unmask = 0x01;
- ppipe->mf_valid = 1;
- }
- }
-#endif
- /* restore variable */
- ppipe->inuse = true;
- ppipe->waitsem = waitsem;
-
- *pipe = (usbh_pipe_t)ppipe;
-
- return 0;
-}
-
-int usbh_pipe_free(usbh_pipe_t pipe)
-{
- struct usbh_urb *urb;
- struct ehci_pipe *ppipe;
-
- ppipe = (struct ehci_pipe *)pipe;
-
- if (!ppipe) {
- return -EINVAL;
- }
-
- urb = ppipe->urb;
-
- if (urb) {
- usbh_kill_urb(urb);
- }
-
- ehci_pipe_free(ppipe);
- return 0;
-}
-
int usbh_submit_urb(struct usbh_urb *urb)
{
- struct ehci_pipe *pipe;
struct ehci_qh_hw *qh = NULL;
size_t flags;
int ret = 0;
- if (!urb || !urb->pipe) {
+ if (!urb || !urb->hport || !urb->ep) {
return -EINVAL;
}
- pipe = urb->pipe;
-
- if (!pipe->inuse /*|| !(EHCI_HCOR->portsc[pipe->hport->port-1] & EHCI_PORTSC_CCS)*/ || !pipe->hport->connected) {
+ if (!urb->hport->connected) {
return -ENODEV;
}
- if (pipe->urb && (pipe->ep_type != USB_ENDPOINT_TYPE_ISOCHRONOUS)) {
+ if ((urb->errorcode == -EBUSY) && (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) != USB_ENDPOINT_TYPE_ISOCHRONOUS)) {
return -EBUSY;
}
flags = usb_osal_enter_critical_section();
- pipe->waiter = false;
- pipe->xfrd = 0;
- pipe->urb = urb;
+ urb->hcpriv = NULL;
urb->errorcode = -EBUSY;
urb->actual_length = 0;
- if (urb->timeout > 0) {
- pipe->waiter = true;
- }
usb_osal_leave_critical_section(flags);
- switch (pipe->ep_type) {
+ switch (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes)) {
case USB_ENDPOINT_TYPE_CONTROL:
- qh = ehci_control_pipe_init(pipe, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
+ qh = ehci_control_urb_init(urb, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
if (qh == NULL) {
return -ENOMEM;
}
+ urb->hcpriv = qh;
break;
case USB_ENDPOINT_TYPE_BULK:
- qh = ehci_bulk_pipe_init(pipe, urb->transfer_buffer, urb->transfer_buffer_length);
+ qh = ehci_bulk_urb_init(urb, urb->transfer_buffer, urb->transfer_buffer_length);
if (qh == NULL) {
return -ENOMEM;
}
+ urb->hcpriv = qh;
break;
case USB_ENDPOINT_TYPE_INTERRUPT:
- qh = ehci_intr_pipe_init(pipe, urb->transfer_buffer, urb->transfer_buffer_length);
+ qh = ehci_intr_urb_init(urb, urb->transfer_buffer, urb->transfer_buffer_length);
if (qh == NULL) {
return -ENOMEM;
}
+ urb->hcpriv = qh;
break;
case USB_ENDPOINT_TYPE_ISOCHRONOUS:
#ifdef CONFIG_USB_EHCI_ISO
- ehci_iso_pipe_init(pipe, urb);
+ ret = ehci_iso_urb_init(urb);
#endif
break;
default:
@@ -1214,34 +1113,26 @@ int usbh_submit_urb(struct usbh_urb *urb)
if (urb->timeout > 0) {
/* wait until timeout or sem give */
- ret = usb_osal_sem_take(pipe->waitsem, urb->timeout);
+ ret = usb_osal_sem_take(qh->waitsem, urb->timeout);
if (ret < 0) {
goto errout_timeout;
}
+ urb->timeout = 0;
ret = urb->errorcode;
}
return ret;
errout_timeout:
/* Timeout will run here */
- pipe->waiter = false;
usbh_kill_urb(urb);
return ret;
}
int usbh_kill_urb(struct usbh_urb *urb)
{
- struct ehci_pipe *pipe;
- struct ehci_qh_hw *qh = NULL;
-
+ struct ehci_qh_hw *qh;
size_t flags;
- if (!urb) {
- return -EINVAL;
- }
-
- pipe = urb->pipe;
-
- if (!pipe) {
+ if (!urb || !urb->hcpriv) {
return -EINVAL;
}
@@ -1249,7 +1140,7 @@ int usbh_kill_urb(struct usbh_urb *urb)
EHCI_HCOR->usbcmd &= ~(EHCI_USBCMD_PSEN | EHCI_USBCMD_ASEN);
- if ((pipe->ep_type == USB_ENDPOINT_TYPE_CONTROL) || (pipe->ep_type == USB_ENDPOINT_TYPE_BULK)) {
+ if ((USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_CONTROL) || (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_BULK)) {
qh = EHCI_ADDR2QH(g_async_qh_head.hw.hlp);
while ((qh != &g_async_qh_head) && qh) {
if (qh->urb == urb) {
@@ -1257,14 +1148,14 @@ int usbh_kill_urb(struct usbh_urb *urb)
}
qh = EHCI_ADDR2QH(qh->hw.hlp);
}
- } else if (pipe->ep_type == USB_ENDPOINT_TYPE_INTERRUPT) {
+ } else if (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_INTERRUPT) {
qh = EHCI_ADDR2QH(g_periodic_qh_head[EHCI_PERIOIDIC_QH_NUM - 1].hw.hlp);
while (qh) {
if (qh->urb == urb) {
- if (pipe->speed == USB_SPEED_HIGH) {
- ehci_kill_qh(ehci_get_periodic_qhead(pipe->ep_interval), qh);
+ if (urb->hport->speed == USB_SPEED_HIGH) {
+ ehci_kill_qh(ehci_get_periodic_qhead(urb->ep->bInterval), qh);
} else {
- ehci_kill_qh(ehci_get_periodic_qhead(pipe->ep_interval * 8), qh);
+ ehci_kill_qh(ehci_get_periodic_qhead(urb->ep->bInterval * 8), qh);
}
}
qh = EHCI_ADDR2QH(qh->hw.hlp);
@@ -1277,12 +1168,14 @@ int usbh_kill_urb(struct usbh_urb *urb)
EHCI_HCOR->usbcmd |= (EHCI_USBCMD_PSEN | EHCI_USBCMD_ASEN);
- pipe->urb = NULL;
+ qh = (struct ehci_qh_hw *)urb->hcpriv;
+ urb->hcpriv = NULL;
+ qh->urb = NULL;
- if (pipe->waiter) {
- pipe->waiter = false;
+ if (urb->timeout) {
+ urb->timeout = 0;
urb->errorcode = -ESHUTDOWN;
- usb_osal_sem_give(pipe->waitsem);
+ usb_osal_sem_give(qh->waitsem);
}
usb_osal_leave_critical_section(flags);
@@ -1306,16 +1199,14 @@ static void ehci_scan_async_list(void)
static void ehci_scan_periodic_list(void)
{
struct ehci_qh_hw *qh;
- struct ehci_pipe *pipe;
qh = EHCI_ADDR2QH(g_periodic_qh_head[EHCI_PERIOIDIC_QH_NUM - 1].hw.hlp);
while (qh) {
- if (qh->urb && qh->urb->pipe) {
- pipe = (struct ehci_pipe *)qh->urb->pipe;
- if (pipe->speed == USB_SPEED_HIGH) {
- ehci_check_qh(ehci_get_periodic_qhead(pipe->ep_interval), qh);
+ if (qh->urb) {
+ if (qh->urb->hport->speed == USB_SPEED_HIGH) {
+ ehci_check_qh(ehci_get_periodic_qhead(qh->urb->ep->bInterval), qh);
} else {
- ehci_check_qh(ehci_get_periodic_qhead(pipe->ep_interval * 8), qh);
+ ehci_check_qh(ehci_get_periodic_qhead(qh->urb->ep->bInterval * 8), qh);
}
}
qh = EHCI_ADDR2QH(qh->hw.hlp);
@@ -1372,16 +1263,7 @@ void USBH_IRQHandler(void)
for (uint8_t index = 0; index < CONFIG_USB_EHCI_QH_NUM; index++) {
struct ehci_qh_hw *qh = &ehci_qh_pool[index];
if (g_ehci_hcd.ehci_qh_used[index] && qh->remove_in_iaad) {
- struct usbh_urb *urb;
- struct ehci_pipe *pipe;
-
- urb = qh->urb;
- pipe = urb->pipe;
-
- qh->remove_in_iaad = 0;
- ehci_qh_free(qh);
-
- ehci_pipe_waitup(pipe);
+ ehci_urb_waitup(qh->urb);
}
}
}
diff --git a/port/musb/usb_hc_musb.c b/port/musb/usb_hc_musb.c
index d5cd7da4..f19f3264 100644
--- a/port/musb/usb_hc_musb.c
+++ b/port/musb/usb_hc_musb.c
@@ -151,17 +151,10 @@ typedef enum {
} ep0_state_t;
struct musb_pipe {
- uint8_t dev_addr;
- uint8_t ep_addr;
- uint8_t ep_type;
- uint8_t ep_interval;
- uint8_t speed;
- uint16_t ep_mps;
+ uint8_t chidx;
bool inuse;
uint32_t xfrd;
- volatile bool waiter;
usb_osal_sem_t waitsem;
- struct usbh_hubport *hport;
struct usbh_urb *urb;
};
@@ -169,7 +162,7 @@ struct musb_hcd {
volatile bool port_csc;
volatile bool port_pec;
volatile bool port_pe;
- struct musb_pipe pipe_pool[CONFIG_USBHOST_PIPE_NUM][2]; /* Support Bidirectional ep */
+ struct musb_pipe pipe_pool[CONFIG_USBHOST_PIPE_NUM];
} g_musb_hcd;
static volatile uint8_t usb_ep0_state = USB_EP0_STATE_SETUP;
@@ -265,88 +258,115 @@ static void musb_read_packet(uint8_t ep_idx, uint8_t *buffer, uint16_t len)
}
}
-void musb_control_pipe_init(struct musb_pipe *pipe, struct usb_setup_packet *setup, uint8_t *buffer, uint32_t buflen)
+void musb_control_urb_init(uint8_t chidx, struct usbh_urb *urb, struct usb_setup_packet *setup, uint8_t *buffer, uint32_t buflen)
{
uint8_t old_ep_index;
+ uint8_t speed;
old_ep_index = musb_get_active_ep();
- musb_set_active_ep(0);
+ musb_set_active_ep(chidx);
- HWREGB(USB_TXADDR_BASE(0)) = pipe->dev_addr;
- HWREGB(USB_BASE + MUSB_IND_TXTYPE_OFFSET) = pipe->speed;
- HWREGB(USB_TXHUBADDR_BASE(0)) = 0;
- HWREGB(USB_TXHUBPORT_BASE(0)) = 0;
+ if (urb->hport->speed == USB_SPEED_HIGH) {
+ speed = USB_TYPE0_SPEED_HIGH;
+ } else if (urb->hport->speed == USB_SPEED_FULL) {
+ speed = USB_TYPE0_SPEED_FULL;
+ } else if (urb->hport->speed == USB_SPEED_LOW) {
+ speed = USB_TYPE0_SPEED_LOW;
+ }
- musb_write_packet(0, (uint8_t *)setup, 8);
+ HWREGB(USB_TXADDR_BASE(chidx)) = urb->hport->dev_addr;
+ HWREGB(USB_BASE + MUSB_IND_TXTYPE_OFFSET) = speed;
+ HWREGB(USB_TXHUBADDR_BASE(chidx)) = 0;
+ HWREGB(USB_TXHUBPORT_BASE(chidx)) = 0;
+
+ musb_write_packet(chidx, (uint8_t *)setup, 8);
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_CSRL0_TXRDY | USB_CSRL0_SETUP;
musb_set_active_ep(old_ep_index);
}
-void musb_bulk_pipe_init(struct musb_pipe *pipe, uint8_t *buffer, uint32_t buflen)
+void musb_bulk_urb_init(uint8_t chidx, struct usbh_urb *urb, uint8_t *buffer, uint32_t buflen)
{
- uint8_t ep_idx;
uint8_t old_ep_index;
+ uint8_t speed;
- ep_idx = pipe->ep_addr & 0x7f;
old_ep_index = musb_get_active_ep();
- musb_set_active_ep(ep_idx);
+ musb_set_active_ep(chidx);
- if (pipe->ep_addr & 0x80) {
- HWREGB(USB_RXADDR_BASE(ep_idx)) = pipe->dev_addr;
- HWREGB(USB_BASE + MUSB_IND_RXTYPE_OFFSET) = ep_idx | pipe->speed | USB_TXTYPE1_PROTO_BULK;
+ if (urb->hport->speed == USB_SPEED_HIGH) {
+ speed = USB_TXTYPE1_SPEED_HIGH;
+ } else if (urb->hport->speed == USB_SPEED_FULL) {
+ speed = USB_TXTYPE1_SPEED_FULL;
+ } else if (urb->hport->speed == USB_SPEED_LOW) {
+ speed = USB_TXTYPE1_SPEED_LOW;
+ }
+
+ if (urb->ep->bEndpointAddress & 0x80) {
+ HWREGB(USB_RXADDR_BASE(chidx)) = urb->hport->dev_addr;
+ HWREGB(USB_BASE + MUSB_IND_RXTYPE_OFFSET) = chidx | speed | USB_TXTYPE1_PROTO_BULK;
HWREGB(USB_BASE + MUSB_IND_RXINTERVAL_OFFSET) = 0;
- HWREGB(USB_RXHUBADDR_BASE(ep_idx)) = 0;
- HWREGB(USB_RXHUBPORT_BASE(ep_idx)) = 0;
+ HWREGB(USB_RXHUBADDR_BASE(chidx)) = 0;
+ HWREGB(USB_RXHUBPORT_BASE(chidx)) = 0;
HWREGB(USB_BASE + MUSB_IND_TXCSRH_OFFSET) &= ~USB_TXCSRH1_MODE;
HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) = USB_RXCSRL1_REQPKT;
+
+ HWREGH(USB_BASE + MUSB_RXIE_OFFSET) |= (1 << chidx);
} else {
- HWREGB(USB_TXADDR_BASE(ep_idx)) = pipe->dev_addr;
- HWREGB(USB_BASE + MUSB_IND_TXTYPE_OFFSET) = ep_idx | pipe->speed | USB_TXTYPE1_PROTO_BULK;
+ HWREGB(USB_TXADDR_BASE(chidx)) = urb->hport->dev_addr;
+ HWREGB(USB_BASE + MUSB_IND_TXTYPE_OFFSET) = chidx | speed | USB_TXTYPE1_PROTO_BULK;
HWREGB(USB_BASE + MUSB_IND_TXINTERVAL_OFFSET) = 0;
- HWREGB(USB_TXHUBADDR_BASE(ep_idx)) = 0;
- HWREGB(USB_TXHUBPORT_BASE(ep_idx)) = 0;
+ HWREGB(USB_TXHUBADDR_BASE(chidx)) = 0;
+ HWREGB(USB_TXHUBPORT_BASE(chidx)) = 0;
- if (buflen > pipe->ep_mps) {
- buflen = pipe->ep_mps;
+ if (buflen > USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize)) {
+ buflen = USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize);
}
- musb_write_packet(ep_idx, buffer, buflen);
+ musb_write_packet(chidx, buffer, buflen);
HWREGB(USB_BASE + MUSB_IND_TXCSRH_OFFSET) &= ~USB_TXCSRH1_MODE;
HWREGB(USB_BASE + MUSB_IND_TXCSRH_OFFSET) |= USB_TXCSRH1_MODE;
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_TXCSRL1_TXRDY;
+
+ HWREGH(USB_BASE + MUSB_TXIE_OFFSET) |= (1 << chidx);
}
musb_set_active_ep(old_ep_index);
}
-void musb_intr_pipe_init(struct musb_pipe *pipe, uint8_t *buffer, uint32_t buflen)
+void musb_intr_urb_init(uint8_t chidx, struct usbh_urb *urb, uint8_t *buffer, uint32_t buflen)
{
- uint8_t ep_idx;
uint8_t old_ep_index;
+ uint8_t speed;
- ep_idx = pipe->ep_addr & 0x7f;
old_ep_index = musb_get_active_ep();
- musb_set_active_ep(ep_idx);
+ musb_set_active_ep(chidx);
- if (pipe->ep_addr & 0x80) {
- HWREGB(USB_RXADDR_BASE(ep_idx)) = pipe->dev_addr;
- HWREGB(USB_BASE + MUSB_IND_RXTYPE_OFFSET) = ep_idx | pipe->speed | USB_TXTYPE1_PROTO_INT;
- HWREGB(USB_BASE + MUSB_IND_RXINTERVAL_OFFSET) = pipe->ep_interval;
- HWREGB(USB_RXHUBADDR_BASE(ep_idx)) = 0;
- HWREGB(USB_RXHUBPORT_BASE(ep_idx)) = 0;
+ if (urb->hport->speed == USB_SPEED_HIGH) {
+ speed = USB_TXTYPE1_SPEED_HIGH;
+ } else if (urb->hport->speed == USB_SPEED_FULL) {
+ speed = USB_TXTYPE1_SPEED_FULL;
+ } else if (urb->hport->speed == USB_SPEED_LOW) {
+ speed = USB_TXTYPE1_SPEED_LOW;
+ }
+
+ if (urb->ep->bEndpointAddress & 0x80) {
+ HWREGB(USB_RXADDR_BASE(chidx)) = urb->hport->dev_addr;
+ HWREGB(USB_BASE + MUSB_IND_RXTYPE_OFFSET) = chidx | speed | USB_TXTYPE1_PROTO_INT;
+ HWREGB(USB_BASE + MUSB_IND_RXINTERVAL_OFFSET) = urb->ep->bInterval;
+ HWREGB(USB_RXHUBADDR_BASE(chidx)) = 0;
+ HWREGB(USB_RXHUBPORT_BASE(chidx)) = 0;
HWREGB(USB_BASE + MUSB_IND_TXCSRH_OFFSET) &= ~USB_TXCSRH1_MODE;
HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) = USB_RXCSRL1_REQPKT;
} else {
- HWREGB(USB_TXADDR_BASE(ep_idx)) = pipe->dev_addr;
- HWREGB(USB_BASE + MUSB_IND_TXTYPE_OFFSET) = ep_idx | pipe->speed | USB_TXTYPE1_PROTO_INT;
- HWREGB(USB_BASE + MUSB_IND_TXINTERVAL_OFFSET) = pipe->ep_interval;
- HWREGB(USB_TXHUBADDR_BASE(ep_idx)) = 0;
- HWREGB(USB_TXHUBPORT_BASE(ep_idx)) = 0;
+ HWREGB(USB_TXADDR_BASE(chidx)) = urb->hport->dev_addr;
+ HWREGB(USB_BASE + MUSB_IND_TXTYPE_OFFSET) = chidx | speed | USB_TXTYPE1_PROTO_INT;
+ HWREGB(USB_BASE + MUSB_IND_TXINTERVAL_OFFSET) = urb->ep->bInterval;
+ HWREGB(USB_TXHUBADDR_BASE(chidx)) = 0;
+ HWREGB(USB_TXHUBPORT_BASE(chidx)) = 0;
- if (buflen > pipe->ep_mps) {
- buflen = pipe->ep_mps;
+ if (buflen > USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize)) {
+ buflen = USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize);
}
- musb_write_packet(ep_idx, buffer, buflen);
+ musb_write_packet(chidx, buffer, buflen);
HWREGB(USB_BASE + MUSB_IND_TXCSRH_OFFSET) &= ~USB_TXCSRH1_MODE;
HWREGB(USB_BASE + MUSB_IND_TXCSRH_OFFSET) |= USB_TXCSRH1_MODE;
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_TXCSRL1_TXRDY;
@@ -379,6 +399,25 @@ static uint8_t usbh_get_port_speed(const uint8_t port)
return speed;
}
+static int musb_pipe_alloc(void)
+{
+ int chidx;
+
+ for (chidx = 1; chidx < CONFIG_USBHOST_PIPE_NUM; chidx++) {
+ if (!g_musb_hcd.pipe_pool[chidx].inuse) {
+ g_musb_hcd.pipe_pool[chidx].inuse = true;
+ return chidx;
+ }
+ }
+
+ return -1;
+}
+
+static void musb_pipe_free(struct musb_pipe *pipe)
+{
+ pipe->inuse = false;
+}
+
__WEAK void usb_hc_low_level_init(void)
{
}
@@ -391,8 +430,7 @@ int usb_hc_init(void)
memset(&g_musb_hcd, 0, sizeof(struct musb_hcd));
for (uint8_t i = 0; i < CONFIG_USBHOST_PIPE_NUM; i++) {
- g_musb_hcd.pipe_pool[i][0].waitsem = usb_osal_sem_create(0);
- g_musb_hcd.pipe_pool[i][1].waitsem = usb_osal_sem_create(0);
+ g_musb_hcd.pipe_pool[i].waitsem = usb_osal_sem_create(0);
}
usb_hc_low_level_init();
@@ -551,150 +589,53 @@ int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf)
return 0;
}
-int usbh_ep_pipe_reconfigure(usbh_pipe_t pipe, uint8_t dev_addr, uint8_t ep_mps, uint8_t mult)
-{
- struct musb_pipe *ppipe = (struct musb_pipe *)pipe;
-
- ppipe->dev_addr = dev_addr;
- ppipe->ep_mps = ep_mps;
-
- return 0;
-}
-
-int usbh_pipe_alloc(usbh_pipe_t *pipe, const struct usbh_endpoint_cfg *ep_cfg)
-{
- struct musb_pipe *ppipe;
- uint8_t old_ep_index;
- uint8_t ep_idx;
- usb_osal_sem_t waitsem;
-
- ep_idx = ep_cfg->ep_addr & 0x7f;
-
- if (ep_idx > CONIFG_USB_MUSB_PIPE_NUM) {
- return -ENOMEM;
- }
-
- old_ep_index = musb_get_active_ep();
- musb_set_active_ep(ep_idx);
-
- if (ep_cfg->ep_addr & 0x80) {
- ppipe = &g_musb_hcd.pipe_pool[ep_idx][1];
- } else {
- ppipe = &g_musb_hcd.pipe_pool[ep_idx][0];
- }
-
- /* store variables */
- waitsem = ppipe->waitsem;
-
- memset(ppipe, 0, sizeof(struct musb_pipe));
-
- ppipe->ep_addr = ep_cfg->ep_addr;
- ppipe->ep_type = ep_cfg->ep_type;
- ppipe->ep_mps = ep_cfg->ep_mps;
- ppipe->ep_interval = ep_cfg->ep_interval;
- ppipe->speed = ep_cfg->hport->speed;
- ppipe->dev_addr = ep_cfg->hport->dev_addr;
- ppipe->hport = ep_cfg->hport;
-
- if (ep_cfg->ep_type == USB_ENDPOINT_TYPE_CONTROL) {
- if (ppipe->speed == USB_SPEED_HIGH) {
- ppipe->speed = USB_TYPE0_SPEED_HIGH;
- } else if (ppipe->speed == USB_SPEED_FULL) {
- ppipe->speed = USB_TYPE0_SPEED_FULL;
- } else if (ppipe->speed == USB_SPEED_LOW) {
- ppipe->speed = USB_TYPE0_SPEED_LOW;
- }
- } else {
- if (ppipe->speed == USB_SPEED_HIGH) {
- ppipe->speed = USB_TXTYPE1_SPEED_HIGH;
- } else if (ppipe->speed == USB_SPEED_FULL) {
- ppipe->speed = USB_TXTYPE1_SPEED_FULL;
- } else if (ppipe->speed == USB_SPEED_LOW) {
- ppipe->speed = USB_TXTYPE1_SPEED_LOW;
- }
-
- if (ppipe->ep_addr & 0x80) {
- HWREGH(USB_BASE + MUSB_RXIE_OFFSET) |= (1 << ep_idx);
- } else {
- HWREGH(USB_BASE + MUSB_TXIE_OFFSET) |= (1 << ep_idx);
- }
- }
- /* restore variable */
- ppipe->inuse = true;
- ppipe->waitsem = waitsem;
-
- musb_set_active_ep(old_ep_index);
- *pipe = (usbh_pipe_t)ppipe;
- return 0;
-}
-
-int usbh_pipe_free(usbh_pipe_t pipe)
-{
- struct musb_pipe *ppipe;
- struct usbh_urb *urb;
-
- ppipe = (struct musb_pipe *)pipe;
-
- if (!ppipe) {
- return -EINVAL;
- }
-
- urb = ppipe->urb;
-
- if (urb) {
- usbh_kill_urb(urb);
- }
-
- return 0;
-}
-
int usbh_submit_urb(struct usbh_urb *urb)
{
struct musb_pipe *pipe;
+ int chidx;
size_t flags;
int ret = 0;
- if (!urb) {
+ if (!urb || !urb->hport || !urb->ep) {
return -EINVAL;
}
- pipe = urb->pipe;
-
- if (!pipe) {
- return -EINVAL;
- }
-
- if (!pipe->hport->connected) {
+ if (!urb->hport->connected) {
return -ENODEV;
}
- if (pipe->urb) {
+ if (urb->errorcode == -EBUSY) {
return -EBUSY;
}
flags = usb_osal_enter_critical_section();
- pipe->waiter = false;
- pipe->xfrd = 0;
+ chidx = musb_pipe_alloc();
+ if (chidx == -1) {
+ usb_osal_leave_critical_section(flags);
+ return -ENOMEM;
+ }
+
+ pipe = &g_musb_hcd.pipe_pool[chidx];
+ pipe->chidx = chidx;
pipe->urb = urb;
+
+ urb->hcpriv = pipe;
urb->errorcode = -EBUSY;
urb->actual_length = 0;
- if (urb->timeout > 0) {
- pipe->waiter = true;
- }
usb_osal_leave_critical_section(flags);
- switch (pipe->ep_type) {
+ switch (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes)) {
case USB_ENDPOINT_TYPE_CONTROL:
usb_ep0_state = USB_EP0_STATE_SETUP;
- musb_control_pipe_init(pipe, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
+ musb_control_urb_init(0, urb, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
break;
case USB_ENDPOINT_TYPE_BULK:
- musb_bulk_pipe_init(pipe, urb->transfer_buffer, urb->transfer_buffer_length);
+ musb_bulk_urb_init(chidx, urb, urb->transfer_buffer, urb->transfer_buffer_length);
break;
case USB_ENDPOINT_TYPE_INTERRUPT:
- musb_intr_pipe_init(pipe, urb->transfer_buffer, urb->transfer_buffer_length);
+ musb_intr_urb_init(chidx, urb, urb->transfer_buffer, urb->transfer_buffer_length);
break;
case USB_ENDPOINT_TYPE_ISOCHRONOUS:
break;
@@ -707,12 +648,11 @@ int usbh_submit_urb(struct usbh_urb *urb)
if (ret < 0) {
goto errout_timeout;
}
-
+ urb->timeout = 0;
ret = urb->errorcode;
}
return ret;
errout_timeout:
- pipe->waiter = false;
usbh_kill_urb(urb);
return ret;
}
@@ -720,31 +660,42 @@ errout_timeout:
int usbh_kill_urb(struct usbh_urb *urb)
{
struct musb_pipe *pipe;
+ size_t flags;
- pipe = urb->pipe;
-
- if (!urb || !pipe) {
+ if (!urb || !urb->hcpriv) {
return -EINVAL;
}
- if (pipe->waiter) {
- pipe->waiter = false;
+ flags = usb_osal_enter_critical_section();
+
+ pipe = (struct musb_pipe *)urb->hcpriv;
+ urb->hcpriv = NULL;
+ pipe->urb = NULL;
+
+ musb_pipe_free(pipe);
+
+ if (urb->timeout) {
+ urb->timeout = 0;
urb->errorcode = -ESHUTDOWN;
usb_osal_sem_give(pipe->waitsem);
}
+ usb_osal_leave_critical_section(flags);
return 0;
}
-static inline void musb_pipe_waitup(struct musb_pipe *pipe)
+static void musb_urb_waitup(struct usbh_urb *urb)
{
- struct usbh_urb *urb;
+ struct musb_pipe *pipe;
- urb = pipe->urb;
+ pipe = (struct musb_pipe *)urb->hcpriv;
pipe->urb = NULL;
+ urb->hcpriv = NULL;
- if (pipe->waiter) {
- pipe->waiter = false;
+ musb_pipe_free(pipe);
+
+ if (urb->timeout) {
+ urb->timeout = 0;
usb_osal_sem_give(pipe->waitsem);
}
@@ -764,7 +715,7 @@ void handle_ep0(void)
struct usbh_urb *urb;
uint32_t size;
- pipe = (struct musb_pipe *)&g_musb_hcd.pipe_pool[0][0];
+ pipe = (struct musb_pipe *)&g_musb_hcd.pipe_pool[0];
urb = pipe->urb;
if (urb == NULL) {
return;
@@ -776,7 +727,7 @@ void handle_ep0(void)
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~USB_CSRL0_STALLED;
usb_ep0_state = USB_EP0_STATE_SETUP;
urb->errorcode = -EPERM;
- musb_pipe_waitup(pipe);
+ musb_urb_waitup(urb);
return;
}
if (ep0_status & USB_CSRL0_ERROR) {
@@ -784,14 +735,14 @@ void handle_ep0(void)
musb_fifo_flush(0);
usb_ep0_state = USB_EP0_STATE_SETUP;
urb->errorcode = -EIO;
- musb_pipe_waitup(pipe);
+ musb_urb_waitup(urb);
return;
}
if (ep0_status & USB_CSRL0_STALL) {
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~USB_CSRL0_STALL;
usb_ep0_state = USB_EP0_STATE_SETUP;
urb->errorcode = -EPERM;
- musb_pipe_waitup(pipe);
+ musb_urb_waitup(urb);
return;
}
@@ -805,8 +756,8 @@ void handle_ep0(void)
} else {
usb_ep0_state = USB_EP0_STATE_OUT_DATA;
size = urb->transfer_buffer_length;
- if (size > pipe->ep_mps) {
- size = pipe->ep_mps;
+ if (size > USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize)) {
+ size = USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize);
}
musb_write_packet(0, urb->transfer_buffer, size);
@@ -824,8 +775,8 @@ void handle_ep0(void)
case USB_EP0_STATE_IN_DATA:
if (ep0_status & USB_CSRL0_RXRDY) {
size = urb->transfer_buffer_length;
- if (size > pipe->ep_mps) {
- size = pipe->ep_mps;
+ if (size > USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize)) {
+ size = USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize);
}
size = MIN(size, HWREGH(USB_BASE + MUSB_IND_RXCOUNT_OFFSET));
@@ -835,7 +786,7 @@ void handle_ep0(void)
urb->transfer_buffer_length -= size;
urb->actual_length += size;
- if ((size < pipe->ep_mps) || (urb->transfer_buffer_length == 0)) {
+ if ((size < USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize)) || (urb->transfer_buffer_length == 0)) {
usb_ep0_state = USB_EP0_STATE_OUT_STATUS;
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = (USB_CSRL0_TXRDY | USB_CSRL0_STATUS);
} else {
@@ -846,8 +797,8 @@ void handle_ep0(void)
case USB_EP0_STATE_OUT_DATA:
if (urb->transfer_buffer_length > 0) {
size = urb->transfer_buffer_length;
- if (size > pipe->ep_mps) {
- size = pipe->ep_mps;
+ if (size > USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize)) {
+ size = USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize);
}
musb_write_packet(0, urb->transfer_buffer, size);
@@ -863,13 +814,13 @@ void handle_ep0(void)
break;
case USB_EP0_STATE_OUT_STATUS:
urb->errorcode = 0;
- musb_pipe_waitup(pipe);
+ musb_urb_waitup(urb);
break;
case USB_EP0_STATE_IN_STATUS:
if (ep0_status & (USB_CSRL0_RXRDY | USB_CSRL0_STATUS)) {
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~(USB_CSRL0_RXRDY | USB_CSRL0_STATUS);
urb->errorcode = 0;
- musb_pipe_waitup(pipe);
+ musb_urb_waitup(urb);
}
break;
}
@@ -939,7 +890,7 @@ void USBH_IRQHandler(void)
if (txis & (1 << ep_idx)) {
HWREGH(USB_BASE + MUSB_TXIS_OFFSET) = (1 << ep_idx);
- pipe = &g_musb_hcd.pipe_pool[ep_idx][0];
+ pipe = &g_musb_hcd.pipe_pool[ep_idx];
urb = pipe->urb;
musb_set_active_ep(ep_idx);
@@ -960,8 +911,8 @@ void USBH_IRQHandler(void)
} else {
uint32_t size = urb->transfer_buffer_length;
- if (size > pipe->ep_mps) {
- size = pipe->ep_mps;
+ if (size > USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize)) {
+ size = USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize);
}
urb->transfer_buffer += size;
@@ -984,7 +935,7 @@ void USBH_IRQHandler(void)
if (rxis & (1 << ep_idx)) {
HWREGH(USB_BASE + MUSB_RXIS_OFFSET) = (1 << ep_idx); // clear isr flag
- pipe = &g_musb_hcd.pipe_pool[ep_idx][1];
+ pipe = &g_musb_hcd.pipe_pool[ep_idx];
urb = pipe->urb;
musb_set_active_ep(ep_idx);
@@ -1005,8 +956,8 @@ void USBH_IRQHandler(void)
goto pipe_wait;
} else if (ep_csrl_status & USB_RXCSRL1_RXRDY) {
uint32_t size = urb->transfer_buffer_length;
- if (size > pipe->ep_mps) {
- size = pipe->ep_mps;
+ if (size > USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize)) {
+ size = USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize);
}
size = MIN(size, HWREGH(USB_BASE + MUSB_IND_RXCOUNT_OFFSET));
@@ -1018,7 +969,7 @@ void USBH_IRQHandler(void)
urb->transfer_buffer_length -= size;
urb->actual_length += size;
- if ((size < pipe->ep_mps) || (urb->transfer_buffer_length == 0)) {
+ if ((size < USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize)) || (urb->transfer_buffer_length == 0)) {
urb->errorcode = 0;
goto pipe_wait;
} else {
@@ -1030,6 +981,11 @@ void USBH_IRQHandler(void)
musb_set_active_ep(old_ep_idx);
return;
pipe_wait:
+ if (urb->ep->bEndpointAddress & 0x80) {
+ HWREGH(USB_BASE + MUSB_RXIE_OFFSET) |= (1 << pipe->chidx);
+ } else {
+ HWREGH(USB_BASE + MUSB_TXIE_OFFSET) |= (1 << pipe->chidx);
+ }
musb_set_active_ep(old_ep_idx);
- musb_pipe_waitup(pipe);
+ musb_urb_waitup(urb);
} \ No newline at end of file