forked from xuos/xiuos
Decoupling core and xhci.
This commit is contained in:
parent
303737e590
commit
d4f72f2ad9
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue