Modify USB core code to decouple from xhci.

This commit is contained in:
songyanguang 2024-06-20 17:44:51 +08:00
parent 545c240c8d
commit 7f188bff03
3 changed files with 103 additions and 77 deletions

View File

@ -100,6 +100,14 @@ uint16_t usbh_get_frame_number(void);
*/ */
int usbh_roothub_control(struct usbh_bus *usb, struct usb_setup_packet *setup, uint8_t *buf); int usbh_roothub_control(struct usbh_bus *usb, struct usb_setup_packet *setup, uint8_t *buf);
/**
* @brief get device address.
*
* @param hport Hub port of USB device
* @return On success will return device address, and others indicate fail.
*/
int usbh_get_devaddr(struct usbh_hubport *hport);
/** /**
* @brief reconfig endpoint pipe. * @brief reconfig endpoint pipe.
* *
@ -127,6 +135,7 @@ int usbh_pipe_alloc(usbh_pipe_t *pipe, const struct usbh_endpoint_cfg *ep_cfg);
* @return On success will return 0, and others indicate fail. * @return On success will return 0, and others indicate fail.
*/ */
int usbh_pipe_free(usbh_pipe_t pipe); int usbh_pipe_free(usbh_pipe_t pipe);
int usbh_pipe_free_xiuos(struct usbh_hubport *hport, usbh_pipe_t pipe);
/** /**
* @brief Submit a usb transfer request to an endpoint. * @brief Submit a usb transfer request to an endpoint.

View File

@ -90,20 +90,20 @@ struct usbh_bus* usbh_get_bus_of_devname(const char *devname)
/** /**
* Get USB transaction translator * Get USB transaction translator
* *
* @v hport Hub port of USB device * @v hport Hub port of USB device
* @ret port Transaction translator port, or NULL * @ret port Transaction translator port, or NULL
*/ */
struct usbh_hubport *usbh_transaction_translator ( struct usbh_hubport *hport ) { struct usbh_hubport *usbh_transaction_translator ( struct usbh_hubport *hport ) {
struct usbh_hubport *parent; struct usbh_hubport *parent;
if (hport->parent->is_roothub) { if (hport->parent->is_roothub) {
return NULL; return NULL;
} }
/* Navigate up to root hub. If we find a low-speed or /* Navigate up to root hub. If we find a low-speed or
* full-speed device with a higher-speed parent hub, then that * full-speed device with a higher-speed parent hub, then that
* device's port is the transaction translator. * device's port is the transaction translator.
*/ */
for (; (parent = hport->parent->parent); hport = parent) { for (; (parent = hport->parent->parent); hport = parent) {
if ((hport->speed <= USB_SPEED_FULL) && if ((hport->speed <= USB_SPEED_FULL) &&
(parent->speed > USB_SPEED_FULL)) { (parent->speed > USB_SPEED_FULL)) {
@ -117,18 +117,18 @@ struct usbh_hubport *usbh_transaction_translator ( struct usbh_hubport *hport )
/** /**
* Get USB route string * Get USB route string
* *
* @v hport Hub Port of USB device * @v hport Hub Port of USB device
* @ret route USB route string * @ret route USB route string
*/ */
unsigned int usbh_route_string ( struct usbh_hubport *hport ) { unsigned int usbh_route_string ( struct usbh_hubport *hport ) {
struct usbh_hubport *parent; struct usbh_hubport *parent;
unsigned int route; unsigned int route;
/* Navigate up to root hub, constructing route string as we go */ /* Navigate up to root hub, constructing route string as we go */
for (route = 0; (parent = hport->parent->parent); hport = parent) { for (route = 0; (parent = hport->parent->parent); hport = parent) {
route <<= 4; route <<= 4;
route |= ( ( hport->dev_addr > 0xf ) ? route |= ( ( hport->dev_addr > 0xf ) ?
0xf : hport->dev_addr ); 0xf : hport->dev_addr );
} }
return route; return route;
@ -137,8 +137,8 @@ unsigned int usbh_route_string ( struct usbh_hubport *hport ) {
/** /**
* Get USB root hub port * Get USB root hub port
* *
* @v usb USB device * @v usb USB device
* @ret port Root hub port * @ret port Root hub port
*/ */
struct usbh_hubport * usbh_root_hub_port ( struct usbh_hubport *hport ) { struct usbh_hubport * usbh_root_hub_port ( struct usbh_hubport *hport ) {
struct usbh_hubport *parent; struct usbh_hubport *parent;
@ -483,13 +483,7 @@ 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;
if (USB_HC_XHCI == usb->usb_hc_type) { usbh_pipe_alloc(&hport->ep0, &ep0_cfg);
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;
} }
@ -504,13 +498,7 @@ int usbh_hport_deactivate_ep0(struct usbh_hubport *hport)
} }
#endif #endif
if (hport->ep0) { if (hport->ep0) {
if (USB_HC_XHCI == usb->usb_hc_type) { usbh_pipe_free_xiuos(hport, hport->ep0);
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;
@ -520,7 +508,6 @@ 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;
@ -537,13 +524,7 @@ 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);
if (USB_HC_XHCI == usb->usb_hc_type) { return usbh_pipe_alloc(pipe, &ep_cfg);
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)
@ -567,7 +548,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_msg(usb->usb_hc_type, hport->ep0, setup, (uint8_t *)dev_desc); ret = usbh_control_transfer_xiuos(hport, 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;
@ -589,30 +570,12 @@ int usbh_enumerate(struct usbh_hubport *hport)
/* Reconfigure EP0 with the correct maximum packet size */ /* Reconfigure EP0 with the correct maximum packet size */
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
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;
}
}
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 */ /* Assign a function address to the device connected to this port */
dev_addr = usbh_allocate_devaddr(&usb->devgen); dev_addr = usbh_get_devaddr(hport);
if (dev_addr < 0) { if (dev_addr < 0) {
USB_LOG_ERR("Failed to allocate devaddr,errorcode:%d\r\n", ret); USB_LOG_ERR("Failed to allocate devaddr,errorcode:%d\r\n", ret);
goto errout; goto errout;
} }
#endif
/* Set the USB device address */ /* Set the USB device address */
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE; setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
@ -621,7 +584,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
setup->wIndex = 0; setup->wIndex = 0;
setup->wLength = 0; setup->wLength = 0;
ret = usbh_control_transfer_msg(usb->usb_hc_type, hport->ep0, setup, NULL); ret = usbh_control_transfer_xiuos(hport, 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;
@ -643,7 +606,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_msg(usb->usb_hc_type, hport->ep0, setup, usb->ep0_request_buffer); ret = usbh_control_transfer_xiuos(hport, 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;
@ -662,7 +625,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_msg(usb->usb_hc_type, hport->ep0, setup, usb->ep0_request_buffer); ret = usbh_control_transfer_xiuos(hport, 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;
@ -679,7 +642,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
setup->wIndex = 0; setup->wIndex = 0;
setup->wLength = wTotalLength; setup->wLength = wTotalLength;
ret = usbh_control_transfer_msg(usb->usb_hc_type, hport->ep0, setup, usb->ep0_request_buffer); ret = usbh_control_transfer_xiuos(hport, 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;
@ -706,7 +669,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
setup->wIndex = 0x0409; setup->wIndex = 0x0409;
setup->wLength = 255; setup->wLength = 255;
ret = usbh_control_transfer_msg(usb->usb_hc_type, hport->ep0, setup, usb->ep0_request_buffer); ret = usbh_control_transfer_xiuos(hport, 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;
@ -721,7 +684,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
setup->wIndex = 0x0409; setup->wIndex = 0x0409;
setup->wLength = 255; setup->wLength = 255;
ret = usbh_control_transfer_msg(usb->usb_hc_type, hport->ep0, setup, usb->ep0_request_buffer); ret = usbh_control_transfer_xiuos(hport, 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;
@ -736,7 +699,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
setup->wIndex = 0x0409; setup->wIndex = 0x0409;
setup->wLength = 255; setup->wLength = 255;
ret = usbh_control_transfer_msg(usb->usb_hc_type, hport->ep0, setup, usb->ep0_request_buffer); ret = usbh_control_transfer_xiuos(hport, 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;
@ -751,7 +714,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
setup->wIndex = 0; setup->wIndex = 0;
setup->wLength = 0; setup->wLength = 0;
ret = usbh_control_transfer_msg(usb->usb_hc_type, hport->ep0, setup, NULL); ret = usbh_control_transfer_xiuos(hport, 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;
@ -892,27 +855,22 @@ 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) int usbh_control_transfer_xiuos(struct usbh_hubport *hport, usbh_pipe_t pipe, struct usb_setup_packet *setup, uint8_t *buffer)
{ {
struct usbh_bus *usb = usbh_get_bus_of_port(hport);
struct usbh_urb *urb; struct usbh_urb *urb;
int ret; int ret;
urb = usb_malloc(sizeof(struct usbh_urb)); urb = usb_malloc(sizeof(struct usbh_urb));
memset(urb, 0, sizeof(struct usbh_urb)); memset(urb, 0, sizeof(struct usbh_urb));
urb->usb_hc_type = usb->usb_hc_type;
usbh_control_urb_fill(urb, pipe, setup, buffer, setup->wLength, CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT, NULL, NULL); usbh_control_urb_fill(urb, pipe, setup, buffer, setup->wLength, CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT, NULL, NULL);
if (USB_HC_XHCI == hc_type) { ret = usbh_submit_urb(urb);
ret = xhci_usbh_submit_urb(urb); if (ret == 0) {
if (ret == 0) { ret = urb->actual_length;
ret = urb->actual_length;
}
} }
else {
USB_LOG_WRN("invalid usb controller type %d \r\n", hc_type);
ret = -EINVAL;
}
usb_free(urb); usb_free(urb);
return ret; return ret;
} }
@ -1029,7 +987,18 @@ int usbh_ep_pipe_reconfigure(struct usbh_bus *usb, usbh_pipe_t pipe, uint8_t dev
int usbh_pipe_alloc(usbh_pipe_t *pipe, const struct usbh_endpoint_cfg *ep_cfg) int usbh_pipe_alloc(usbh_pipe_t *pipe, const struct usbh_endpoint_cfg *ep_cfg)
{ {
return 0; struct usbh_bus *usb = usbh_get_bus_of_port(ep_cfg->hport);
int rc = 0;
if (USB_HC_XHCI == usb->usb_hc_type) {
rc = xhci_usbh_pipe_alloc(pipe, ep_cfg);
}
else {
USB_LOG_WRN("invalid usb controller type %d \r\n", usb->usb_hc_type);
return -EINVAL;
}
return rc;
} }
int usbh_get_xhci_devaddr(usbh_pipe_t *pipe) int usbh_get_xhci_devaddr(usbh_pipe_t *pipe)
@ -1037,14 +1006,62 @@ int usbh_get_xhci_devaddr(usbh_pipe_t *pipe)
return 0; return 0;
} }
int usbh_get_devaddr(struct usbh_hubport *hport)
{
int dev_addr;
struct usbh_bus *usb = usbh_get_bus_of_port(hport);
#ifdef CONFIG_USBHOST_XHCI
if (USB_HC_XHCI == usb->usb_hc_type) {
/* Assign a function address to the device connected to this port */
dev_addr = usbh_get_xhci_devaddr(hport->ep0);
}
else {
USB_LOG_WRN("invalid usb controller type %d \r\n", usb->usb_hc_type);
return -EINVAL;
}
#else
/* Assign a function address to the device connected to this port */
dev_addr = usbh_allocate_devaddr(&usb->devgen);
#endif
return dev_addr;
}
int usbh_pipe_free(usbh_pipe_t pipe) int usbh_pipe_free(usbh_pipe_t pipe)
{ {
return 0; return 0;
} }
int usbh_pipe_free_xiuos(struct usbh_hubport *hport, usbh_pipe_t pipe)
{
int ret = 0;
struct usbh_bus *usb = usbh_get_bus_of_port(hport);
if (USB_HC_XHCI == usb->usb_hc_type) {
ret = xhci_usbh_pipe_free(hport->ep0);
}
else {
USB_LOG_WRN("invalid usb controller type %d \r\n", usb->usb_hc_type);
return -EINVAL;
}
return ret;
}
int usbh_submit_urb(struct usbh_urb *urb) int usbh_submit_urb(struct usbh_urb *urb)
{ {
return 0; int ret;
if (USB_HC_XHCI == urb->usb_hc_type) {
ret = xhci_usbh_submit_urb(urb);
}
else {
USB_LOG_WRN("invalid usb controller type %d \r\n", urb->usb_hc_type);
ret = -EINVAL;
}
return ret;
} }
int usbh_kill_urb(struct usbh_urb *urb) int usbh_kill_urb(struct usbh_urb *urb)

View File

@ -215,7 +215,7 @@ 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); int usbh_control_transfer_xiuos(struct usbh_hubport *hport, usbh_pipe_t pipe, struct usb_setup_packet *setup, uint8_t *buffer);
struct usbh_devaddr_map { struct usbh_devaddr_map {
/** /**