update hub process for usb3.0, update xhci driver

This commit is contained in:
sakimisu
2023-04-21 23:43:59 +08:00
parent dc4887aef1
commit 5657b2a028
7 changed files with 219 additions and 42 deletions

View File

@@ -7,7 +7,8 @@
#define USB_HUB_H #define USB_HUB_H
/* HUB Class Descriptor Types */ /* HUB Class Descriptor Types */
#define HUB_DESCRIPTOR_TYPE_HUB 0x29 #define HUB_DESCRIPTOR_TYPE_HUB 0x29
#define HUB_DESCRIPTOR_TYPE_HUB3 0x2A
/* Hub class requests */ /* Hub class requests */
#define HUB_REQUEST_GET_STATUS USB_REQUEST_GET_STATUS #define HUB_REQUEST_GET_STATUS USB_REQUEST_GET_STATUS
@@ -19,6 +20,7 @@
#define HUB_REQUEST_RESET_TT (0x09) #define HUB_REQUEST_RESET_TT (0x09)
#define HUB_REQUEST_GET_TT_STATE (0x0a) #define HUB_REQUEST_GET_TT_STATE (0x0a)
#define HUB_REQUEST_STOP_TT (0x0b) #define HUB_REQUEST_STOP_TT (0x0b)
#define HUB_REQUEST_SET_HUB_DEPTH (0x0C)
/* Hub class features */ /* Hub class features */
#define HUB_FEATURE_HUB_C_LOCALPOWER (0x0) #define HUB_FEATURE_HUB_C_LOCALPOWER (0x0)

View File

@@ -38,6 +38,13 @@ static void usbh_hub_thread_wakeup(struct usbh_hub *hub);
static const char *speed_table[] = { "error-speed", "low-speed", "full-speed", "high-speed", "wireless-speed", "super-speed", "superplus-speed" }; static const char *speed_table[] = { "error-speed", "low-speed", "full-speed", "high-speed", "wireless-speed", "super-speed", "superplus-speed" };
#ifdef CONFIG_USBHOST_XHCI
struct usbh_hubport *usbh_get_roothub_port(unsigned int port)
{
return &roothub.child[port - 1];
}
#endif
#if CONFIG_USBHOST_MAX_EXTHUBS > 0 #if CONFIG_USBHOST_MAX_EXTHUBS > 0
static int usbh_hub_devno_alloc(void) static int usbh_hub_devno_alloc(void)
{ {
@@ -82,7 +89,16 @@ static int _usbh_hub_get_hub_descriptor(struct usbh_hub *hub, uint8_t *buffer)
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_DEVICE; setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_DEVICE;
setup->bRequest = USB_REQUEST_GET_DESCRIPTOR; setup->bRequest = USB_REQUEST_GET_DESCRIPTOR;
setup->wValue = HUB_DESCRIPTOR_TYPE_HUB << 8;
/* TODO: hub descriptor has some difference between USB 2.0 and USB 3.x,
and we havn't handle the difference here */
if ((hub->parent->speed == USB_SPEED_SUPER) ||
(hub->parent->speed == USB_SPEED_SUPER_PLUS)) {
setup->wValue = HUB_DESCRIPTOR_TYPE_HUB3 << 8;
} else {
setup->wValue = HUB_DESCRIPTOR_TYPE_HUB << 8;
}
setup->wIndex = 0; setup->wIndex = 0;
setup->wLength = USB_SIZEOF_HUB_DESC; setup->wLength = USB_SIZEOF_HUB_DESC;
@@ -167,6 +183,21 @@ static int _usbh_hub_clear_feature(struct usbh_hub *hub, uint8_t port, uint8_t f
return usbh_control_transfer(hub->parent->ep0, setup, NULL); return usbh_control_transfer(hub->parent->ep0, setup, NULL);
} }
static int _usbh_hub_set_depth(struct usbh_hub *hub, uint16_t depth)
{
struct usb_setup_packet *setup;
setup = hub->parent->setup;
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_DEVICE;
setup->bRequest = HUB_REQUEST_SET_HUB_DEPTH;
setup->wValue = depth;
setup->wIndex = 0;
setup->wLength = 0;
return usbh_control_transfer(hub->parent->ep0, setup, NULL);
}
#if CONFIG_USBHOST_MAX_EXTHUBS > 0 #if CONFIG_USBHOST_MAX_EXTHUBS > 0
static int parse_hub_descriptor(struct usb_hub_descriptor *desc, uint16_t length) static int parse_hub_descriptor(struct usb_hub_descriptor *desc, uint16_t length)
{ {
@@ -245,6 +276,24 @@ static int usbh_hub_clear_feature(struct usbh_hub *hub, uint8_t port, uint8_t fe
} }
} }
static int usbh_hub_set_depth(struct usbh_hub *hub, uint16_t depth)
{
struct usb_setup_packet roothub_setup;
struct usb_setup_packet *setup;
if (hub->is_roothub) {
setup = &roothub_setup;
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_DEVICE;
setup->bRequest = HUB_REQUEST_SET_HUB_DEPTH;
setup->wValue = depth;
setup->wIndex = 0;
setup->wLength = 0;
return usbh_roothub_control(setup, NULL);
} else {
return _usbh_hub_set_depth(hub, depth);
}
}
#if CONFIG_USBHOST_MAX_EXTHUBS > 0 #if CONFIG_USBHOST_MAX_EXTHUBS > 0
static void hub_int_complete_callback(void *arg, int nbytes) static void hub_int_complete_callback(void *arg, int nbytes)
{ {
@@ -297,6 +346,20 @@ static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf)
return -1; return -1;
} }
if (hport->speed == USB_SPEED_SUPER) {
uint16_t depth = 0;
struct usbh_hubport *parent = hport->parent->parent;
while (parent) {
depth++;
parent = parent->parent->parent;
}
ret = usbh_hub_set_depth(hub, depth);
if (ret < 0) {
return ret;
}
}
for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) { for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
ret = usbh_hub_set_feature(hub, port + 1, HUB_PORT_FEATURE_POWER); ret = usbh_hub_set_feature(hub, port + 1, HUB_PORT_FEATURE_POWER);
if (ret < 0) { if (ret < 0) {
@@ -502,9 +565,26 @@ static void usbh_hub_events(struct usbh_hub *hub)
speed = USB_SPEED_HIGH; speed = USB_SPEED_HIGH;
} else if (portstatus & HUB_PORT_STATUS_LOW_SPEED) { } else if (portstatus & HUB_PORT_STATUS_LOW_SPEED) {
speed = USB_SPEED_LOW; speed = USB_SPEED_LOW;
} else { }
#ifdef CONFIG_USBHOST_XHCI
extern uint8_t usbh_get_port_speed(struct usbh_hub * hub, const uint8_t port);
/* USB3.0 speed cannot get from portstatus, checkout port speed instead */
else
{
uint8_t super_speed = usbh_get_port_speed(hub, port + 1);
if (super_speed > USB_SPEED_HIGH) {
/* assert that when using USB 3.0 ports, attached device must also be USB 3.0 speed */
speed = super_speed;
} else {
speed = USB_SPEED_FULL;
}
}
#else
else {
speed = USB_SPEED_FULL; speed = USB_SPEED_FULL;
} }
#endif
child = &hub->child[port]; child = &hub->child[port];
/** release child sources first */ /** release child sources first */
@@ -530,7 +610,9 @@ static void usbh_hub_events(struct usbh_hub *hub)
child = &hub->child[port]; child = &hub->child[port];
/** release child sources */ /** release child sources */
usbh_hubport_release(child); usbh_hubport_release(child);
USB_LOG_ERR("Failed to enable port %u\r\n", port + 1);
/** some USB 3.0 ip may failed to enable USB 2.0 port for USB 3.0 device */
USB_LOG_WRN("Failed to enable port %u\r\n", port + 1);
continue; continue;
} }

View File

@@ -11,6 +11,9 @@
#define USB_2_0 0x0200 #define USB_2_0 0x0200
/* Set USB version to 2.1 so that the host will request the BOS descriptor */ /* Set USB version to 2.1 so that the host will request the BOS descriptor */
#define USB_2_1 0x0210 #define USB_2_1 0x0210
#define USB_3_0 0x0300
#define USB_3_1 0x0310
#define USB_3_2 0x0320
/* Device speeds */ /* Device speeds */
#define USB_SPEED_UNKNOWN 0 /* Transfer rate not yet set */ #define USB_SPEED_UNKNOWN 0 /* Transfer rate not yet set */

View File

@@ -412,6 +412,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
{ {
struct usb_interface_descriptor *intf_desc; struct usb_interface_descriptor *intf_desc;
struct usb_setup_packet *setup; struct usb_setup_packet *setup;
struct usb_device_descriptor *dev_desc;
int dev_addr; int dev_addr;
uint16_t ep_mps; uint16_t ep_mps;
int ret; int ret;
@@ -435,7 +436,16 @@ int usbh_enumerate(struct usbh_hubport *hport)
parse_device_descriptor(hport, (struct usb_device_descriptor *)ep0_request_buffer, 8); parse_device_descriptor(hport, (struct usb_device_descriptor *)ep0_request_buffer, 8);
/* Extract the correct max packetsize from the device descriptor */ /* Extract the correct max packetsize from the device descriptor */
ep_mps = ((struct usb_device_descriptor *)ep0_request_buffer)->bMaxPacketSize0; dev_desc = (struct usb_device_descriptor *)ep0_request_buffer;
if (dev_desc->bcdUSB >= USB_3_0) {
ep_mps = 1 << dev_desc->bMaxPacketSize0;
} else {
ep_mps = dev_desc->bMaxPacketSize0;
}
USB_LOG_DBG("Device rev=%04x cls=%02x sub=%02x proto=%02x size=%d\r\n",
dev_desc->bcdUSB, dev_desc->bDeviceClass, dev_desc->bDeviceSubClass,
dev_desc->bDeviceProtocol, ep_mps);
/* Reconfigure EP0 with the correct maximum packet size */ /* Reconfigure EP0 with the correct maximum packet size */
usbh_ep_pipe_reconfigure(hport->ep0, 0, ep_mps, 0); usbh_ep_pipe_reconfigure(hport->ep0, 0, ep_mps, 0);
@@ -791,4 +801,4 @@ int lsusb(int argc, char **argv)
} }
return 0; return 0;
} }

View File

@@ -149,6 +149,9 @@ struct usbh_hubport {
uint8_t *raw_config_desc; uint8_t *raw_config_desc;
struct usb_setup_packet *setup; struct usb_setup_packet *setup;
struct usbh_hub *parent; struct usbh_hub *parent;
#ifdef CONFIG_USBHOST_XHCI
uint32_t protocol; /* port protocol, for xhci, some ports are USB2.0, others are USB3.0 */
#endif
}; };
struct usbh_hub { struct usbh_hub {

View File

@@ -62,6 +62,14 @@ __WEAK unsigned long usb_hc_get_register_base(void)
return 0U; return 0U;
} }
/**
* Get USB root hub port
*
* @v hport Hub port of USB device
* @ret port Root hub port
*/
extern struct usbh_hubport *usbh_root_hub_port(struct usbh_hubport *hport);
static struct xhci_host xhci_host; static struct xhci_host xhci_host;
/* xhci hardware init */ /* xhci hardware init */

View File

@@ -29,6 +29,75 @@
#include "xhci_reg.h" #include "xhci_reg.h"
#include "xhci.h" #include "xhci.h"
extern struct usbh_hubport *usbh_get_roothub_port(unsigned int port);
/**
* Get USB transaction translator
*
* @v hport Hub port of USB device
* @ret port Transaction translator port, or NULL
*/
struct usbh_hubport *usbh_transaction_translator(struct usbh_hubport *hport)
{
struct usbh_hubport *parent;
if (hport->parent->is_roothub) {
return NULL;
}
/* Navigate up to root hub. If we find a low-speed or
* full-speed device with a higher-speed parent hub, then that
* device's port is the transaction translator.
*/
for (; (parent = hport->parent->parent); hport = parent) {
if ((hport->speed <= USB_SPEED_FULL) &&
(parent->speed > USB_SPEED_FULL)) {
return hport;
}
}
return NULL;
}
/**
* Get USB route string
*
* @v hport Hub Port of USB device
* @ret route USB route string
*/
unsigned int usbh_route_string(struct usbh_hubport *hport)
{
struct usbh_hubport *parent;
unsigned int route;
/* Navigate up to root hub, constructing route string as we go */
for (route = 0; (parent = hport->parent->parent); hport = parent) {
route <<= 4;
route |= ((hport->dev_addr > 0xf) ?
0xf :
hport->dev_addr);
}
return route;
}
/**
* Get USB root hub port
*
* @v usb Hub port of USB device
* @ret port Root hub port
*/
struct usbh_hubport *usbh_root_hub_port(struct usbh_hubport *hport)
{
struct usbh_hubport *parent;
/* Navigate up to root hub */
while (parent = hport->parent->parent) {
hport = parent;
}
return hport;
}
/** @file /** @file
* *
@@ -485,7 +554,7 @@ static unsigned int xhci_port_protocol ( struct xhci_host *xhci,
protocol = XHCI_SUPPORTED_REVISION_VER ( revision ); protocol = XHCI_SUPPORTED_REVISION_VER ( revision );
/* Describe port protocol */ /* Describe port protocol */
#if XHCI_DUMP #if XHCI_DUMP
{ {
name.raw = CPU_TO_LE32 ( readl ( xhci->cap + supported + name.raw = CPU_TO_LE32 ( readl ( xhci->cap + supported +
XHCI_SUPPORTED_NAME ) ); XHCI_SUPPORTED_NAME ) );
@@ -798,7 +867,7 @@ static void xhci_run ( struct xhci_host *xhci ) {
* @v xhci xHCI device * @v xhci xHCI device
*/ */
static void xhci_event_free ( struct xhci_host *xhci ) { static void xhci_event_free ( struct xhci_host *xhci ) {
/* Clear event ring registers */ /* Clear event ring registers */
writel ( 0, xhci->run + XHCI_RUN_ERSTSZ ( 0 ) ); writel ( 0, xhci->run + XHCI_RUN_ERSTSZ ( 0 ) );
xhci_writeq ( xhci, 0, xhci->run + XHCI_RUN_ERSTBA ( 0 ) ); xhci_writeq ( xhci, 0, xhci->run + XHCI_RUN_ERSTBA ( 0 ) );
@@ -1029,12 +1098,12 @@ int xhci_port_enable(struct xhci_host *xhci, uint32_t port) {
/** /**
* Convert USB Speed to PSI * Convert USB Speed to PSI
* *
* @v speed USB speed * @v speed USB speed
* @ret psi USB speed in PSI * @ret psi USB speed in PSI
*/ */
static unsigned int xhci_speed_to_psi(int speed) { static unsigned int xhci_speed_to_psi(int speed) {
unsigned int psi = USB_SPEED_UNKNOWN; unsigned int psi = USB_SPEED_UNKNOWN;
switch (speed) { switch (speed) {
case USB_SPEED_LOW: case USB_SPEED_LOW:
psi = XCHI_PSI_LOW; psi = XCHI_PSI_LOW;
@@ -1056,12 +1125,12 @@ static unsigned int xhci_speed_to_psi(int speed) {
/** /**
* Convert USB PSI to Speed * Convert USB PSI to Speed
* *
* @v psi USB speed in PSI * @v psi USB speed in PSI
* @ret speed USB speed * @ret speed USB speed
*/ */
static int xhci_psi_to_speed(int psi) { static int xhci_psi_to_speed(int psi) {
int speed = USB_SPEED_UNKNOWN; int speed = USB_SPEED_UNKNOWN;
switch (psi) { switch (psi) {
case XCHI_PSI_LOW: case XCHI_PSI_LOW:
speed = USB_SPEED_LOW; speed = USB_SPEED_LOW;
@@ -1221,7 +1290,7 @@ uint32_t xhci_root_speed ( struct xhci_host *xhci, uint8_t port ) {
csc = ( portsc & XHCI_PORTSC_CSC ); csc = ( portsc & XHCI_PORTSC_CSC );
psiv = XHCI_PORTSC_PSIV ( portsc ); psiv = XHCI_PORTSC_PSIV ( portsc );
USB_LOG_DBG("XHCI %s port-%d ccs: %d, ped: %d, csc: %d, psiv: 0x%x\n", USB_LOG_DBG("XHCI %s port-%d ccs: %d, ped: %d, csc: %d, psiv: 0x%x\n",
xhci->name, port, !!ccs, !!ped, !!csc, psiv); xhci->name, port, !!ccs, !!ped, !!csc, psiv);
/* Port speed is not valid unless port is connected */ /* Port speed is not valid unless port is connected */
@@ -1348,7 +1417,7 @@ static void xhci_abort ( struct xhci_host *xhci ) {
/* Consume (and ignore) any final command status */ /* Consume (and ignore) any final command status */
int cc = xhci_event_wait(xhci, xhci->cur_cmd_pipe, xhci->cmds); int cc = xhci_event_wait(xhci, xhci->cur_cmd_pipe, xhci->cmds);
if (XHCI_CMPLT_SUCCESS != cc) { if (XHCI_CMPLT_SUCCESS != cc) {
USB_LOG_ERR("XHCI %s abort command failed, cc %d\n", xhci->name, cc); USB_LOG_ERR("XHCI %s abort command failed, cc %d\n", xhci->name, cc);
} }
/* Reset the command ring control register */ /* Reset the command ring control register */
@@ -1364,7 +1433,7 @@ static void xhci_abort ( struct xhci_host *xhci ) {
* @ trb Command TRB to be sent * @ trb Command TRB to be sent
*/ */
static int xhci_cmd_submit(struct xhci_host *xhci, struct xhci_endpoint *ep, union xhci_trb *trb) { static int xhci_cmd_submit(struct xhci_host *xhci, struct xhci_endpoint *ep, union xhci_trb *trb) {
int rc = 0; int rc = 0;
usb_osal_mutex_take(xhci->cmds->lock); /* handle command one by one */ usb_osal_mutex_take(xhci->cmds->lock); /* handle command one by one */
@@ -1382,7 +1451,7 @@ static int xhci_cmd_submit(struct xhci_host *xhci, struct xhci_endpoint *ep, uni
if (XHCI_CMPLT_SUCCESS != cc) { if (XHCI_CMPLT_SUCCESS != cc) {
USB_LOG_ERR("XHCI %s cmd failed, cc %d\n", xhci->name, cc); USB_LOG_ERR("XHCI %s cmd failed, cc %d\n", xhci->name, cc);
xhci_abort(xhci); /* Abort command */ xhci_abort(xhci); /* Abort command */
rc = -ENOTSUP; rc = -ENOTSUP;
} }
usb_osal_mutex_give(xhci->cmds->lock); usb_osal_mutex_give(xhci->cmds->lock);
@@ -1528,7 +1597,7 @@ static int xhci_context ( struct xhci_host *xhci, struct xhci_slot *slot,
err_command: err_command:
usb_free ( input ); usb_free ( input );
err_alloc: err_alloc:
return rc; return rc;
} }
/** /**
@@ -1548,7 +1617,7 @@ static void xhci_address_device_input ( struct xhci_host *xhci,
struct xhci_endpoint_context *ep_ctx; struct xhci_endpoint_context *ep_ctx;
/* Sanity checks */ /* Sanity checks */
USB_ASSERT ( endpoint->ctx == XHCI_CTX_EP0 ); USB_ASSERT ( endpoint->ctx == XHCI_CTX_EP0 );
/* Populate control context, add slot context and ep context */ /* Populate control context, add slot context and ep context */
control_ctx = input; control_ctx = input;
@@ -1585,7 +1654,7 @@ static void xhci_address_device_input ( struct xhci_host *xhci,
* @v slot Device slot * @v slot Device slot
* @ret rc Return status code * @ret rc Return status code
*/ */
static inline int xhci_address_device ( struct xhci_host *xhci, static inline int xhci_address_device ( struct xhci_host *xhci,
struct xhci_endpoint *ep, struct xhci_endpoint *ep,
struct xhci_slot *slot ) { struct xhci_slot *slot ) {
struct xhci_slot_context *slot_ctx; struct xhci_slot_context *slot_ctx;
@@ -1595,7 +1664,7 @@ static inline int xhci_address_device ( struct xhci_host *xhci,
if ( ( rc = xhci_context ( xhci, slot, slot->endpoint[XHCI_CTX_EP0], if ( ( rc = xhci_context ( xhci, slot, slot->endpoint[XHCI_CTX_EP0],
XHCI_TRB_ADDRESS_DEVICE, XHCI_TRB_ADDRESS_DEVICE,
xhci_address_device_input ) ) != 0 ) xhci_address_device_input ) ) != 0 )
USB_LOG_DBG("XHCI %s slot ctx 0x%x\n", xhci->name, slot->context); USB_LOG_DBG("XHCI %s slot ctx 0x%x\n", xhci->name, slot->context);
/* Get assigned address for check */ /* Get assigned address for check */
@@ -1604,7 +1673,7 @@ static inline int xhci_address_device ( struct xhci_host *xhci,
USB_LOG_DBG("XHCI %s slot ctx 0x%x assigned address 0x%x\n", USB_LOG_DBG("XHCI %s slot ctx 0x%x assigned address 0x%x\n",
xhci->name, slot_ctx, slot_ctx->address ); xhci->name, slot_ctx, slot_ctx->address );
return rc; return rc;
} }
/** /**
@@ -1701,12 +1770,12 @@ static int xhci_port_slot_type ( struct xhci_host *xhci, unsigned int port ) {
* *
* @v xhci XHCI device * @v xhci XHCI device
* @v ep Endpoint * @v ep Endpoint
* @ret slot_id Return device slot id * @ret slot_id Return device slot id
* @ret rc Return status code * @ret rc Return status code
*/ */
int xhci_device_open ( struct xhci_host *xhci, struct xhci_endpoint *ep, int *slot_id ) { int xhci_device_open ( struct xhci_host *xhci, struct xhci_endpoint *ep, int *slot_id ) {
struct usbh_hubport *hport = ep->hport; struct usbh_hubport *hport = ep->hport;
struct usbh_hubport *tt = usbh_transaction_translator(hport); struct usbh_hubport *tt = usbh_transaction_translator(hport);
struct xhci_slot *slot; struct xhci_slot *slot;
struct xhci_slot *tt_slot; struct xhci_slot *tt_slot;
int type; int type;
@@ -1774,7 +1843,7 @@ err_alloc_context:
xhci->slot[id] = NULL; xhci->slot[id] = NULL;
usb_free ( slot ); usb_free ( slot );
err_alloc: err_alloc:
xhci_disable_slot ( xhci, ep, id ); xhci_disable_slot ( xhci, ep, id );
err_enable_slot: err_enable_slot:
err_type: err_type:
return rc; return rc;
@@ -1903,7 +1972,7 @@ static void xhci_configure_endpoint_input ( struct xhci_host *xhci,
ep_ctx->burst = endpoint->burst; ep_ctx->burst = endpoint->burst;
ep_ctx->mtu = CPU_TO_LE16 ( endpoint->mtu ); /* bit[31:16] max packet size */ ep_ctx->mtu = CPU_TO_LE16 ( endpoint->mtu ); /* bit[31:16] max packet size */
ep_ctx->dequeue = CPU_TO_LE64 ( (uint64_t)( &(endpoint->reqs.ring[0]) ) | XHCI_EP_DCS ); ep_ctx->dequeue = CPU_TO_LE64 ( (uint64_t)( &(endpoint->reqs.ring[0]) ) | XHCI_EP_DCS );
/* TODO: endpoint attached on hub may need different setting here */ /* TODO: endpoint attached on hub may need different setting here */
if (endpoint->ep_type == USB_ENDPOINT_TYPE_BULK) { if (endpoint->ep_type == USB_ENDPOINT_TYPE_BULK) {
ep_ctx->trb_len = CPU_TO_LE16 ( 256U ); /* bit[15:0] average trb length */ ep_ctx->trb_len = CPU_TO_LE16 ( 256U ); /* bit[15:0] average trb length */
@@ -1933,7 +2002,7 @@ static inline int xhci_configure_endpoint ( struct xhci_host *xhci,
XHCI_TRB_CONFIGURE_ENDPOINT, XHCI_TRB_CONFIGURE_ENDPOINT,
xhci_configure_endpoint_input ) ) != 0 ){ xhci_configure_endpoint_input ) ) != 0 ){
USB_LOG_ERR("XHCI %s slot %d ctx %d configure failed, error %d !!!\n", USB_LOG_ERR("XHCI %s slot %d ctx %d configure failed, error %d !!!\n",
xhci->name, slot->id, endpoint->ctx, rc ); xhci->name, slot->id, endpoint->ctx, rc );
return rc; return rc;
} }
@@ -1943,7 +2012,7 @@ static inline int xhci_configure_endpoint ( struct xhci_host *xhci,
xhci_dump_slot_ctx(endpoint->slot->context); xhci_dump_slot_ctx(endpoint->slot->context);
xhci_dump_ep_ctx(endpoint->context); xhci_dump_ep_ctx(endpoint->context);
USB_LOG_ERR("XHCI %s slot %d ctx %d configure failed !!!\n", USB_LOG_ERR("XHCI %s slot %d ctx %d configure failed !!!\n",
xhci->name, slot->id, endpoint->ctx ); xhci->name, slot->id, endpoint->ctx );
return -1; return -1;
} }
@@ -2035,7 +2104,7 @@ int xhci_ctrl_endpoint_open ( struct xhci_host *xhci, struct xhci_slot *slot, st
ep->reqs.cs = 1; /* cycle state = 1 */ ep->reqs.cs = 1; /* cycle state = 1 */
USB_LOG_DBG("XHCI %s slot %d endpoint 0x%x ep type %d xhci ep type 0x%x\n", USB_LOG_DBG("XHCI %s slot %d endpoint 0x%x ep type %d xhci ep type 0x%x\n",
xhci->name, slot->id, ep->address, ep->ep_type, xhci->name, slot->id, ep->address, ep->ep_type,
(ep->ctx_type >> 3) ); (ep->ctx_type >> 3) );
USB_LOG_DBG("XHCI %s slot %d ctx %d ring [%08lx,%08lx)\n", USB_LOG_DBG("XHCI %s slot %d ctx %d ring [%08lx,%08lx)\n",
@@ -2090,7 +2159,7 @@ int xhci_work_endpoint_open ( struct xhci_host *xhci, struct xhci_slot *slot, st
ep->xhci = xhci; ep->xhci = xhci;
ep->slot = slot; ep->slot = slot;
ep->ctx = ctx; ep->ctx = ctx;
/* Calculate interval */ /* Calculate interval */
if ( ctx_type & XHCI_EP_TYPE_PERIODIC ) { if ( ctx_type & XHCI_EP_TYPE_PERIODIC ) {
ep->interval = ( fls ( ep->interval ) - 1 ); ep->interval = ( fls ( ep->interval ) - 1 );
@@ -2102,7 +2171,7 @@ int xhci_work_endpoint_open ( struct xhci_host *xhci, struct xhci_slot *slot, st
ep->reqs.cs = 1; /* cycle state = 1 */ ep->reqs.cs = 1; /* cycle state = 1 */
USB_LOG_DBG("XHCI %s slot %d endpoint 0x%x ep type %d xhci ep type 0x%x\n", USB_LOG_DBG("XHCI %s slot %d endpoint 0x%x ep type %d xhci ep type 0x%x\n",
xhci->name, slot->id, ep->address, ep->ep_type, xhci->name, slot->id, ep->address, ep->ep_type,
(ep->ctx_type >> 3) ); (ep->ctx_type >> 3) );
/* Configure endpoint */ /* Configure endpoint */
@@ -2136,7 +2205,7 @@ void xhci_endpoint_close ( struct xhci_endpoint *ep ) {
(void)xhci_deconfigure_endpoint ( xhci, slot, ep ); (void)xhci_deconfigure_endpoint ( xhci, slot, ep );
slot->endpoint[ctx] = NULL; slot->endpoint[ctx] = NULL;
usb_free(ep); usb_free(ep);
} }
/*********************************************************************/ /*********************************************************************/
@@ -2150,9 +2219,9 @@ void xhci_endpoint_close ( struct xhci_endpoint *ep ) {
* @v datalen Data length * @v datalen Data length
* @ret rc Return status code * @ret rc Return status code
*/ */
void xhci_endpoint_message ( struct xhci_endpoint *ep, void xhci_endpoint_message ( struct xhci_endpoint *ep,
struct usb_setup_packet *packet, struct usb_setup_packet *packet,
void *data_buff, void *data_buff,
int datalen ) { int datalen ) {
struct xhci_host *xhci = ep->xhci; struct xhci_host *xhci = ep->xhci;
struct xhci_slot *slot = ep->slot; struct xhci_slot *slot = ep->slot;
@@ -2219,8 +2288,8 @@ void xhci_endpoint_message ( struct xhci_endpoint *ep,
* @v datalen Data length * @v datalen Data length
* @ret rc Return status code * @ret rc Return status code
*/ */
void xhci_endpoint_stream ( struct xhci_endpoint *ep, void xhci_endpoint_stream ( struct xhci_endpoint *ep,
void *data_buff, void *data_buff,
int datalen ) { int datalen ) {
struct xhci_host *xhci = ep->xhci; struct xhci_host *xhci = ep->xhci;
struct xhci_slot *slot = ep->slot; struct xhci_slot *slot = ep->slot;
@@ -2254,7 +2323,7 @@ void xhci_endpoint_stream ( struct xhci_endpoint *ep,
xhci_doorbell(xhci, slot->id, ep->ctx); xhci_doorbell(xhci, slot->id, ep->ctx);
err_enqueue: err_enqueue:
return; return;
} }
/*********************************************************************/ /*********************************************************************/
@@ -2357,7 +2426,7 @@ static void xhci_port_status ( struct xhci_host *xhci,
if (portsc & XHCI_PORTSC_CSC) { if (portsc & XHCI_PORTSC_CSC) {
/* Report port status change */ /* Report port status change */
usbh_roothub_thread_wakeup ( trb->port ); usbh_roothub_thread_wakeup ( trb->port );
} }
} }
/** /**
@@ -2369,11 +2438,11 @@ static void xhci_port_status ( struct xhci_host *xhci,
static void xhci_transfer ( struct xhci_host *xhci, static void xhci_transfer ( struct xhci_host *xhci,
struct xhci_trb_transfer *trb ) { struct xhci_trb_transfer *trb ) {
struct xhci_slot *slot; struct xhci_slot *slot;
struct xhci_endpoint *endpoint; struct xhci_endpoint *endpoint;
union xhci_trb *trans_trb = (void *)(uintptr_t)(trb->transfer); union xhci_trb *trans_trb = (void *)(uintptr_t)(trb->transfer);
struct xhci_ring *trans_ring = XHCI_RING(trans_trb); /* to align addr is ring base */ struct xhci_ring *trans_ring = XHCI_RING(trans_trb); /* to align addr is ring base */
union xhci_trb *pending = &trans_ring->evt; /* preserve event trb pending to handle */ union xhci_trb *pending = &trans_ring->evt; /* preserve event trb pending to handle */
uint32_t eidx = trans_trb - trans_ring->ring + 1; /* calculate current evt trb index */ uint32_t eidx = trans_trb - trans_ring->ring + 1; /* calculate current evt trb index */
int rc; int rc;
/* Identify slot */ /* Identify slot */
@@ -2434,7 +2503,7 @@ static void xhci_transfer ( struct xhci_host *xhci,
} }
} }
return; return;
} }
/** /**
@@ -2559,5 +2628,5 @@ struct xhci_endpoint *xhci_event_process(struct xhci_host *xhci) {
xhci->run + XHCI_RUN_ERDP ( 0 ) ); xhci->run + XHCI_RUN_ERDP ( 0 ) );
} }
return work_pipe; return work_pipe;
} }