Decoupling core and xhci.

This commit is contained in:
songyanguang 2024-06-18 16:09:32 +08:00
parent 303737e590
commit d4f72f2ad9
2 changed files with 112 additions and 39 deletions

View File

@ -3,16 +3,24 @@
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
/************************************************* /*************************************************
File name: usbh_core.c File name: usbh_core.c
Description: adopt cherry USB to XiZi AIOT. Description: adopt cherry USB to XiZi AIOT.
Others: CherryUSB third-party/cherryusb/core/usbh_core.c for references 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 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_core.h"
#include "usbh_hub.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_begin = NULL;
struct usbh_class_info *usbh_class_info_table_end = 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) 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 }; struct usbh_endpoint_cfg ep0_cfg = { 0 };
ep0_cfg.ep_addr = 0x00; 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.ep_type = USB_ENDPOINT_TYPE_CONTROL;
ep0_cfg.hport = hport; 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; return 0;
} }
@ -485,7 +501,13 @@ int usbh_hport_deactivate_ep0(struct usbh_hubport *hport)
} }
#endif #endif
if (hport->ep0) { 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; 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) 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 }; struct usbh_endpoint_cfg ep_cfg = { 0 };
ep_cfg.ep_addr = ep_desc->bEndpointAddress; 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.ep_interval,
ep_cfg.mult); 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) int usbh_enumerate(struct usbh_hubport *hport)
@ -535,7 +564,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
setup->wLength = 8; setup->wLength = 8;
dev_desc = (struct usb_device_descriptor *)usb->ep0_request_buffer; 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) { if (ret < 0) {
USB_LOG_ERR("Failed to get device descriptor,errorcode:%d\r\n", ret); USB_LOG_ERR("Failed to get device descriptor,errorcode:%d\r\n", ret);
goto errout; goto errout;
@ -558,14 +587,22 @@ int usbh_enumerate(struct usbh_hubport *hport)
usbh_ep_pipe_reconfigure(usb, hport->ep0, 0, ep_mps, 0); usbh_ep_pipe_reconfigure(usb, hport->ep0, 0, ep_mps, 0);
#ifdef CONFIG_USBHOST_XHCI #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); else {
if (dev_addr < 0) { USB_LOG_WRN("invalid usb controller type %d \r\n", usb->usb_hc_type);
USB_LOG_ERR("Failed to allocate devaddr,errorcode:%d\r\n", ret);
goto errout; goto errout;
} }
#else #else
/* Assign a function address to the device connected to this port */ /* Assign a function address to the device connected to this port */
dev_addr = usbh_allocate_devaddr(&usb->devgen); dev_addr = usbh_allocate_devaddr(&usb->devgen);
@ -582,7 +619,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
setup->wIndex = 0; setup->wIndex = 0;
setup->wLength = 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) { if (ret < 0) {
USB_LOG_ERR("Failed to set devaddr,errorcode:%d\r\n", ret); USB_LOG_ERR("Failed to set devaddr,errorcode:%d\r\n", ret);
goto errout; goto errout;
@ -604,7 +641,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
setup->wIndex = 0; setup->wIndex = 0;
setup->wLength = USB_SIZEOF_DEVICE_DESC; 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) { if (ret < 0) {
USB_LOG_ERR("Failed to get full device descriptor,errorcode:%d\r\n", ret); USB_LOG_ERR("Failed to get full device descriptor,errorcode:%d\r\n", ret);
goto errout; goto errout;
@ -623,7 +660,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
setup->wIndex = 0; setup->wIndex = 0;
setup->wLength = USB_SIZEOF_CONFIG_DESC; 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) { if (ret < 0) {
USB_LOG_ERR("Failed to get config descriptor,errorcode:%d\r\n", ret); USB_LOG_ERR("Failed to get config descriptor,errorcode:%d\r\n", ret);
goto errout; goto errout;
@ -640,7 +677,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
setup->wIndex = 0; setup->wIndex = 0;
setup->wLength = wTotalLength; 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) { if (ret < 0) {
USB_LOG_ERR("Failed to get full config descriptor,errorcode:%d\r\n", ret); USB_LOG_ERR("Failed to get full config descriptor,errorcode:%d\r\n", ret);
goto errout; goto errout;
@ -667,7 +704,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
setup->wIndex = 0x0409; setup->wIndex = 0x0409;
setup->wLength = 255; 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) { if (ret < 0) {
USB_LOG_ERR("Failed to get Manufacturer string,errorcode:%d\r\n", ret); USB_LOG_ERR("Failed to get Manufacturer string,errorcode:%d\r\n", ret);
goto errout; goto errout;
@ -682,7 +719,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
setup->wIndex = 0x0409; setup->wIndex = 0x0409;
setup->wLength = 255; 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) { if (ret < 0) {
USB_LOG_ERR("Failed to get get Product string,errorcode:%d\r\n", ret); USB_LOG_ERR("Failed to get get Product string,errorcode:%d\r\n", ret);
goto errout; goto errout;
@ -697,7 +734,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
setup->wIndex = 0x0409; setup->wIndex = 0x0409;
setup->wLength = 255; 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) { if (ret < 0) {
USB_LOG_ERR("Failed to get get SerialNumber string,errorcode:%d\r\n", ret); USB_LOG_ERR("Failed to get get SerialNumber string,errorcode:%d\r\n", ret);
goto errout; goto errout;
@ -712,7 +749,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
setup->wIndex = 0; setup->wIndex = 0;
setup->wLength = 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) { if (ret < 0) {
USB_LOG_ERR("Failed to set configuration,errorcode:%d\r\n", ret); USB_LOG_ERR("Failed to set configuration,errorcode:%d\r\n", ret);
goto errout; goto errout;
@ -853,6 +890,31 @@ int usbh_control_transfer(usbh_pipe_t pipe, struct usb_setup_packet *setup, uint
return ret; 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) int lsusb(int argc, char **argv)
{ {
usb_slist_t *i; usb_slist_t *i;
@ -945,4 +1007,4 @@ int lsusb(int argc, char **argv)
} }
return 0; return 0;
} }

View File

@ -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_ #ifndef USBH_CORE_H_
#define USBH_CORE_H_ #define USBH_CORE_H_
@ -21,6 +40,14 @@
extern "C" { extern "C" {
#endif #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_VENDOR 0x0001
#define USB_CLASS_MATCH_PRODUCT 0x0002 #define USB_CLASS_MATCH_PRODUCT 0x0002
@ -40,7 +67,6 @@ extern "C" {
#define CLASS_INFO_DEFINE __attribute__((section("usbh_class_info"))) __USED __ALIGNED(1) #define CLASS_INFO_DEFINE __attribute__((section("usbh_class_info"))) __USED __ALIGNED(1)
#endif #endif
static inline void usbh_control_urb_fill(struct usbh_urb *urb, static inline void usbh_control_urb_fill(struct usbh_urb *urb,
usbh_pipe_t pipe, usbh_pipe_t pipe,
struct usb_setup_packet *setup, struct usb_setup_packet *setup,
@ -59,8 +85,6 @@ static inline void usbh_control_urb_fill(struct usbh_urb *urb,
urb->arg = arg; urb->arg = arg;
} }
static inline void usbh_bulk_urb_fill(struct usbh_urb *urb, static inline void usbh_bulk_urb_fill(struct usbh_urb *urb,
usbh_pipe_t pipe, usbh_pipe_t pipe,
uint8_t *transfer_buffer, uint8_t *transfer_buffer,
@ -78,8 +102,6 @@ static inline void usbh_bulk_urb_fill(struct usbh_urb *urb,
urb->arg = arg; urb->arg = arg;
} }
static inline void usbh_int_urb_fill(struct usbh_urb *urb, static inline void usbh_int_urb_fill(struct usbh_urb *urb,
usbh_pipe_t pipe, usbh_pipe_t pipe,
uint8_t *transfer_buffer, uint8_t *transfer_buffer,
@ -97,8 +119,6 @@ static inline void usbh_int_urb_fill(struct usbh_urb *urb,
urb->arg = arg; urb->arg = arg;
} }
struct usbh_class_info { struct usbh_class_info {
uint8_t match_flags; /* Used for product specific matches; range is inclusive */ uint8_t match_flags; /* Used for product specific matches; range is inclusive */
uint8_t class; /* Base device class code */ uint8_t class; /* Base device class code */
@ -109,17 +129,13 @@ struct usbh_class_info {
const struct usbh_class_driver *class_driver; const struct usbh_class_driver *class_driver;
}; };
struct usbh_hubport; struct usbh_hubport;
struct usbh_class_driver { struct usbh_class_driver {
const char *driver_name; const char *driver_name;
int (*connect)(struct usbh_hubport *hport, uint8_t intf); int (*connect)(struct usbh_hubport *hport, uint8_t intf);
int (*disconnect)(struct usbh_hubport *hport, uint8_t intf); int (*disconnect)(struct usbh_hubport *hport, uint8_t intf);
}; };
struct usbh_endpoint { struct usbh_endpoint {
struct usb_endpoint_descriptor ep_desc; struct usb_endpoint_descriptor ep_desc;
}; };
@ -143,8 +159,6 @@ struct usbh_configuration {
}; };
struct usbh_hub; struct usbh_hub;
struct usbh_hubport { struct usbh_hubport {
/** Name */ /** Name */
char name[32]; char name[32];
@ -167,9 +181,7 @@ struct usbh_hubport {
}; };
struct usbh_bus; struct usbh_bus;
struct usbh_hub { struct usbh_hub {
usb_slist_t list; usb_slist_t list;
bool connected; bool connected;
@ -189,7 +201,6 @@ struct usbh_hub {
USB_MEM_ALIGNX uint8_t g_hub_intbuf[CONFIG_USBHOST_MAX_EXTHUBS + 1][1]; 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); 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(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 { struct usbh_devaddr_map {
/** /**
* alloctab[0]:addr from 0~31 * alloctab[0]:addr from 0~31
@ -219,6 +232,7 @@ struct usbh_devaddr_map {
struct usbh_bus { struct usbh_bus {
usb_slist_t list; usb_slist_t list;
uint8_t id; uint8_t id;
uint8_t usb_hc_type;
/** Largest transfer allowed on the bus */ /** Largest transfer allowed on the bus */
size_t mtu; size_t mtu;
struct usbh_devaddr_map devgen; 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); void *usbh_find_class_instance(const char *devname);
int lsusb(int argc, char **argv); int lsusb(int argc, char **argv);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* USBH_CORE_H */
#endif