refactor urb, add ep & hport in urb to make hardware pipe more reusable
This commit is contained in:
@@ -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') {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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') {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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') {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user