From d4f72f2ad9ce24bcfdfe2b72c60a2a5354cd8589 Mon Sep 17 00:00:00 2001 From: songyanguang <345810377@qq.com> Date: Tue, 18 Jun 2024 16:09:32 +0800 Subject: [PATCH] Decoupling core and xhci. --- .../drivers/usb/components/core/usbh_core.c | 100 ++++++++++++++---- .../drivers/usb/components/core/usbh_core.h | 51 +++++---- 2 files changed, 112 insertions(+), 39 deletions(-) diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/core/usbh_core.c b/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/core/usbh_core.c index 134378d2b..1822356cd 100644 --- a/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/core/usbh_core.c +++ b/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/core/usbh_core.c @@ -3,16 +3,24 @@ * * SPDX-License-Identifier: Apache-2.0 */ - + /************************************************* File name: usbh_core.c Description: adopt cherry USB to XiZi AIOT. Others: CherryUSB third-party/cherryusb/core/usbh_core.c for references https://gitee.com/phytium_embedded/phytium-free-rtos-sdk/blob/master/third-party/cherryusb/core/usbh_core.c + +History: +1. Date: 2024-06-18 +Author: AIIT XUOS Lab +Modification: + Modify function usbh_enumerate usbh_hport_activate_ep0 usbh_hport_deactivate_ep0 and usbh_hport_activate_epx, for select host controller function. + new function usbh_control_transfer_msg, for references usbh_control_transfer, to select host controller function by type. *************************************************/ #include "usbh_core.h" #include "usbh_hub.h" +#include "usb_hc_xhci.h" struct usbh_class_info *usbh_class_info_table_begin = NULL; struct usbh_class_info *usbh_class_info_table_end = NULL; @@ -463,6 +471,7 @@ static int usbh_get_default_mps(int speed) int usbh_hport_activate_ep0(struct usbh_hubport *hport) { + struct usbh_bus *usb = usbh_get_bus_of_port(hport); struct usbh_endpoint_cfg ep0_cfg = { 0 }; ep0_cfg.ep_addr = 0x00; @@ -471,7 +480,14 @@ int usbh_hport_activate_ep0(struct usbh_hubport *hport) ep0_cfg.ep_type = USB_ENDPOINT_TYPE_CONTROL; ep0_cfg.hport = hport; - usbh_pipe_alloc(&hport->ep0, &ep0_cfg); + if (USB_HC_XHCI == usb->usb_hc_type) { + xhci_usbh_pipe_alloc(&hport->ep0, &ep0_cfg); + } + else { + USB_LOG_WRN("invalid usb controller type %d \r\n", usb->usb_hc_type); + return -EINVAL; + } + return 0; } @@ -485,7 +501,13 @@ int usbh_hport_deactivate_ep0(struct usbh_hubport *hport) } #endif if (hport->ep0) { - usbh_pipe_free(hport->ep0); + if (USB_HC_XHCI == usb->usb_hc_type) { + xhci_usbh_pipe_free(hport->ep0); + } + else { + USB_LOG_WRN("invalid usb controller type %d \r\n", usb->usb_hc_type); + return -EINVAL; + } } hport->ep0 = NULL; @@ -495,6 +517,7 @@ int usbh_hport_deactivate_ep0(struct usbh_hubport *hport) int usbh_hport_activate_epx(usbh_pipe_t *pipe, struct usbh_hubport *hport, struct usb_endpoint_descriptor *ep_desc) { + struct usbh_bus *usb = usbh_get_bus_of_port(hport); struct usbh_endpoint_cfg ep_cfg = { 0 }; ep_cfg.ep_addr = ep_desc->bEndpointAddress; @@ -511,7 +534,13 @@ int usbh_hport_activate_epx(usbh_pipe_t *pipe, struct usbh_hubport *hport, struc ep_cfg.ep_interval, ep_cfg.mult); - return usbh_pipe_alloc(pipe, &ep_cfg); + if (USB_HC_XHCI == usb->usb_hc_type) { + return xhci_usbh_pipe_alloc(pipe, &ep_cfg); + } + else { + USB_LOG_WRN("invalid usb controller type %d \r\n", usb->usb_hc_type); + return -EINVAL; + } } int usbh_enumerate(struct usbh_hubport *hport) @@ -535,7 +564,7 @@ int usbh_enumerate(struct usbh_hubport *hport) setup->wLength = 8; dev_desc = (struct usb_device_descriptor *)usb->ep0_request_buffer; - ret = usbh_control_transfer(hport->ep0, setup, (uint8_t *)dev_desc); + ret = usbh_control_transfer_msg(usb->usb_hc_type, hport->ep0, setup, (uint8_t *)dev_desc); if (ret < 0) { USB_LOG_ERR("Failed to get device descriptor,errorcode:%d\r\n", ret); goto errout; @@ -558,14 +587,22 @@ int usbh_enumerate(struct usbh_hubport *hport) usbh_ep_pipe_reconfigure(usb, hport->ep0, 0, ep_mps, 0); #ifdef CONFIG_USBHOST_XHCI - extern int usbh_get_xhci_devaddr(usbh_pipe_t * pipe); + if (USB_HC_XHCI == usb->usb_hc_type) { + extern int usbh_get_xhci_devaddr(usbh_pipe_t * pipe); + + /* Assign a function address to the device connected to this port */ + dev_addr = usbh_get_xhci_devaddr(hport->ep0); + if (dev_addr < 0) { + USB_LOG_ERR("Failed to allocate devaddr,errorcode:%d\r\n", ret); + goto errout; + } - /* Assign a function address to the device connected to this port */ - dev_addr = usbh_get_xhci_devaddr(hport->ep0); - if (dev_addr < 0) { - USB_LOG_ERR("Failed to allocate devaddr,errorcode:%d\r\n", ret); + } + else { + USB_LOG_WRN("invalid usb controller type %d \r\n", usb->usb_hc_type); goto errout; } + #else /* Assign a function address to the device connected to this port */ dev_addr = usbh_allocate_devaddr(&usb->devgen); @@ -582,7 +619,7 @@ int usbh_enumerate(struct usbh_hubport *hport) setup->wIndex = 0; setup->wLength = 0; - ret = usbh_control_transfer(hport->ep0, setup, NULL); + ret = usbh_control_transfer_msg(usb->usb_hc_type, hport->ep0, setup, NULL); if (ret < 0) { USB_LOG_ERR("Failed to set devaddr,errorcode:%d\r\n", ret); goto errout; @@ -604,7 +641,7 @@ int usbh_enumerate(struct usbh_hubport *hport) setup->wIndex = 0; setup->wLength = USB_SIZEOF_DEVICE_DESC; - ret = usbh_control_transfer(hport->ep0, setup, usb->ep0_request_buffer); + ret = usbh_control_transfer_msg(usb->usb_hc_type, hport->ep0, setup, usb->ep0_request_buffer); if (ret < 0) { USB_LOG_ERR("Failed to get full device descriptor,errorcode:%d\r\n", ret); goto errout; @@ -623,7 +660,7 @@ int usbh_enumerate(struct usbh_hubport *hport) setup->wIndex = 0; setup->wLength = USB_SIZEOF_CONFIG_DESC; - ret = usbh_control_transfer(hport->ep0, setup, usb->ep0_request_buffer); + ret = usbh_control_transfer_msg(usb->usb_hc_type, hport->ep0, setup, usb->ep0_request_buffer); if (ret < 0) { USB_LOG_ERR("Failed to get config descriptor,errorcode:%d\r\n", ret); goto errout; @@ -640,7 +677,7 @@ int usbh_enumerate(struct usbh_hubport *hport) setup->wIndex = 0; setup->wLength = wTotalLength; - ret = usbh_control_transfer(hport->ep0, setup, usb->ep0_request_buffer); + ret = usbh_control_transfer_msg(usb->usb_hc_type, hport->ep0, setup, usb->ep0_request_buffer); if (ret < 0) { USB_LOG_ERR("Failed to get full config descriptor,errorcode:%d\r\n", ret); goto errout; @@ -667,7 +704,7 @@ int usbh_enumerate(struct usbh_hubport *hport) setup->wIndex = 0x0409; setup->wLength = 255; - ret = usbh_control_transfer(hport->ep0, setup, usb->ep0_request_buffer); + ret = usbh_control_transfer_msg(usb->usb_hc_type, hport->ep0, setup, usb->ep0_request_buffer); if (ret < 0) { USB_LOG_ERR("Failed to get Manufacturer string,errorcode:%d\r\n", ret); goto errout; @@ -682,7 +719,7 @@ int usbh_enumerate(struct usbh_hubport *hport) setup->wIndex = 0x0409; setup->wLength = 255; - ret = usbh_control_transfer(hport->ep0, setup, usb->ep0_request_buffer); + ret = usbh_control_transfer_msg(usb->usb_hc_type, hport->ep0, setup, usb->ep0_request_buffer); if (ret < 0) { USB_LOG_ERR("Failed to get get Product string,errorcode:%d\r\n", ret); goto errout; @@ -697,7 +734,7 @@ int usbh_enumerate(struct usbh_hubport *hport) setup->wIndex = 0x0409; setup->wLength = 255; - ret = usbh_control_transfer(hport->ep0, setup, usb->ep0_request_buffer); + ret = usbh_control_transfer_msg(usb->usb_hc_type, hport->ep0, setup, usb->ep0_request_buffer); if (ret < 0) { USB_LOG_ERR("Failed to get get SerialNumber string,errorcode:%d\r\n", ret); goto errout; @@ -712,7 +749,7 @@ int usbh_enumerate(struct usbh_hubport *hport) setup->wIndex = 0; setup->wLength = 0; - ret = usbh_control_transfer(hport->ep0, setup, NULL); + ret = usbh_control_transfer_msg(usb->usb_hc_type, hport->ep0, setup, NULL); if (ret < 0) { USB_LOG_ERR("Failed to set configuration,errorcode:%d\r\n", ret); goto errout; @@ -853,6 +890,31 @@ int usbh_control_transfer(usbh_pipe_t pipe, struct usb_setup_packet *setup, uint return ret; } +int usbh_control_transfer_msg(uint8_t hc_type, usbh_pipe_t pipe, struct usb_setup_packet *setup, uint8_t *buffer) +{ + struct usbh_urb *urb; + int ret; + + urb = usb_malloc(sizeof(struct usbh_urb)); + memset(urb, 0, sizeof(struct usbh_urb)); + + usbh_control_urb_fill(urb, pipe, setup, buffer, setup->wLength, CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT, NULL, NULL); + + if (USB_HC_XHCI == hc_type) { + ret = xhci_usbh_submit_urb(urb); + if (ret == 0) { + ret = urb->actual_length; + } + } + else { + USB_LOG_WRN("invalid usb controller type %d \r\n", hc_type); + ret = -EINVAL; + } + + usb_free(urb); + return ret; +} + int lsusb(int argc, char **argv) { usb_slist_t *i; @@ -945,4 +1007,4 @@ int lsusb(int argc, char **argv) } return 0; -} \ No newline at end of file +} diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/core/usbh_core.h b/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/core/usbh_core.h index ddc40012b..6022c7ef2 100644 --- a/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/core/usbh_core.h +++ b/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/core/usbh_core.h @@ -1,3 +1,22 @@ +/* + * Copyright (c) 2022, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/************************************************* +File name: usbh_core.c +Description: adopt cherry USB to XiZi AIOT. +Others: CherryUSB third-party/cherryusb/core/usbh_core.h for references + https://gitee.com/phytium_embedded/phytium-free-rtos-sdk/blob/master/third-party/cherryusb/core/usbh_core.h + +History: +1. Date: 2024-06-18 +Author: AIIT XUOS Lab +Modification: new parameter usb_hc_type for host controller type. +*************************************************/ + + #ifndef USBH_CORE_H_ #define USBH_CORE_H_ @@ -21,6 +40,14 @@ extern "C" { #endif +/** + * @brief USB host controller type. + * USB 1.1 OHCI UHCI + * USB 2.0 EHCI DWC2 + * USB 3.0 XHCI DWC3 + */ +#define USB_HC_XHCI 5 +#define USB_HC_DWC3 6 #define USB_CLASS_MATCH_VENDOR 0x0001 #define USB_CLASS_MATCH_PRODUCT 0x0002 @@ -40,7 +67,6 @@ extern "C" { #define CLASS_INFO_DEFINE __attribute__((section("usbh_class_info"))) __USED __ALIGNED(1) #endif - static inline void usbh_control_urb_fill(struct usbh_urb *urb, usbh_pipe_t pipe, struct usb_setup_packet *setup, @@ -59,8 +85,6 @@ static inline void usbh_control_urb_fill(struct usbh_urb *urb, urb->arg = arg; } - - static inline void usbh_bulk_urb_fill(struct usbh_urb *urb, usbh_pipe_t pipe, uint8_t *transfer_buffer, @@ -78,8 +102,6 @@ static inline void usbh_bulk_urb_fill(struct usbh_urb *urb, urb->arg = arg; } - - static inline void usbh_int_urb_fill(struct usbh_urb *urb, usbh_pipe_t pipe, uint8_t *transfer_buffer, @@ -97,8 +119,6 @@ static inline void usbh_int_urb_fill(struct usbh_urb *urb, urb->arg = arg; } - - struct usbh_class_info { uint8_t match_flags; /* Used for product specific matches; range is inclusive */ uint8_t class; /* Base device class code */ @@ -109,17 +129,13 @@ struct usbh_class_info { const struct usbh_class_driver *class_driver; }; - struct usbh_hubport; - struct usbh_class_driver { const char *driver_name; int (*connect)(struct usbh_hubport *hport, uint8_t intf); int (*disconnect)(struct usbh_hubport *hport, uint8_t intf); }; - - struct usbh_endpoint { struct usb_endpoint_descriptor ep_desc; }; @@ -143,8 +159,6 @@ struct usbh_configuration { }; struct usbh_hub; - - struct usbh_hubport { /** Name */ char name[32]; @@ -167,9 +181,7 @@ struct usbh_hubport { }; - struct usbh_bus; - struct usbh_hub { usb_slist_t list; bool connected; @@ -189,7 +201,6 @@ struct usbh_hub { USB_MEM_ALIGNX uint8_t g_hub_intbuf[CONFIG_USBHOST_MAX_EXTHUBS + 1][1]; }; - int usbh_hport_activate_epx(usbh_pipe_t *pipe, struct usbh_hubport *hport, struct usb_endpoint_descriptor *ep_desc); /** @@ -204,6 +215,8 @@ int usbh_hport_activate_epx(usbh_pipe_t *pipe, struct usbh_hubport *hport, struc */ int usbh_control_transfer(usbh_pipe_t pipe, struct usb_setup_packet *setup, uint8_t *buffer); +int usbh_control_transfer_msg(uint8_t hc_type, usbh_pipe_t pipe, struct usb_setup_packet *setup, uint8_t *buffer); + struct usbh_devaddr_map { /** * alloctab[0]:addr from 0~31 @@ -219,6 +232,7 @@ struct usbh_devaddr_map { struct usbh_bus { usb_slist_t list; uint8_t id; + uint8_t usb_hc_type; /** Largest transfer allowed on the bus */ size_t mtu; struct usbh_devaddr_map devgen; @@ -282,11 +296,8 @@ struct usbh_hubport *usbh_find_hubport(uint32_t id, uint8_t dev_addr); void *usbh_find_class_instance(const char *devname); int lsusb(int argc, char **argv); - #ifdef __cplusplus } #endif - - -#endif +#endif /* USBH_CORE_H */