From ba8c528918e0f2896f4f5ad656a116c2f1750caa Mon Sep 17 00:00:00 2001 From: sakumisu <1203593632@qq.com> Date: Thu, 24 Feb 2022 12:29:06 +0800 Subject: [PATCH] use hport setup to replace class setup,move out test demo --- class/cdc/usbh_cdc_acm.c | 99 ++++------------------ class/cdc/usbh_cdc_acm.h | 4 +- class/hid/usbh_hid.c | 79 ++++------------- class/hid/usbh_hid.h | 2 +- class/hub/usbh_hub.c | 61 +++++--------- class/hub/usbh_hub.h | 1 + class/msc/usbh_msc.c | 73 +++++++--------- class/msc/usbh_msc.h | 5 +- core/usbh_core.c | 124 ++++++++++++++++++++------- core/usbh_core.h | 14 ++-- demo/usb_host.c | 177 +++++++++++++++++++++++++++++++++++++++ usb_config.h | 5 ++ 12 files changed, 377 insertions(+), 267 deletions(-) create mode 100644 demo/usb_host.c diff --git a/class/cdc/usbh_cdc_acm.c b/class/cdc/usbh_cdc_acm.c index 32ac41d9..4fe60a69 100644 --- a/class/cdc/usbh_cdc_acm.c +++ b/class/cdc/usbh_cdc_acm.c @@ -1,5 +1,6 @@ /** * @file usbh_cdc_acm.c + * @brief * * Copyright (c) 2022 sakumisu * @@ -22,8 +23,7 @@ #include "usbh_core.h" #include "usbh_cdc_acm.h" -#define DEV_FORMAT "/dev/ttyACM%d" -#define DEV_NAMELEN 16 +#define DEV_FORMAT "/dev/ttyACM%d" static uint32_t g_devinuse = 0; @@ -74,26 +74,13 @@ static void usbh_cdc_acm_devno_free(struct usbh_cdc_acm *priv) } } -/**************************************************************************** - * Name: usbh_cdc_acm_mkdevname - * - * Description: - * Format a /dev/ttyACM[n] device name given a minor number. - * - ****************************************************************************/ - -static inline void usbh_cdc_acm_mkdevname(struct usbh_cdc_acm *priv, char *devname) -{ - snprintf(devname, DEV_NAMELEN, DEV_FORMAT, priv->minor); -} - int usbh_cdc_acm_set_line_coding(struct usbh_hubport *hport, uint8_t intf, struct cdc_line_coding *line_coding) { int ret; struct usb_setup_packet *setup; struct usbh_cdc_acm *cdc_acm_class = (struct usbh_cdc_acm *)hport->config.intf[intf].priv; - setup = cdc_acm_class->setup; + setup = hport->setup; if (cdc_acm_class->ctrl_intf != intf) { return -1; @@ -119,7 +106,7 @@ int usbh_cdc_acm_get_line_coding(struct usbh_hubport *hport, uint8_t intf, struc struct usb_setup_packet *setup; struct usbh_cdc_acm *cdc_acm_class = (struct usbh_cdc_acm *)hport->config.intf[intf].priv; - setup = cdc_acm_class->setup; + setup = hport->setup; if (cdc_acm_class->ctrl_intf != intf) { return -1; @@ -145,7 +132,7 @@ int usbh_cdc_acm_set_line_state(struct usbh_hubport *hport, uint8_t intf, bool d struct usb_setup_packet *setup; struct usbh_cdc_acm *cdc_acm_class = (struct usbh_cdc_acm *)hport->config.intf[intf].priv; - setup = cdc_acm_class->setup; + setup = hport->setup; if (cdc_acm_class->ctrl_intf != intf) { return -1; @@ -168,26 +155,10 @@ int usbh_cdc_acm_set_line_state(struct usbh_hubport *hport, uint8_t intf, bool d return 0; } -USB_NOCACHE_RAM_SECTION uint8_t cdc_buffer[4096]; - -void usbh_cdc_acm_callback(void *arg, int nbytes) -{ - struct usbh_cdc_acm *cdc_acm_class = (struct usbh_cdc_acm *)arg; - - if (nbytes > 0) { - for (size_t i = 0; i < nbytes; i++) { - printf("0x%02x ", cdc_buffer[i]); - } - } - - printf("nbytes:%d\r\n", nbytes); -} - int usbh_cdc_acm_connect(struct usbh_hubport *hport, uint8_t intf) { struct usbh_endpoint_cfg ep_cfg = { 0 }; struct usb_endpoint_descriptor *ep_desc; - char devname[DEV_NAMELEN]; int ret; struct usbh_cdc_acm *cdc_acm_class = usb_malloc(sizeof(struct usbh_cdc_acm)); @@ -199,16 +170,11 @@ int usbh_cdc_acm_connect(struct usbh_hubport *hport, uint8_t intf) memset(cdc_acm_class, 0, sizeof(struct usbh_cdc_acm)); usbh_cdc_acm_devno_alloc(cdc_acm_class); - usbh_cdc_acm_mkdevname(cdc_acm_class, devname); + snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, cdc_acm_class->minor); hport->config.intf[intf].priv = cdc_acm_class; - hport->config.intf[intf + 1].priv = cdc_acm_class; + hport->config.intf[intf + 1].priv = NULL; - cdc_acm_class->setup = usb_iomalloc(sizeof(struct usb_setup_packet)); - if (cdc_acm_class->setup == NULL) { - USB_LOG_ERR("Fail to alloc setup\r\n"); - return -ENOMEM; - } cdc_acm_class->linecoding = usb_iomalloc(sizeof(struct cdc_line_coding)); if (cdc_acm_class->linecoding == NULL) { USB_LOG_ERR("Fail to alloc linecoding\r\n"); @@ -231,7 +197,7 @@ int usbh_cdc_acm_connect(struct usbh_hubport *hport, uint8_t intf) return ret; } -#if 0 +#ifdef CONFIG_USBHOST_CDC_ACM_NOTIFY ep_desc = &hport->config.intf[intf].ep[0].ep_desc; ep_cfg.ep_addr = ep_desc->bEndpointAddress; ep_cfg.ep_type = ep_desc->bmAttributes & USB_ENDPOINT_TYPE_MASK; @@ -256,56 +222,21 @@ int usbh_cdc_acm_connect(struct usbh_hubport *hport, uint8_t intf) } } - USB_LOG_INFO("Register CDC ACM Class:%s\r\n", devname); + USB_LOG_INFO("Register CDC ACM Class:%s\r\n", hport->config.intf[intf].devname); - memset(cdc_buffer, 0, 512); - ret = usbh_ep_bulk_transfer(cdc_acm_class->bulkin, cdc_buffer, 512); - if (ret < 0) { - printf("bulk in error\r\n"); - return ret; - } - printf("recv over:%d\r\n", ret); - for (size_t i = 0; i < ret; i++) { - printf("0x%02x ", cdc_buffer[i]); - } - printf("\r\n"); - const uint8_t data1[10] = { 0x02, 0x00, 0x00, 0x00, 0x02, 0x02, 0x08, 0x14 }; - - memcpy(cdc_buffer, data1, 8); - ret = usbh_ep_bulk_transfer(cdc_acm_class->bulkout, cdc_buffer, 8); - if (ret < 0) { - printf("bulk out error\r\n"); - return ret; - } - printf("send over:%d\r\n", ret); - -#if 0 - usbh_ep_bulk_async_transfer(cdc_acm_class->bulkin, cdc_buffer, 512, usbh_cdc_acm_callback, cdc_acm_class); -#else - ret = usbh_ep_bulk_transfer(cdc_acm_class->bulkin, cdc_buffer, 512); - if (ret < 0) { - printf("bulk in error\r\n"); - return ret; - } - printf("recv over:%d\r\n", ret); - for (size_t i = 0; i < ret; i++) { - printf("0x%02x ", cdc_buffer[i]); - } - printf("\r\n"); -#endif + extern int cdc_acm_test(); + cdc_acm_test(); return ret; } int usbh_cdc_acm_disconnect(struct usbh_hubport *hport, uint8_t intf) { - char devname[DEV_NAMELEN]; int ret = 0; struct usbh_cdc_acm *cdc_acm_class = (struct usbh_cdc_acm *)hport->config.intf[intf].priv; if (cdc_acm_class) { usbh_cdc_acm_devno_free(cdc_acm_class); - usbh_cdc_acm_mkdevname(cdc_acm_class, devname); if (cdc_acm_class->bulkin) { ret = usb_ep_cancel(cdc_acm_class->bulkin); @@ -320,17 +251,17 @@ int usbh_cdc_acm_disconnect(struct usbh_hubport *hport, uint8_t intf) } usbh_ep_free(cdc_acm_class->bulkout); } - if (cdc_acm_class->setup) - usb_iofree(cdc_acm_class->setup); + if (cdc_acm_class->linecoding) usb_iofree(cdc_acm_class->linecoding); usb_free(cdc_acm_class); + USB_LOG_INFO("Unregister CDC ACM Class:%s\r\n", hport->config.intf[intf].devname); + memset(hport->config.intf[intf].devname, 0, CONFIG_USBHOST_DEV_NAMELEN); + hport->config.intf[intf].priv = NULL; hport->config.intf[intf + 1].priv = NULL; - - USB_LOG_INFO("Unregister CDC ACM Class:%s\r\n", devname); } return ret; diff --git a/class/cdc/usbh_cdc_acm.h b/class/cdc/usbh_cdc_acm.h index e1283504..1ef8d516 100644 --- a/class/cdc/usbh_cdc_acm.h +++ b/class/cdc/usbh_cdc_acm.h @@ -1,5 +1,6 @@ /** * @file usbh_cdc_acm.h + * @brief * * Copyright (c) 2022 sakumisu * @@ -25,7 +26,6 @@ #include "usb_cdc.h" struct usbh_cdc_acm { - struct usb_setup_packet *setup; struct cdc_line_coding *linecoding; uint8_t ctrl_intf; /* Control interface number */ uint8_t data_intf; /* Data interface number */ @@ -34,7 +34,7 @@ struct usbh_cdc_acm { uint8_t minor; usbh_epinfo_t bulkin; /* Bulk IN endpoint */ usbh_epinfo_t bulkout; /* Bulk OUT endpoint */ -#ifdef HAVE_INTIN_ENDPOINT +#ifdef CONFIG_USBHOST_CDC_ACM_NOTIFY usbh_epinfo_t intin; /* Interrupt IN endpoint (optional) */ #endif }; diff --git a/class/hid/usbh_hid.c b/class/hid/usbh_hid.c index 7fee5a9b..691c86ad 100644 --- a/class/hid/usbh_hid.c +++ b/class/hid/usbh_hid.c @@ -1,5 +1,6 @@ /** * @file usbh_hid.c + * @brief * * Copyright (c) 2022 sakumisu * @@ -22,8 +23,7 @@ #include "usbh_core.h" #include "usbh_hid.h" -#define DEV_FORMAT "/dev/input%d" -#define DEV_NAMELEN 16 +#define DEV_FORMAT "/dev/input%d" static uint32_t g_devinuse = 0; @@ -74,25 +74,12 @@ static void usbh_hid_devno_free(struct usbh_hid *priv) } } -/**************************************************************************** - * Name: usbh_hid_mkdevname - * - * Description: - * Format a /dev/hid[n] device name given a minor number. - * - ****************************************************************************/ - -static inline void usbh_hid_mkdevname(struct usbh_hid *priv, char *devname) -{ - snprintf(devname, DEV_NAMELEN, DEV_FORMAT, priv->minor); -} - int usbh_hid_get_report_descriptor(struct usbh_hubport *hport, uint8_t intf, uint8_t *buffer) { struct usb_setup_packet *setup; struct usbh_hid *hid_class = (struct usbh_hid *)hport->config.intf[intf].priv; - setup = hid_class->setup; + setup = hport->setup; if (hid_class->intf != intf) { return -1; @@ -113,7 +100,7 @@ int usbh_hid_set_idle(struct usbh_hubport *hport, uint8_t intf, uint8_t report_i struct usb_setup_packet *setup; struct usbh_hid *hid_class = (struct usbh_hid *)hport->config.intf[intf].priv; - setup = hid_class->setup; + setup = hport->setup; if (hid_class->intf != intf) { return -1; @@ -139,7 +126,7 @@ int usbh_hid_get_idle(struct usbh_hubport *hport, uint8_t intf, uint8_t *buffer) struct usb_setup_packet *setup; struct usbh_hid *hid_class = (struct usbh_hid *)hport->config.intf[intf].priv; - setup = hid_class->setup; + setup = hport->setup; if (hid_class->intf != intf) { return -1; @@ -159,26 +146,10 @@ int usbh_hid_get_idle(struct usbh_hubport *hport, uint8_t intf, uint8_t *buffer) return 0; } -USB_NOCACHE_RAM_SECTION uint8_t hid_buffer[128]; - -void usbh_hid_callback(void *arg, int nbytes) -{ - struct usbh_hid *hid_class = (struct usbh_hid *)arg; - - if (nbytes > 0) { - for (size_t i = 0; i < nbytes; i++) { - printf("0x%02x ", hid_buffer[i]); - } - } - - printf("nbytes:%d\r\n", nbytes); -} - int usbh_hid_connect(struct usbh_hubport *hport, uint8_t intf) { struct usbh_endpoint_cfg ep_cfg = { 0 }; struct usb_endpoint_descriptor *ep_desc; - char devname[DEV_NAMELEN]; int ret; struct usbh_hid *hid_class = usb_malloc(sizeof(struct usbh_hid)); @@ -186,18 +157,13 @@ int usbh_hid_connect(struct usbh_hubport *hport, uint8_t intf) USB_LOG_ERR("Fail to alloc hid_class\r\n"); return -ENOMEM; } + memset(hid_class, 0, sizeof(struct usbh_hid)); usbh_hid_devno_alloc(hid_class); - usbh_hid_mkdevname(hid_class, devname); + snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, hid_class->minor); hport->config.intf[intf].priv = hid_class; - - hid_class->setup = usb_iomalloc(sizeof(struct usb_setup_packet)); - if (hid_class->setup == NULL) { - USB_LOG_ERR("Fail to alloc setup\r\n"); - return -ENOMEM; - } hid_class->intf = intf; ret = usbh_hid_set_idle(hport, intf, 0, 0); @@ -205,10 +171,13 @@ int usbh_hid_connect(struct usbh_hubport *hport, uint8_t intf) return ret; } - ret = usbh_hid_get_report_descriptor(hport, intf, hid_buffer); + uint8_t *report_buffer = usb_iomalloc(128); + ret = usbh_hid_get_report_descriptor(hport, intf, report_buffer); if (ret < 0) { + usb_iofree(report_buffer); return ret; } + usb_iofree(report_buffer); for (uint8_t i = 0; i < hport->config.intf[intf].intf_desc.bNumEndpoints; i++) { ep_desc = &hport->config.intf[intf].ep[i].ep_desc; @@ -224,33 +193,21 @@ int usbh_hid_connect(struct usbh_hubport *hport, uint8_t intf) } } - USB_LOG_INFO("Register HID Class:%s\r\n", devname); + USB_LOG_INFO("Register HID Class:%s\r\n", hport->config.intf[intf].devname); -#if 1 - ret = usbh_ep_intr_async_transfer(hid_class->intin, hid_buffer, 128, usbh_hid_callback, hid_class); - if (ret < 0) { - return ret; - } -#else - ret = usbh_ep_intr_transfer(hid_class->intin, hid_buffer, 128); - if (ret < 0) { - return ret; - } - USB_LOG_INFO("recv len:%d\r\n", ret); -#endif + extern int hid_test(); + hid_test(); return 0; } int usbh_hid_disconnect(struct usbh_hubport *hport, uint8_t intf) { - char devname[DEV_NAMELEN]; int ret = 0; struct usbh_hid *hid_class = (struct usbh_hid *)hport->config.intf[intf].priv; if (hid_class) { usbh_hid_devno_free(hid_class); - usbh_hid_mkdevname(hid_class, devname); if (hid_class->intin) { ret = usb_ep_cancel(hid_class->intin); @@ -265,13 +222,13 @@ int usbh_hid_disconnect(struct usbh_hubport *hport, uint8_t intf) } usbh_ep_free(hid_class->intout); } - if (hid_class->setup) - usb_iofree(hid_class->setup); usb_free(hid_class); - hport->config.intf[intf].priv = NULL; - USB_LOG_INFO("Unregister HID Class:%s\r\n", devname); + USB_LOG_INFO("Unregister HID Class:%s\r\n", hport->config.intf[intf].devname); + + memset(hport->config.intf[intf].devname, 0, CONFIG_USBHOST_DEV_NAMELEN); + hport->config.intf[intf].priv = NULL; } return ret; diff --git a/class/hid/usbh_hid.h b/class/hid/usbh_hid.h index a22c0653..0d32ffd1 100644 --- a/class/hid/usbh_hid.h +++ b/class/hid/usbh_hid.h @@ -1,5 +1,6 @@ /** * @file usbh_hid.h + * @brief * * Copyright (c) 2022 sakumisu * @@ -25,7 +26,6 @@ #include "usb_hid.h" struct usbh_hid { - struct usb_setup_packet *setup; uint8_t intf; /* interface number */ uint8_t minor; usbh_epinfo_t intin; /* INTR IN endpoint */ diff --git a/class/hub/usbh_hub.c b/class/hub/usbh_hub.c index 77cf334e..76642cb0 100644 --- a/class/hub/usbh_hub.c +++ b/class/hub/usbh_hub.c @@ -1,5 +1,6 @@ /** * @file usbh_hub.c + * @brief * * Copyright (c) 2022 sakumisu * @@ -22,8 +23,7 @@ #include "usbh_core.h" #include "usbh_hub.h" -#define DEV_FORMAT "/dev/hub%d" -#define DEV_NAMELEN 16 +#define DEV_FORMAT "/dev/hub%d" static uint32_t g_devinuse = 0; @@ -94,24 +94,11 @@ static void usbh_hub_devno_free(struct usbh_hub *hub) } } -/**************************************************************************** - * Name: usbh_hub_mkdevname - * - * Description: - * Format a /dev/hub[n] device name given a minor number. - * - ****************************************************************************/ - -static inline void usbh_hub_mkdevname(struct usbh_hub *hub, char *devname) -{ - snprintf(devname, DEV_NAMELEN, DEV_FORMAT, hub->index); -} - int usbh_hub_get_hub_descriptor(struct usbh_hub *hub, uint8_t *buffer) { struct usb_setup_packet *setup; - setup = hub->setup; + setup = hub->parent->setup; setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_DEVICE; setup->bRequest = USB_REQUEST_GET_DESCRIPTOR; @@ -126,7 +113,7 @@ int usbh_hub_get_status(struct usbh_hub *hub, uint8_t *buffer) { struct usb_setup_packet *setup; - setup = hub->setup; + setup = hub->parent->setup; setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_DEVICE; setup->bRequest = HUB_REQUEST_GET_STATUS; @@ -141,7 +128,7 @@ int usbh_hub_get_portstatus(struct usbh_hub *hub, uint8_t port, struct hub_port_ { struct usb_setup_packet *setup; - setup = hub->setup; + setup = hub->parent->setup; setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_OTHER; setup->bRequest = HUB_REQUEST_GET_STATUS; @@ -156,7 +143,7 @@ int usbh_hub_set_feature(struct usbh_hub *hub, uint8_t port, uint8_t feature) { struct usb_setup_packet *setup; - setup = hub->setup; + setup = hub->parent->setup; setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_OTHER; setup->bRequest = HUB_REQUEST_SET_FEATURE; @@ -171,7 +158,7 @@ int usbh_hub_clear_feature(struct usbh_hub *hub, uint8_t port, uint8_t feature) { struct usb_setup_packet *setup; - setup = hub->setup; + setup = hub->parent->setup; setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_OTHER; setup->bRequest = HUB_REQUEST_CLEAR_FEATURE; @@ -208,36 +195,30 @@ int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf) { struct usbh_endpoint_cfg ep_cfg = { 0 }; struct usb_endpoint_descriptor *ep_desc; - char devname[DEV_NAMELEN]; int ret; - uint8_t *hub_desc_buffer; - struct usbh_hub *hub_class; - hub_class = usb_malloc(sizeof(struct usbh_hub)); + struct usbh_hub *hub_class = usb_malloc(sizeof(struct usbh_hub)); if (hub_class == NULL) { USB_LOG_ERR("Fail to alloc hub_class\r\n"); return -ENOMEM; } + memset(hub_class, 0, sizeof(struct usbh_hub)); - hub_class->setup = usb_iomalloc(sizeof(struct usb_setup_packet)); - if (hub_class->setup == NULL) { - USB_LOG_ERR("Fail to alloc setup\r\n"); - return -ENOMEM; - } + hub_class->port_status = usb_iomalloc(sizeof(struct hub_port_status)); if (hub_class->port_status == NULL) { USB_LOG_ERR("Fail to alloc port_status\r\n"); return -ENOMEM; } - hub_desc_buffer = usb_iomalloc(32); - usbh_hub_devno_alloc(hub_class); - usbh_hub_mkdevname(hub_class, devname); + snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, hub_class->index); + hport->config.intf[intf].priv = hub_class; hub_class->dev_addr = hport->dev_addr; hub_class->parent = hport; - hport->config.intf[0].priv = hub_class; + + uint8_t *hub_desc_buffer = usb_iomalloc(32); ret = usbh_hub_get_hub_descriptor(hub_class, hub_desc_buffer); if (ret != 0) { @@ -286,7 +267,7 @@ int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf) } } - USB_LOG_INFO("Register HUB Class:%s\r\n", devname); + USB_LOG_INFO("Register HUB Class:%s\r\n", hport->config.intf[intf].devname); ret = usbh_ep_intr_async_transfer(hub_class->intin, hub_class->int_buffer, USBH_HUB_INTIN_BUFSIZE, usbh_external_hub_callback, hub_class); return 0; @@ -295,14 +276,12 @@ int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf) int usbh_hub_disconnect(struct usbh_hubport *hport, uint8_t intf) { struct usbh_hubport *child; - char devname[DEV_NAMELEN]; int ret = 0; struct usbh_hub *hub_class = (struct usbh_hub *)hport->config.intf[intf].priv; if (hub_class) { usbh_hub_devno_free(hub_class); - usbh_hub_mkdevname(hub_class, devname); if (hub_class->intin) { ret = usb_ep_cancel(hub_class->intin); @@ -311,8 +290,6 @@ int usbh_hub_disconnect(struct usbh_hubport *hport, uint8_t intf) usbh_ep_free(hub_class->intin); } - if (hub_class->setup) - usb_iofree(hub_class->setup); if (hub_class->port_status) usb_iofree(hub_class->port_status); @@ -331,9 +308,11 @@ int usbh_hub_disconnect(struct usbh_hubport *hport, uint8_t intf) usbh_hub_unregister(hub_class); usb_free(hub_class); - hport->config.intf[intf].priv = NULL; - USB_LOG_INFO("Unregister HUB Class:%s\r\n", devname); + USB_LOG_INFO("Unregister HUB Class:%s\r\n", hport->config.intf[intf].devname); + + memset(hport->config.intf[intf].devname, 0, CONFIG_USBHOST_DEV_NAMELEN); + hport->config.intf[intf].priv = NULL; } return ret; } @@ -445,7 +424,7 @@ static void usbh_extern_hub_psc_event(void *arg) if (status & HUB_PORT_STATUS_CONNECTION) { /* Device connected to a port on the hub */ - //USB_LOG_INFO("Connection on port:%d\n", port); + USB_LOG_DBG("Connection on port:%d\n", port); ret = usbh_hub_set_feature(hub_class, port, HUB_PORT_FEATURE_RESET); if (ret < 0) { diff --git a/class/hub/usbh_hub.h b/class/hub/usbh_hub.h index ee0df9e3..82bf1701 100644 --- a/class/hub/usbh_hub.h +++ b/class/hub/usbh_hub.h @@ -1,5 +1,6 @@ /** * @file usbh_hub.h + * @brief * * Copyright (c) 2022 sakumisu * diff --git a/class/msc/usbh_msc.c b/class/msc/usbh_msc.c index a64ca7fa..f2056566 100644 --- a/class/msc/usbh_msc.c +++ b/class/msc/usbh_msc.c @@ -24,8 +24,7 @@ #include "usbh_msc.h" #include "usb_scsi.h" -#define DEV_FORMAT "/dev/sd%c" -#define DEV_NAMELEN 16 +#define DEV_FORMAT "/dev/sd%c" static uint32_t g_devinuse = 0; @@ -76,25 +75,12 @@ static void usbh_msc_devno_free(struct usbh_msc *priv) } } -/**************************************************************************** - * Name: usbh_msc_mkdevname - * - * Description: - * Format a /dev/sd[n] device name given a minor number. - * - ****************************************************************************/ - -static inline void usbh_msc_mkdevname(struct usbh_msc *priv, char *devname) -{ - snprintf(devname, DEV_NAMELEN, DEV_FORMAT, priv->sdchar); -} - static int usbh_msc_get_maxlun(struct usbh_hubport *hport, uint8_t intf, uint8_t *buffer) { struct usb_setup_packet *setup; struct usbh_msc *msc_class = (struct usbh_msc *)hport->config.intf[intf].priv; - setup = msc_class->setup; + setup = hport->setup; if (msc_class->intf != intf) { return -1; @@ -111,6 +97,7 @@ static int usbh_msc_get_maxlun(struct usbh_hubport *hport, uint8_t intf, uint8_t static void usbh_msc_cbw_dump(struct CBW *cbw) { +#if 0 int i; USB_LOG_INFO("CBW:\r\n"); @@ -128,15 +115,18 @@ static void usbh_msc_cbw_dump(struct CBW *cbw) cbw->CB[i + 3], cbw->CB[i + 4], cbw->CB[i + 5], cbw->CB[i + 6], cbw->CB[i + 7]); } +#endif } static void usbh_msc_csw_dump(struct CSW *csw) { +#if 0 USB_LOG_INFO("CSW:\r\n"); USB_LOG_INFO(" signature: 0x%08x\r\n", (unsigned int)csw->dSignature); USB_LOG_INFO(" tag: 0x%08x\r\n", (unsigned int)csw->dTag); USB_LOG_INFO(" residue: 0x%08x\r\n", (unsigned int)csw->dDataResidue); USB_LOG_INFO(" status: 0x%02x\r\n", csw->bStatus); +#endif } static inline int usbh_msc_scsi_testunitready(struct usbh_msc *msc_class) @@ -152,6 +142,7 @@ static inline int usbh_msc_scsi_testunitready(struct usbh_msc *msc_class) cbw->bCBLength = SCSICMD_TESTUNITREADY_SIZEOF; cbw->CB[0] = SCSI_CMD_TESTUNITREADY; + usbh_msc_cbw_dump(cbw); /* Send the CBW */ nbytes = usbh_ep_bulk_transfer(msc_class->bulkout, (uint8_t *)cbw, USB_SIZEOF_MSC_CBW); if (nbytes >= 0) { @@ -179,6 +170,8 @@ static inline int usbh_msc_scsi_requestsense(struct usbh_msc *msc_class) cbw->dDataLength = SCSICMD_REQUESTSENSE_SIZEOF; cbw->CB[0] = SCSI_CMD_REQUESTSENSE; cbw->CB[4] = SCSIRESP_FIXEDSENSEDATA_SIZEOF; + + usbh_msc_cbw_dump(cbw); /* Send the CBW */ nbytes = usbh_ep_bulk_transfer(msc_class->bulkout, (uint8_t *)cbw, USB_SIZEOF_MSC_CBW); if (nbytes >= 0) { @@ -211,6 +204,7 @@ static inline int usbh_msc_scsi_inquiry(struct usbh_msc *msc_class) cbw->CB[0] = SCSI_CMD_INQUIRY; cbw->CB[4] = SCSIRESP_INQUIRY_SIZEOF; + usbh_msc_cbw_dump(cbw); /* Send the CBW */ nbytes = usbh_ep_bulk_transfer(msc_class->bulkout, (uint8_t *)cbw, USB_SIZEOF_MSC_CBW); if (nbytes >= 0) { @@ -242,6 +236,7 @@ static inline int usbh_msc_scsi_readcapacity10(struct usbh_msc *msc_class) cbw->bCBLength = SCSICMD_READCAPACITY10_SIZEOF; cbw->CB[0] = SCSI_CMD_READCAPACITY10; + usbh_msc_cbw_dump(cbw); /* Send the CBW */ nbytes = usbh_ep_bulk_transfer(msc_class->bulkout, (uint8_t *)cbw, USB_SIZEOF_MSC_CBW); if (nbytes >= 0) { @@ -251,8 +246,6 @@ static inline int usbh_msc_scsi_readcapacity10(struct usbh_msc *msc_class) /* Save the capacity information */ msc_class->blocknum = GET_BE32(&msc_class->tx_buffer[0]) + 1; msc_class->blocksize = GET_BE32(&msc_class->tx_buffer[4]); - USB_LOG_INFO("capacity info:\r\n"); - USB_LOG_INFO("block num:%d,block size:%d\r\n", (unsigned int)msc_class->blocknum, (unsigned int)msc_class->blocksize); /* Receive the CSW */ nbytes = usbh_ep_bulk_transfer(msc_class->bulkin, msc_class->tx_buffer, USB_SIZEOF_MSC_CSW); if (nbytes >= 0) { @@ -263,7 +256,7 @@ static inline int usbh_msc_scsi_readcapacity10(struct usbh_msc *msc_class) return nbytes < 0 ? (int)nbytes : 0; } -int usbh_msc_mem_write(struct usbh_msc *msc_class, uint32_t sector, const uint8_t *buffer, uint32_t nsectors) +int usbh_msc_scsi_write10(struct usbh_msc *msc_class, uint32_t start_sector, const uint8_t *buffer, uint32_t nsectors) { int nbytes; struct CBW *cbw; @@ -277,9 +270,10 @@ int usbh_msc_mem_write(struct usbh_msc *msc_class, uint32_t sector, const uint8_ cbw->bCBLength = SCSICMD_WRITE10_SIZEOF; cbw->CB[0] = SCSI_CMD_WRITE10; - SET_BE24(&cbw->CB[2], sector); - SET_BE24(&cbw->CB[7], nsectors); + SET_BE32(&cbw->CB[2], start_sector); + SET_BE16(&cbw->CB[7], nsectors); + usbh_msc_cbw_dump(cbw); /* Send the CBW */ nbytes = usbh_ep_bulk_transfer(msc_class->bulkout, (uint8_t *)cbw, USB_SIZEOF_MSC_CBW); if (nbytes >= 0) { @@ -296,7 +290,7 @@ int usbh_msc_mem_write(struct usbh_msc *msc_class, uint32_t sector, const uint8_ return nbytes < 0 ? (int)nbytes : 0; } -int usbh_msc_mem_read(struct usbh_msc *msc_class, uint32_t sector, const uint8_t *buffer, uint32_t nsectors) +int usbh_msc_scsi_read10(struct usbh_msc *msc_class, uint32_t start_sector, const uint8_t *buffer, uint32_t nsectors) { int nbytes; struct CBW *cbw; @@ -311,9 +305,10 @@ int usbh_msc_mem_read(struct usbh_msc *msc_class, uint32_t sector, const uint8_t cbw->bCBLength = SCSICMD_READ10_SIZEOF; cbw->CB[0] = SCSI_CMD_READ10; - SET_BE24(&cbw->CB[2], sector); - SET_BE24(&cbw->CB[7], nsectors); + SET_BE32(&cbw->CB[2], start_sector); + SET_BE16(&cbw->CB[7], nsectors); + usbh_msc_cbw_dump(cbw); /* Send the CBW */ nbytes = usbh_ep_bulk_transfer(msc_class->bulkout, (uint8_t *)cbw, USB_SIZEOF_MSC_CBW); if (nbytes >= 0) { @@ -334,8 +329,6 @@ int usbh_msc_connect(struct usbh_hubport *hport, uint8_t intf) { struct usbh_endpoint_cfg ep_cfg = { 0 }; struct usb_endpoint_descriptor *ep_desc; - - char devname[DEV_NAMELEN]; int ret; struct usbh_msc *msc_class = usb_malloc(sizeof(struct usbh_msc)); @@ -347,26 +340,22 @@ int usbh_msc_connect(struct usbh_hubport *hport, uint8_t intf) memset(msc_class, 0, sizeof(struct usbh_msc)); usbh_msc_devno_alloc(msc_class); - usbh_msc_mkdevname(msc_class, devname); + snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, msc_class->sdchar); hport->config.intf[intf].priv = msc_class; - msc_class->setup = usb_iomalloc(sizeof(struct usb_setup_packet)); - if (msc_class->setup == NULL) { - USB_LOG_ERR("Fail to alloc setup\r\n"); - return -ENOMEM; - } - msc_class->tx_buffer = usb_iomalloc(128); + msc_class->tx_buffer = usb_iomalloc(32); if (msc_class->tx_buffer == NULL) { USB_LOG_ERR("Fail to alloc tx_buffer\r\n"); return -ENOMEM; } + ret = usbh_msc_get_maxlun(hport, intf, msc_class->tx_buffer); if (ret < 0) { return ret; } - USB_LOG_INFO("Get max LUN:%u\r\n", msc_class->tx_buffer[0]); + USB_LOG_INFO("Get max LUN:%u\r\n", msc_class->tx_buffer[0] + 1); for (uint8_t i = 0; i < hport->config.intf[intf].intf_desc.bNumEndpoints; i++) { ep_desc = &hport->config.intf[intf].ep[i].ep_desc; @@ -383,25 +372,28 @@ int usbh_msc_connect(struct usbh_hubport *hport, uint8_t intf) } } - USB_LOG_INFO("Register MSC Class:%s\r\n", devname); + USB_LOG_INFO("Register MSC Class:%s\r\n", hport->config.intf[intf].devname); ret = usbh_msc_scsi_testunitready(msc_class); ret = usbh_msc_scsi_inquiry(msc_class); ret = usbh_msc_scsi_readcapacity10(msc_class); + USB_LOG_INFO("Capacity info:\r\n"); + USB_LOG_INFO("Block num:%d,block size:%d\r\n", (unsigned int)msc_class->blocknum, (unsigned int)msc_class->blocksize); + + extern int msc_test(); + msc_test(); return ret; } int usbh_msc_disconnect(struct usbh_hubport *hport, uint8_t intf) { - char devname[DEV_NAMELEN]; int ret = 0; struct usbh_msc *msc_class = (struct usbh_msc *)hport->config.intf[intf].priv; if (msc_class) { usbh_msc_devno_free(msc_class); - usbh_msc_mkdevname(msc_class, devname); if (msc_class->bulkin) { ret = usb_ep_cancel(msc_class->bulkin); @@ -417,16 +409,15 @@ int usbh_msc_disconnect(struct usbh_hubport *hport, uint8_t intf) usbh_ep_free(msc_class->bulkout); } - if (msc_class->setup) - usb_iofree(msc_class->setup); if (msc_class->tx_buffer) usb_iofree(msc_class->tx_buffer); usb_free(msc_class); - hport->config.intf[intf].priv = NULL; + USB_LOG_INFO("Unregister MSC Class:%s\r\n", hport->config.intf[intf].devname); - USB_LOG_INFO("Unregister MSC Class:%s\r\n", devname); + memset(hport->config.intf[intf].devname, 0, CONFIG_USBHOST_DEV_NAMELEN); + hport->config.intf[intf].priv = NULL; } return ret; diff --git a/class/msc/usbh_msc.h b/class/msc/usbh_msc.h index 7318028a..f1d48980 100644 --- a/class/msc/usbh_msc.h +++ b/class/msc/usbh_msc.h @@ -1,5 +1,6 @@ /** * @file usbh_msc.h + * @brief * * Copyright (c) 2022 sakumisu * @@ -26,7 +27,6 @@ #include "usb_scsi.h" struct usbh_msc { - struct usb_setup_packet *setup; uint8_t intf; /* Data interface number */ uint8_t sdchar; usbh_epinfo_t bulkin; /* Bulk IN endpoint */ @@ -38,6 +38,9 @@ struct usbh_msc { extern const struct usbh_class_driver msc_class_driver; +int usbh_msc_scsi_write10(struct usbh_msc *msc_class, uint32_t start_sector, const uint8_t *buffer, uint32_t nsectors); +int usbh_msc_scsi_read10(struct usbh_msc *msc_class, uint32_t start_sector, const uint8_t *buffer, uint32_t nsectors); + #ifdef __cplusplus extern "C" { #endif diff --git a/core/usbh_core.c b/core/usbh_core.c index 7fa335b7..8d1de09e 100644 --- a/core/usbh_core.c +++ b/core/usbh_core.c @@ -1,5 +1,6 @@ /** * @file usbh_core.c + * @brief * * Copyright (c) 2022 sakumisu * @@ -299,8 +300,9 @@ static int parse_config_descriptor(struct usbh_hubport *hport, struct usb_config } return 0; } -#if 0 -static int parse_string_descriptor(struct usbh_hubport *hport, struct usb_string_descriptor *desc, uint8_t str_idx, uint16_t length) + +#ifdef CONFIG_USBHOST_GET_STRING_DESC +static int parse_string_descriptor(struct usbh_hubport *hport, struct usb_string_descriptor *desc, uint8_t str_idx) { uint8_t string[64 + 1] = { 0 }; uint8_t *p = (uint8_t *)desc; @@ -314,7 +316,15 @@ static int parse_string_descriptor(struct usbh_hubport *hport, struct usb_string string[i] = *p; p += 2; } - USB_LOG_DBG("string:%s\r\n", string); + if (str_idx == USB_STRING_MFC_INDEX) { + USB_LOG_INFO("Manufacturer :%s\r\n", string); + } else if (str_idx == USB_STRING_PRODUCT_INDEX) { + USB_LOG_INFO("Product :%s\r\n", string); + + } else if (str_idx == USB_STRING_SERIAL_INDEX) { + USB_LOG_INFO("SerialNumber :%s\r\n", string); + } else { + } } return 0; } @@ -384,12 +394,16 @@ static int usbh_enumerate(struct usbh_hubport *hport) #define USB_REQUEST_BUFFER_SIZE 256 /* Allocate buffer for setup and data buffer */ - setup = usb_iomalloc(sizeof(struct usb_setup_packet)); - if (setup == NULL) { - USB_LOG_ERR("Fail to alloc setup\r\n"); - return -ENOMEM; + if (hport->setup == NULL) { + hport->setup = usb_iomalloc(sizeof(struct usb_setup_packet)); + if (hport->setup == NULL) { + USB_LOG_ERR("Fail to alloc setup\r\n"); + return -ENOMEM; + } } + setup = hport->setup; + ep0_buffer = usb_iomalloc(USB_REQUEST_BUFFER_SIZE); if (ep0_buffer == NULL) { USB_LOG_ERR("Fail to alloc ep0_buffer\r\n"); @@ -521,6 +535,52 @@ static int usbh_enumerate(struct usbh_hubport *hport) parse_config_descriptor(hport, (struct usb_configuration_descriptor *)ep0_buffer, wTotalLength); +#ifdef CONFIG_USBHOST_GET_STRING_DESC + /* Get Manufacturer string */ + setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE; + setup->bRequest = USB_REQUEST_GET_DESCRIPTOR; + setup->wValue = (uint16_t)((USB_DESCRIPTOR_TYPE_STRING << 8) | USB_STRING_MFC_INDEX); + setup->wIndex = 0x0409; + setup->wLength = 255; + + ret = usbh_control_transfer(hport->ep0, setup, ep0_buffer); + if (ret < 0) { + USB_LOG_ERR("Failed to get Manufacturer string,errorcode:%d\r\n", ret); + goto errout; + } + + parse_string_descriptor(hport, (struct usb_string_descriptor *)ep0_buffer, USB_STRING_MFC_INDEX); + + /* Get Product string */ + setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE; + setup->bRequest = USB_REQUEST_GET_DESCRIPTOR; + setup->wValue = (uint16_t)((USB_DESCRIPTOR_TYPE_STRING << 8) | USB_STRING_PRODUCT_INDEX); + setup->wIndex = 0x0409; + setup->wLength = 255; + + ret = usbh_control_transfer(hport->ep0, setup, ep0_buffer); + if (ret < 0) { + USB_LOG_ERR("Failed to get get Product string,errorcode:%d\r\n", ret); + goto errout; + } + + parse_string_descriptor(hport, (struct usb_string_descriptor *)ep0_buffer, USB_STRING_PRODUCT_INDEX); + + /* Get SerialNumber string */ + setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE; + setup->bRequest = USB_REQUEST_GET_DESCRIPTOR; + setup->wValue = (uint16_t)((USB_DESCRIPTOR_TYPE_STRING << 8) | USB_STRING_SERIAL_INDEX); + setup->wIndex = 0x0409; + setup->wLength = 255; + + ret = usbh_control_transfer(hport->ep0, setup, ep0_buffer); + if (ret < 0) { + USB_LOG_ERR("Failed to get get SerialNumber string,errorcode:%d\r\n", ret); + goto errout; + } + + parse_string_descriptor(hport, (struct usb_string_descriptor *)ep0_buffer, USB_STRING_SERIAL_INDEX); +#endif /* Select device configuration 1 */ setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE; setup->bRequest = USB_REQUEST_SET_CONFIGURATION; @@ -565,9 +625,6 @@ errout: usbh_hport_deactivate(hport); } - if (setup) { - usb_iofree(setup); - } if (ep0_buffer) { usb_iofree(ep0_buffer); } @@ -626,7 +683,6 @@ static void usbh_portchange_detect_thread(void *argument) usbh_core_cfg.rhport[port - 1].devgen.next = 1; usbh_hport_activate(&usbh_core_cfg.rhport[port - 1].hport); } - usb_osal_leave_critical_section(flags); while (1) { @@ -639,9 +695,9 @@ static void usbh_portchange_detect_thread(void *argument) usb_osal_msleep(200); /* Get the current device speed */ hport->speed = usbh_get_port_speed(hport->port); - USB_LOG_INFO("Bus %u, Port %u connected, %s\r\n", 1, hport->port, speed_table[hport->speed]); + USB_LOG_INFO("Hub %u, Port %u connected, %s\r\n", 1, hport->port, speed_table[hport->speed]); } else { - USB_LOG_INFO("Bus %u, Port %u connected, %s\r\n", hport->parent->index, hport->port, speed_table[hport->speed]); + USB_LOG_INFO("Hub %u, Port %u connected, %s\r\n", hport->parent->index, hport->port, speed_table[hport->speed]); } usb_osal_thread_suspend(g_lpworkq.thread); usbh_enumerate(hport); @@ -657,9 +713,9 @@ static void usbh_portchange_detect_thread(void *argument) hport->config.config_desc.bNumInterfaces = 0; if (ROOTHUB(hport)) { - USB_LOG_INFO("Bus %u,Port:%u disconnected\r\n", 1, hport->port); + USB_LOG_INFO("Hub %u,Port:%u disconnected\r\n", 1, hport->port); } else { - USB_LOG_INFO("Bus %u,Port:%u disconnected\r\n", hport->parent->index, hport->port); + USB_LOG_INFO("Hub %u,Port:%u disconnected\r\n", hport->parent->index, hport->port); } } } @@ -732,6 +788,11 @@ void usbh_hport_deactivate(struct usbh_hubport *hport) } /* Free the device address if one has been assigned */ usbh_devaddr_destroy(hport, hport->dev_addr); + + if (hport->setup) + usb_iofree(hport->setup); + + hport->setup = NULL; hport->dev_addr = 0; usb_osal_leave_critical_section(flags); @@ -816,7 +877,7 @@ int lsusb(int argc, char **argv) if (strcmp(argv[1], "-t") == 0) { for (port = USBH_HUB_PORT_START_INDEX; port <= CONFIG_USBHOST_RHPORTS; port++) { if (usbh_core_cfg.rhport[port - 1].hport.connected) { - printf("/: Bus %02u,VID:PID 0x%04x:0x%04x\r\n", USBH_ROOT_HUB_INDEX, usbh_core_cfg.rhport[port - 1].hport.device_desc.idVendor, usbh_core_cfg.rhport[port - 1].hport.device_desc.idProduct); + printf("/: Hub %02u,VID:PID 0x%04x:0x%04x\r\n", USBH_ROOT_HUB_INDEX, usbh_core_cfg.rhport[port - 1].hport.device_desc.idVendor, usbh_core_cfg.rhport[port - 1].hport.device_desc.idProduct); for (uint8_t i = 0; i < usbh_core_cfg.rhport[port - 1].hport.config.config_desc.bNumInterfaces; i++) { if (usbh_core_cfg.rhport[port - 1].hport.config.intf[i].class_driver->driver_name) { @@ -832,7 +893,7 @@ int lsusb(int argc, char **argv) for (port = USBH_HUB_PORT_START_INDEX; port <= hub_class->nports; port++) { if (hub_class->child[port - 1].connected) { - printf("/: Bus %02u,VID:PID 0x%04x:0x%04x\r\n", hub_class->index, hub_class->child[port - 1].device_desc.idVendor, hub_class->child[port - 1].device_desc.idProduct); + printf("/: Hub %02u,VID:PID 0x%04x:0x%04x\r\n", hub_class->index, hub_class->child[port - 1].device_desc.idVendor, hub_class->child[port - 1].device_desc.idProduct); for (uint8_t i = 0; i < hub_class->child[port - 1].config.config_desc.bNumInterfaces; i++) { if (hub_class->child[port - 1].config.intf[i].class_driver->driver_name) { @@ -846,7 +907,7 @@ int lsusb(int argc, char **argv) } else if (strcmp(argv[1], "-v") == 0) { for (port = USBH_HUB_PORT_START_INDEX; port <= CONFIG_USBHOST_RHPORTS; port++) { if (usbh_core_cfg.rhport[port - 1].hport.connected) { - printf("Bus %02u,Port %u,Port addr:0x%02x,VID:PID 0x%04x:0x%04x\r\n", USBH_ROOT_HUB_INDEX, usbh_core_cfg.rhport[port - 1].hport.port, usbh_core_cfg.rhport[port - 1].hport.dev_addr, + printf("Hub %02u,Port %u,Port addr:0x%02x,VID:PID 0x%04x:0x%04x\r\n", USBH_ROOT_HUB_INDEX, usbh_core_cfg.rhport[port - 1].hport.port, usbh_core_cfg.rhport[port - 1].hport.dev_addr, usbh_core_cfg.rhport[port - 1].hport.device_desc.idVendor, usbh_core_cfg.rhport[port - 1].hport.device_desc.idProduct); usbh_print_hubport_info(&usbh_core_cfg.rhport[port - 1].hport); } @@ -858,7 +919,7 @@ int lsusb(int argc, char **argv) for (port = USBH_HUB_PORT_START_INDEX; port <= hub_class->nports; port++) { if (hub_class->child[port - 1].connected) { - printf("Bus %02u,Port %u,Port addr:0x%02x,VID:PID 0x%04x:0x%04x\r\n", hub_class->index, hub_class->child[port - 1].port, hub_class->child[port - 1].dev_addr, + printf("Hub %02u,Port %u,Port addr:0x%02x,VID:PID 0x%04x:0x%04x\r\n", hub_class->index, hub_class->child[port - 1].port, hub_class->child[port - 1].dev_addr, hub_class->child[port - 1].device_desc.idVendor, hub_class->child[port - 1].device_desc.idProduct); usbh_print_hubport_info(&hub_class->child[port - 1]); } @@ -869,7 +930,7 @@ int lsusb(int argc, char **argv) return 0; } -struct usbh_hubport *usbh_get_hubport(uint8_t dev_addr) +struct usbh_hubport *usbh_find_hubport(uint8_t dev_addr) { usb_slist_t *hub_list; uint8_t port; @@ -896,17 +957,18 @@ struct usbh_hubport *usbh_get_hubport(uint8_t dev_addr) return NULL; } -void *usbh_get_class(uint8_t dev_addr, uint8_t intf) +void *usbh_find_class_instance(const char *devname) { usb_slist_t *hub_list; + struct usbh_hubport *hport; uint8_t port; for (port = USBH_HUB_PORT_START_INDEX; port <= CONFIG_USBHOST_RHPORTS; port++) { - if (usbh_core_cfg.rhport[port - 1].hport.connected) { - if (usbh_core_cfg.rhport[port - 1].hport.dev_addr == dev_addr) { - if (usbh_core_cfg.rhport[port - 1].hport.config.intf[intf].priv) { - return usbh_core_cfg.rhport[port - 1].hport.config.intf[intf].priv; - } + hport = &usbh_core_cfg.rhport[port - 1].hport; + 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) + return hport->config.intf[itf].priv; } } } @@ -915,11 +977,11 @@ void *usbh_get_class(uint8_t dev_addr, uint8_t intf) usbh_hub_t *hub_class = usb_slist_entry(hub_list, struct usbh_hub, list); for (port = USBH_HUB_PORT_START_INDEX; port <= hub_class->nports; port++) { - if (hub_class->child[port - 1].connected) { - if (hub_class->child[port - 1].dev_addr == dev_addr) { - if (hub_class->child[port - 1].config.intf[intf].priv) { - return hub_class->child[port - 1].config.intf[intf].priv; - } + hport = &hub_class->child[port - 1]; + 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) + return hport->config.intf[itf].priv; } } } diff --git a/core/usbh_core.h b/core/usbh_core.h index 740c5380..df4ae26d 100644 --- a/core/usbh_core.h +++ b/core/usbh_core.h @@ -1,5 +1,6 @@ /** * @file usbh_core.h + * @brief * * Copyright (c) 2022 sakumisu * @@ -44,8 +45,8 @@ extern "C" { #define ROOTHUB(hport) true #endif -#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)) enum usbh_event_type { USBH_EVENT_ATTACHED, @@ -75,6 +76,7 @@ typedef struct usbh_endpoint { typedef struct usbh_interface { struct usb_interface_descriptor intf_desc; struct usbh_endpoint ep[CONFIG_USBHOST_EP_NUM]; + char devname[CONFIG_USBHOST_DEV_NAMELEN]; struct usbh_class_driver *class_driver; void *priv; } usbh_interface_t; @@ -96,6 +98,7 @@ typedef struct usbh_hubport { #if 0 uint8_t* config_desc; #endif + struct usb_setup_packet *setup; struct usbh_hub *parent; /*if NULL, is roothub*/ } usbh_hubport_t; @@ -106,7 +109,6 @@ typedef struct usbh_hub { uint8_t dev_addr; /* Hub device address */ usbh_epinfo_t intin; uint8_t *int_buffer; - struct usb_setup_packet *setup; struct hub_port_status *port_status; struct usb_hub_descriptor hub_desc; struct usbh_hubport child[CONFIG_USBHOST_EHPORTS]; @@ -117,9 +119,11 @@ typedef struct usbh_hub { void usbh_event_notify_handler(uint8_t event, uint8_t rhport); int usbh_initialize(void); +int usbh_lock(void); +void usbh_unlock(void); int lsusb(int argc, char **argv); -struct usbh_hubport *usbh_get_hubport(uint8_t dev_addr); -void *usbh_get_class(uint8_t dev_addr, uint8_t intf); +struct usbh_hubport *usbh_find_hubport(uint8_t dev_addr); +void *usbh_find_class_instance(const char *devname); #ifdef __cplusplus } diff --git a/demo/usb_host.c b/demo/usb_host.c new file mode 100644 index 00000000..26e38037 --- /dev/null +++ b/demo/usb_host.c @@ -0,0 +1,177 @@ +#include "usbh_core.h" +#include "usbh_cdc_acm.h" +#include "usbh_hid.h" +#include "usbh_msc.h" + +uint8_t cdc_buffer[4096]; + +void usbh_cdc_acm_callback(void *arg, int nbytes) +{ + //struct usbh_cdc_acm *cdc_acm_class = (struct usbh_cdc_acm *)arg; + + if (nbytes > 0) { + for (size_t i = 0; i < nbytes; i++) { + printf("0x%02x ", cdc_buffer[i]); + } + } + + printf("nbytes:%d\r\n", nbytes); +} + +int cdc_acm_test(void) +{ + int ret; + + struct usbh_cdc_acm *cdc_acm_class = (struct usbh_cdc_acm *)usbh_find_class_instance("/dev/ttyACM0"); + + if (cdc_acm_class == NULL) { + printf("do not find /dev/ttyACM0\r\n"); + return -1; + } + + memset(cdc_buffer, 0, 512); + ret = usbh_ep_bulk_transfer(cdc_acm_class->bulkin, cdc_buffer, 512); + if (ret < 0) { + printf("bulk in error\r\n"); + return ret; + } + printf("recv over:%d\r\n", ret); + for (size_t i = 0; i < ret; i++) { + printf("0x%02x ", cdc_buffer[i]); + } + printf("\r\n"); + const uint8_t data1[10] = { 0x02, 0x00, 0x00, 0x00, 0x02, 0x02, 0x08, 0x14 }; + + memcpy(cdc_buffer, data1, 8); + ret = usbh_ep_bulk_transfer(cdc_acm_class->bulkout, cdc_buffer, 8); + if (ret < 0) { + printf("bulk out error\r\n"); + return ret; + } + printf("send over:%d\r\n", ret); + +#if 0 + usbh_ep_bulk_async_transfer(cdc_acm_class->bulkin, cdc_buffer, 512, usbh_cdc_acm_callback, cdc_acm_class); +#else + ret = usbh_ep_bulk_transfer(cdc_acm_class->bulkin, cdc_buffer, 512); + if (ret < 0) { + printf("bulk in error\r\n"); + return ret; + } + printf("recv over:%d\r\n", ret); + for (size_t i = 0; i < ret; i++) { + printf("0x%02x ", cdc_buffer[i]); + } + printf("\r\n"); + + return ret; +#endif +} + + +#include "ff.h" + +int msc_test(void) +{ + int ret; + struct usbh_msc *msc_class = (struct usbh_msc *)usbh_find_class_instance("/dev/sda"); + if (msc_class == NULL) { + printf("do not find /dev/sda\r\n"); + return -1; + } +#if 0 + /* get the partition table */ + uint8_t *partition_table = usb_iomalloc(1024); + ret = usbh_msc_scsi_read10(msc_class, 0, partition_table, 1); + + for (uint32_t i = 0; i < 1024; i++) { + if (i % 16 == 0) { + printf("\r\n"); + } + printf("%02x ", partition_table[i]); + } + printf("\r\n"); +#endif + +#if 0 + uint8_t *partition_table = usb_iomalloc(8192); + ret = usbh_msc_scsi_read10(msc_class, 0, partition_table, 16); + usb_iofree(partition_table); + // for (uint32_t i = 0; i < 1024; i++) { + // if (i % 16 == 0) { + // printf("\r\n"); + // } + // printf("%02x ", partition_table[i]); + // } + // printf("\r\n"); +#endif + +#if 1 + + FATFS fs; + FIL fnew; + UINT fnum; + FRESULT res_sd = 0; + uint8_t *ReadBuffer; + + ReadBuffer = usb_iomalloc(512); + f_mount(&fs, "2:", 1); + res_sd = f_open(&fnew, "2:test.c", FA_OPEN_EXISTING | FA_READ); + if (res_sd == FR_OK) { + res_sd = f_read(&fnew, ReadBuffer, 512, &fnum); + for (uint32_t i = 0; i < fnum; i++) { + if (i % 16 == 0) { + printf("\r\n"); + } + printf("%02x ", ReadBuffer[i]); + } + printf("\r\n"); + f_close(&fnew); + /*unmount*/ + f_mount(NULL, "2:", 1); + } else { + printf("open error:%d\r\n",res_sd); + } + usb_iofree(ReadBuffer); +#endif + return ret; +} + + +uint8_t hid_buffer[128]; + +void usbh_hid_callback(void *arg, int nbytes) +{ + //struct usbh_hid *hid_class = (struct usbh_hid *)arg; + + if (nbytes > 0) { + for (size_t i = 0; i < nbytes; i++) { + printf("0x%02x ", hid_buffer[i]); + } + } + + printf("nbytes:%d\r\n", nbytes); +} + +int hid_test(void) +{ + int ret; + struct usbh_hid *hid_class = (struct usbh_hid *)usbh_find_class_instance("/dev/input0"); + if (hid_class == NULL) { + printf("do not find /dev/input0\r\n"); + return -1; + } +#if 1 + ret = usbh_ep_intr_async_transfer(hid_class->intin, hid_buffer, 128, usbh_hid_callback, hid_class); + if (ret < 0) { + return ret; + } +#else + ret = usbh_ep_intr_transfer(hid_class->intin, hid_buffer, 128); + if (ret < 0) { + return ret; + } + printf("recv len:%d\r\n", ret); +#endif + return ret; +} \ No newline at end of file diff --git a/usb_config.h b/usb_config.h index 8fb0f1c4..07cec261 100644 --- a/usb_config.h +++ b/usb_config.h @@ -41,7 +41,12 @@ #define CONFIG_USBHOST_PSC_STACKSIZE 2048 #endif +#ifndef CONFIG_USBHOST_DEV_NAMELEN +#define CONFIG_USBHOST_DEV_NAMELEN 16 +#endif + #define CONFIG_USBHOST_ASYNCH +//#define CONFIG_USBHOST_GET_STRING_DESC /* EHCI Configuration */ #define CONFIG_USB_EHCI_HCCR_BASE (0x20072000)