summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsakumisu <[email protected]>2024-06-07 10:29:44 +0800
committersakumisu <[email protected]>2024-06-07 10:29:44 +0800
commit6fd87902b5aa4b7eb9b9df2f093230c9a53a61f7 (patch)
treee19b6f4a0a10122698f08a837a2b1749d322f7e6
parentb1660f743fdf9178883794d651afd80fb09ab0a7 (diff)
remove old version
-rw-r--r--port/xhci/usb_hc_xhci.c505
-rw-r--r--port/xhci/usb_hc_xhci.h38
-rw-r--r--port/xhci/xhci.c2667
-rw-r--r--port/xhci/xhci.h940
-rw-r--r--port/xhci/xhci_dbg.c353
-rw-r--r--port/xhci/xhci_reg.h499
6 files changed, 0 insertions, 5002 deletions
diff --git a/port/xhci/usb_hc_xhci.c b/port/xhci/usb_hc_xhci.c
deleted file mode 100644
index 3af541b0..00000000
--- a/port/xhci/usb_hc_xhci.c
+++ /dev/null
@@ -1,505 +0,0 @@
-/*
- * Copyright : (C) 2022 Phytium Information Technology, Inc.
- * All Rights Reserved.
- *
- * This program is OPEN SOURCE software: you can redistribute it and/or modify it
- * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd,
- * either version 1.0 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the Phytium Public License for more details.
- *
- *
- * FilePath: usb_hc_xhci.c
- * Date: 2022-09-19 17:24:36
- * LastEditTime: 2022-09-19 17:24:36
- * Description:  This file is for xhci function implementation.
- *
- * Modify History:
- * Ver   Who        Date         Changes
- * ----- ------     --------    --------------------------------------
- * 1.0 zhugengyu 2022/9/19 init commit
- * 1.1 zhugengyu 2022/10/9 add dumpers and fix command abort
- * 2.0 zhugengyu 2023/3/29 support usb3.0 device attached at roothub
- */
-
-/***************************** Include Files *********************************/
-#include "usbh_hub.h"
-
-#include "xhci.h"
-
-/************************** Constant Definitions *****************************/
-
-/************************** Variable Definitions *****************************/
-
-/***************** Macros (Inline Functions) Definitions *********************/
-
-/************************** Function Prototypes ******************************/
-
-/*****************************************************************************/
-__WEAK void usb_hc_low_level_init(void)
-{
-}
-
-__WEAK void *usb_hc_malloc(size_t size)
-{
- return NULL;
-}
-
-__WEAK void *usb_hc_malloc_align(size_t align, size_t size)
-{
- return NULL;
-}
-
-__WEAK void usb_hc_free()
-{
-}
-
-/* one may get xhci register base address by PCIe bus emuration */
-__WEAK unsigned long usb_hc_get_register_base(void)
-{
- 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;
-
-/* xhci hardware init */
-int usb_hc_init()
-{
- int rc = 0;
- struct xhci_host *xhci = &(xhci_host);
-
- size_t flag = usb_osal_enter_critical_section(); /* no interrupt when init hc */
-
- usb_hc_low_level_init(); /* set gic and memp */
-
- memset(xhci, 0, sizeof(*xhci));
- xhci->id = CONFIG_USBHOST_XHCI_ID;
- if (rc = xhci_probe(xhci, usb_hc_get_register_base()) != 0) {
- goto err_open;
- }
-
- if (rc = xhci_open(xhci) != 0 ) {
- goto err_open;
- }
-
- err_open:
- usb_osal_leave_critical_section(flag);
- return rc;
-}
-
-int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf)
-{
- uint8_t nports;
- uint8_t port;
- uint32_t portsc;
- uint32_t status;
- int ret = 0;
- struct xhci_host *xhci = &xhci_host;
- nports = CONFIG_USBHOST_MAX_RHPORTS;
-
- port = setup->wIndex;
-
- /*
- bmRequestType bit[4:0], define whether the request is directed to the device (0000b),
- specific interface (00001b), endpoint (00010b), or other element (00011b)
- bRequest, identifies the request
- wValue, pass the request-specific info to the device
- */
- if (setup->bmRequestType & USB_REQUEST_RECIPIENT_DEVICE) /* request is directed to device */
- {
- switch (setup->bRequest)
- {
- case HUB_REQUEST_CLEAR_FEATURE: /* disable the feature */
- switch (setup->wValue)
- {
- case HUB_FEATURE_HUB_C_LOCALPOWER:
- USB_LOG_ERR("HUB_FEATURE_HUB_C_LOCALPOWER not implmented.\n");
- break;
- case HUB_FEATURE_HUB_C_OVERCURRENT:
- USB_LOG_ERR("HUB_FEATURE_HUB_C_OVERCURRENT not implmented.\n");
- break;
- default:
- return -EPIPE;
- }
- break;
- case HUB_REQUEST_SET_FEATURE: /* set a value reported in the hub status */
- switch (setup->wValue)
- {
- case HUB_FEATURE_HUB_C_LOCALPOWER:
- USB_LOG_ERR("HUB_FEATURE_HUB_C_LOCALPOWER not implmented.\n");
- break;
- case HUB_FEATURE_HUB_C_OVERCURRENT:
- USB_LOG_ERR("HUB_FEATURE_HUB_C_OVERCURRENT not implmented.\n");
- break;
- default:
- return -EPIPE;
- }
- break;
- case HUB_REQUEST_GET_DESCRIPTOR:
- USB_LOG_ERR("HUB_REQUEST_GET_DESCRIPTOR not implmented.\n");
- break;
- case HUB_REQUEST_GET_STATUS:
- USB_ASSERT(buf);
- memset(buf, 0, 4);
- break;
- default:
- break;
- }
- }
- else if (setup->bmRequestType & USB_REQUEST_RECIPIENT_OTHER)
- {
- switch (setup->bRequest)
- {
- case HUB_REQUEST_CLEAR_FEATURE:
- if (!port || port > nports)
- {
- return -EPIPE;
- }
-
- portsc = readl ( xhci->op + XHCI_OP_PORTSC ( port ) );
- switch (setup->wValue)
- {
- case HUB_PORT_FEATURE_ENABLE:
- break;
- case HUB_PORT_FEATURE_SUSPEND:
- case HUB_PORT_FEATURE_C_SUSPEND:
- break;
- case HUB_PORT_FEATURE_POWER:
- break;
- case HUB_PORT_FEATURE_C_CONNECTION:
- portsc |= XHCI_PORTSC_CSC;
- break;
- case HUB_PORT_FEATURE_C_ENABLE:
- portsc |= XHCI_PORTSC_PEC;
- break;
- case HUB_PORT_FEATURE_C_OVER_CURREN:
- break;
- case HUB_PORT_FEATURE_C_RESET:
- break;
- default:
- return -EPIPE;
- }
-
- uint32_t pclear = portsc & XHCI_PORTSC_RW_MASK;
- /* clear port status */
- writel(pclear, xhci->op + XHCI_OP_PORTSC ( port ));
-
- break;
- case HUB_REQUEST_SET_FEATURE:
- if (!port || port > nports)
- {
- return -EPIPE;
- }
-
- switch (setup->wValue)
- {
- case HUB_PORT_FEATURE_SUSPEND:
- break;
- case HUB_PORT_FEATURE_POWER:
- break;
- case HUB_PORT_FEATURE_RESET:
- ret = xhci_port_enable(xhci, port);
- break;
- default:
- return -EPIPE;
- }
- break;
- case HUB_REQUEST_GET_STATUS:
- if (!port || port > nports)
- {
- return -EPIPE;
- }
-
- portsc = readl ( xhci->op + XHCI_OP_PORTSC ( port ) );
- status = 0;
-
- if (portsc & XHCI_PORTSC_CSC)
- {
- /* Port connection status changed */
- status |= (1 << HUB_PORT_FEATURE_C_CONNECTION);
-
- /* always clear all the status change bits */
- uint32_t temp = portsc & ( XHCI_PORTSC_PRESERVE | XHCI_PORTSC_CHANGE );
- writel ( temp, xhci->op + XHCI_OP_PORTSC ( port ) );
- }
-
- if (portsc & XHCI_PORTSC_PEC)
- {
- /* Port enabled status changed */
- status |= (1 << HUB_PORT_FEATURE_C_ENABLE);
- }
-
- if (portsc & XHCI_PORTSC_OCC)
- {
- /* Port status changed due to over-current */
- status |= (1 << HUB_PORT_FEATURE_C_OVER_CURREN);
- }
-
- if (portsc & XHCI_PORTSC_CCS)
- {
- /* Port connected */
- status |= (1 << HUB_PORT_FEATURE_CONNECTION);
- }
-
- if (portsc & XHCI_PORTSC_PED)
- {
- /* Port enabled */
- status |= (1 << HUB_PORT_FEATURE_ENABLE);
-
- const unsigned int speed = xhci_root_speed(xhci, port);
- USB_LOG_DBG("Port-%d speed = %d \r\n", port, speed);
- if (speed == USB_SPEED_LOW)
- {
- status |= (1 << HUB_PORT_FEATURE_LOWSPEED);
- }
- else if (speed == USB_SPEED_HIGH)
- {
- status |= (1 << HUB_PORT_FEATURE_HIGHSPEED);
- }
- /* else is full-speed */
- }
-
- if (portsc & XHCI_PORTSC_OCA)
- {
- /* Over-current condition */
- status |= (1 << HUB_PORT_FEATURE_OVERCURRENT);
- }
-
- if (portsc & XHCI_PORTSC_PR)
- {
- /* Reset is in progress */
- status |= (1 << HUB_PORT_FEATURE_RESET);
- }
-
- if (portsc & XHCI_PORTSC_PP)
- {
- /* Port is not power off */
- status |= (1 << HUB_PORT_FEATURE_POWER);
- }
- memcpy(buf, &status, 4);
- break;
- default:
- break;
- }
- }
-
- return 0;
-}
-
-uint8_t usbh_get_port_speed(struct usbh_hub *hub, const uint8_t port)
-{
- USB_ASSERT(hub);
- struct xhci_host *xhci = &(xhci_host);
-
- if (hub->is_roothub) {
- return xhci_root_speed(xhci, port);
- } else {
- struct usbh_hubport *roothub_port = usbh_root_hub_port(&(hub->child[port]));
- /* TODO, hanlde TT for low-speed device on high-speed hub, but it doesn't matter, since
- we haven't well handle hub yet */
- USB_ASSERT(roothub_port);
- return xhci_root_speed(xhci, roothub_port->port);
- }
-}
-
-int usbh_ep_pipe_reconfigure(usbh_pipe_t pipe, uint8_t dev_addr, uint8_t mtu, uint8_t speed)
-{
- struct xhci_endpoint *ppipe = (struct xhci_endpoint *)pipe;
- size_t old_mtu = ppipe->mtu;
- int rc = 0;
-
- if (mtu != old_mtu) {
- ppipe->mtu = mtu;
- rc = xhci_endpoint_mtu(ppipe);
- }
-
- return rc;
-}
-
-int usbh_pipe_alloc(usbh_pipe_t *pipe, const struct usbh_endpoint_cfg *ep_cfg)
-{
- int rc = 0;
- int slot_id = 0;
- struct xhci_host *xhci = &xhci_host;
- struct usbh_hubport *hport = ep_cfg->hport;
- struct xhci_endpoint *ppipe = usb_align(XHCI_RING_SIZE, sizeof(struct xhci_endpoint));
- struct xhci_slot *slot;
-
- if (NULL == ppipe) {
- return -ENOMEM;
- }
-
- memset(ppipe, 0, sizeof(struct xhci_endpoint));
-
- ppipe->waitsem = usb_osal_sem_create(0);
- ppipe->waiter = false;
- ppipe->urb = NULL;
- ppipe->hport = hport;
-
- ppipe->address = ep_cfg->ep_addr;
- ppipe->mtu = ep_cfg->ep_mps;
- ppipe->interval = ep_cfg->ep_interval;
- ppipe->ep_type = ep_cfg->ep_type;
- ppipe->burst = 0U;
-
- if (ppipe->address == 0) { /* if try to allocate ctrl ep, open device first */
- USB_LOG_DBG("allocate device for port-%d \r\n", hport->port);
- rc = xhci_device_open(xhci, ppipe, &slot_id);
- if (rc) {
- goto failed;
- }
-
- slot = xhci->slot[slot_id];
- USB_ASSERT(slot);
- rc = xhci_ctrl_endpoint_open(xhci, slot, ppipe);
- if (rc) {
- goto failed;
- }
-
- rc = xhci_device_address(xhci, slot, ppipe);
- if (rc) {
- goto failed;
- }
- } else {
- slot_id = hport->dev_addr;
- slot = xhci->slot[slot_id];
-
- rc = xhci_work_endpoint_open(xhci, slot, ppipe);
- if (rc) {
- goto failed;
- }
- }
-
- *pipe = (usbh_pipe_t)ppipe;
- return rc;
-failed:
- usb_free(ppipe);
- *pipe = NULL;
- return rc;
-}
-
-int usbh_get_xhci_devaddr(usbh_pipe_t *pipe)
-{
- struct xhci_endpoint *ppipe = (struct xhci_endpoint *)pipe;
- USB_ASSERT(ppipe && (ppipe->slot));
- return ppipe->slot->id;
-}
-
-int usbh_pipe_free(usbh_pipe_t pipe)
-{
- int ret = 0;
- struct xhci_endpoint *ppipe = (struct xhci_endpoint *)pipe;
-
- if (!ppipe) {
- return -EINVAL;
- }
-
- struct usbh_urb *urb = ppipe->urb;
- if (urb) {
- usbh_kill_urb(urb);
- }
-
- size_t flags = usb_osal_enter_critical_section();
- xhci_endpoint_close(ppipe);
- usb_osal_leave_critical_section(flags);
- return 0;
-}
-
-int usbh_submit_urb(struct usbh_urb *urb)
-{
- int ret = 0;
- if (!urb || !urb->pipe) {
- return -EINVAL;
- }
-
- struct xhci_endpoint *ppipe = (struct xhci_endpoint *)urb->pipe;
- struct xhci_host *xhci = ppipe->xhci;
- struct usb_setup_packet *setup = urb->setup;
- size_t flags = usb_osal_enter_critical_section();
-
- urb->errorcode = -EBUSY;
- urb->actual_length = 0U;
-
- ppipe->urb = urb;
- ppipe->timeout = urb->timeout;
- if (ppipe->timeout > 0) {
- ppipe->waiter = true;
- } else {
- ppipe->waiter = false;
- }
-
- usb_osal_leave_critical_section(flags);
- switch (ppipe->ep_type) {
- case USB_ENDPOINT_TYPE_CONTROL:
- USB_ASSERT(setup);
- if (setup->bRequest == USB_REQUEST_SET_ADDRESS) {
- /* Set address command sent during xhci_alloc_pipe. */
- goto skip_req;
- }
-
- USB_LOG_DBG("%s request-%d.\n", __func__, setup->bRequest);
- xhci_endpoint_message(ppipe, setup, urb->transfer_buffer, urb->transfer_buffer_length);
- break;
- case USB_ENDPOINT_TYPE_INTERRUPT:
- case USB_ENDPOINT_TYPE_BULK:
- xhci_endpoint_stream(ppipe, urb->transfer_buffer, urb->transfer_buffer_length);
- break;
- default:
- USB_ASSERT(0U);
- break;
- }
-
- /* wait all ring handled by xHc */
- int cc = xhci_event_wait(xhci, ppipe, &ppipe->reqs);
- if ((cc != XHCI_CMPLT_SUCCESS) &&
- !((cc == XHCI_CMPLT_TIMEOUT) && (ppipe->ep_type == USB_ENDPOINT_TYPE_INTERRUPT)))
- {
- /* ignore transfer timeout for interrupt type */
- USB_LOG_ERR("%s: xfer failed (cc %d).\n", __func__, cc);
- ret = -1;
- urb->errorcode = cc;
- goto errout_timeout;
- }
-
-skip_req:
-errout_timeout:
- /* Timeout will run here */
- usbh_kill_urb(urb);
- return ret;
-}
-
-int usbh_kill_urb(struct usbh_urb *urb)
-{
- return 0;
-}
-
-void USBH_IRQHandler(void *param)
-{
- struct xhci_host *xhci = &xhci_host;
- struct xhci_endpoint *work_pipe = NULL;
- USB_ASSERT(xhci);
- uint32_t usbsts;
- uint32_t runtime;
-
- /* clear interrupt status */
- usbsts = readl ( xhci->op + XHCI_OP_USBSTS );
- usbsts |= XHCI_USBSTS_EINT;
- writel(usbsts, xhci->op + XHCI_OP_USBSTS);
-
- /* ack interrupt */
- runtime = readl(xhci->run + XHCI_RUN_IR_IMAN ( 0 ));
- runtime |= XHCI_RUN_IR_IMAN_IP;
- writel (runtime, xhci->run + XHCI_RUN_IR_IMAN ( 0 ));
-
- work_pipe = xhci_event_process(xhci);
-} \ No newline at end of file
diff --git a/port/xhci/usb_hc_xhci.h b/port/xhci/usb_hc_xhci.h
deleted file mode 100644
index 151b5bdc..00000000
--- a/port/xhci/usb_hc_xhci.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright : (C) 2022 Phytium Information Technology, Inc.
- * All Rights Reserved.
- *
- * This program is OPEN SOURCE software: you can redistribute it and/or modify it
- * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd,
- * either version 1.0 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the Phytium Public License for more details.
- *
- *
- * FilePath: usb_hc_xhci.h
- * Date: 2022-07-19 09:26:25
- * LastEditTime: 2022-07-19 09:26:25
- * Description:  This file is for xhci data structure definition.
- *
- * Modify History:
- * Ver   Who        Date         Changes
- * ----- ------     --------    --------------------------------------
- * 1.0 zhugengyu 2022/9/19 init commit
- * 2.0 zhugengyu 2023/3/29 support usb3.0 device attached at roothub
- */
-
-#ifndef USB_HC_XHCI_H
-#define USB_HC_XHCI_H
-
-/***************************** Include Files *********************************/
-#include "usbh_core.h"
-
-/************************** Constant Definitions *****************************/
-
-/************************** Variable Definitions *****************************/
-
-/***************** Macros (Inline Functions) Definitions *********************/
-
-/************************** Function Prototypes ******************************/
diff --git a/port/xhci/xhci.c b/port/xhci/xhci.c
deleted file mode 100644
index 0acf2bd4..00000000
--- a/port/xhci/xhci.c
+++ /dev/null
@@ -1,2667 +0,0 @@
-/*
- * Copyright : (C) 2022 Phytium Information Technology, Inc.
- * All Rights Reserved.
- *
- * This program is OPEN SOURCE software: you can redistribute it and/or modify it
- * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd,
- * either version 1.0 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the Phytium Public License for more details.
- *
- *
- * FilePath: xhci.c
- * Date: 2022-07-19 09:26:25
- * LastEditTime: 2022-07-19 09:26:25
- * Description:  This file is for xhci functions implmentation.
- *
- * Modify History:
- * Ver   Who        Date         Changes
- * ----- ------     --------    --------------------------------------
- * 1.0 zhugengyu 2022/9/19 init commit
- * 2.0 zhugengyu 2023/3/29 support usb3.0 device attached at roothub
- */
-
-#include <string.h>
-
-#include "usbh_core.h"
-#include "usbh_hub.h"
-
-#include "xhci_reg.h"
-#include "xhci.h"
-
-extern struct usbh_hubport *usbh_get_roothub_port(unsigned int port);
-
-#ifdef __aarch64__
-/* find last 64bit set, binary search */
-int xhci_fls(unsigned long v)
-{
- int n = 64;
-
- if (!v) return -1;
- if (!(v & 0xFFFFFFFF00000000)) { v <<= 32; n -= 32; }
- if (!(v & 0xFFFF000000000000)) { v <<= 16; n -= 16; }
- if (!(v & 0xFF00000000000000)) { v <<= 8; n -= 8; }
- if (!(v & 0xF000000000000000)) { v <<= 4; n -= 4; }
- if (!(v & 0xC000000000000000)) { v <<= 2; n -= 2; }
- if (!(v & 0x8000000000000000)) { v <<= 1; n -= 1; }
-
- return n - 1;
-}
-#else
-/* find first bit set, binary search */
-int xhci_fls(unsigned int v)
-{
- int n = 32;
-
- if (!v) return -1;
- if (!(v & 0xFFFF0000)) { v <<= 16; n -= 16; }
- if (!(v & 0xFF000000)) { v <<= 8; n -= 8; }
- if (!(v & 0xF0000000)) { v <<= 4; n -= 4; }
- if (!(v & 0xC0000000)) { v <<= 2; n -= 2; }
- if (!(v & 0x80000000)) { v <<= 1; n -= 1; }
-
- return n - 1;
-}
-#endif
-
-/**
- * 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
- *
- * USB eXtensible Host Controller Interface (xHCI) driver
- *
- */
-
-#define XHCI_DUMP 1
-
-/** Define a XHCI speed in PSI
- *
- * @v mantissa Mantissa
- * @v exponent Exponent (in engineering terms: 1=k, 2=M, 3=G)
- * @ret speed USB speed
- */
-#define XCHI_PSI( mantissa, exponent ) ( (exponent << 16) | (mantissa) )
-
-/** USB device speeds */
-enum {
- /** Not connected */
- XCHI_PSI_NONE = 0,
- /** Low speed (1.5Mbps) */
- XCHI_PSI_LOW = XCHI_PSI ( 1500, 1 ),
- /** Full speed (12Mbps) */
- XCHI_PSI_FULL = XCHI_PSI ( 12, 2 ),
- /** High speed (480Mbps) */
- XCHI_PSI_HIGH = XCHI_PSI ( 480, 2 ),
- /** Super speed (5Gbps) */
- XCHI_PSI_SUPER = XCHI_PSI ( 5, 3 ),
-};
-
-
-/**
- * Calculate buffer alignment
- *
- * @v len Length
- * @ret align Buffer alignment
- *
- * Determine alignment required for a buffer which must be aligned to
- * at least XHCI_MIN_ALIGN and which must not cross a page boundary.
- */
-static inline size_t xhci_align ( size_t len ) {
- size_t align;
-
- /* Align to own length (rounded up to a power of two) */
- align = ( 1 << xhci_fls ( len - 1 ) );
-
- /* Round up to XHCI_MIN_ALIGN if needed */
- if ( align < XHCI_MIN_ALIGN )
- align = XHCI_MIN_ALIGN;
-
- return align;
-}
-
-/**
- * Write potentially 64-bit register
- *
- * @v xhci xHCI device
- * @v value Value
- * @v reg Register address
- * @ret rc Return status code
- */
-static inline int xhci_writeq ( struct xhci_host *xhci, uintptr_t value, void *reg ) {
-
- /* If this is a 32-bit build, then this can never fail
- * (allowing the compiler to optimise out the error path).
- */
- if ( sizeof ( value ) <= sizeof ( uint32_t ) ) {
- writel ( value, reg );
- writel ( 0, ( reg + sizeof ( uint32_t ) ) );
- return 0;
- }
-
- /* If the device does not support 64-bit addresses and this
- * address is outside the 32-bit address space, then fail.
- */
- if ( ( value & ~0xffffffffULL ) && ! xhci->addr64 ) {
- USB_LOG_DBG("XHCI %s cannot access address %lx\n",
- xhci->name, value );
- return -ENOTSUP;
- }
-
- /* If this is a 64-bit build, then writeq() is available */
- writeq ( value, reg );
- return 0;
-}
-
-/**
- * Initialise device
- *
- * @v xhci xHCI device
- * @v regs MMIO registers
- */
-static void xhci_init ( struct xhci_host *xhci, void *regs ) {
- uint32_t hcsparams1;
- uint32_t hcsparams2;
- uint32_t hccparams1;
- uint32_t pagesize;
- size_t caplength;
- size_t rtsoff;
- size_t dboff;
-
- /* Locate capability, operational, runtime, and doorbell registers */
- xhci->cap = regs;
- caplength = readb ( xhci->cap + XHCI_CAP_CAPLENGTH );
- rtsoff = readl ( xhci->cap + XHCI_CAP_RTSOFF );
- dboff = readl ( xhci->cap + XHCI_CAP_DBOFF );
- xhci->op = ( xhci->cap + caplength );
- xhci->run = ( xhci->cap + rtsoff );
- xhci->db = ( xhci->cap + dboff );
-
- /* avoid access XHCI_REG_CAP_HCIVERSION = 0x2, unaligned memory */
- xhci->version = ((readl ( xhci->cap + XHCI_CAP_CAPLENGTH ) >> 16) & 0xffff);
-
- USB_LOG_DBG("XHCI %s version %x cap %08lx op %08lx run %08lx db %08lx\n",
- xhci->name, xhci->version, ( xhci->cap ),
- ( xhci->op ), ( xhci->run ),
- ( xhci->db ) );
-
- if (xhci->version < 0x96 || xhci->version > 0x120) {
- USB_LOG_WRN("XHCI %s not support.\n", xhci->name);
- }
-
- /* Read structural parameters 1 */
- hcsparams1 = readl ( xhci->cap + XHCI_CAP_HCSPARAMS1 );
- xhci->slots = XHCI_HCSPARAMS1_SLOTS ( hcsparams1 );
- xhci->intrs = XHCI_HCSPARAMS1_INTRS ( hcsparams1 );
- xhci->ports = XHCI_HCSPARAMS1_PORTS ( hcsparams1 );
- USB_LOG_DBG("XHCI %s has %d slots %d intrs %d ports\n",
- xhci->name, xhci->slots, xhci->intrs, xhci->ports );
-
- /* Read structural parameters 2 */
- hcsparams2 = readl ( xhci->cap + XHCI_CAP_HCSPARAMS2 );
- xhci->scratch.count = XHCI_HCSPARAMS2_SCRATCHPADS ( hcsparams2 );
- USB_LOG_DBG("XHCI %s needs %d scratchpads\n",
- xhci->name, xhci->scratch.count );
-
- /* Read capability parameters 1 */
- hccparams1 = readl ( xhci->cap + XHCI_CAP_HCCPARAMS1 );
- xhci->addr64 = XHCI_HCCPARAMS1_ADDR64 ( hccparams1 );
- xhci->csz_shift = XHCI_HCCPARAMS1_CSZ_SHIFT ( hccparams1 );
- xhci->xecp = (XHCI_HCCPARAMS1_XECP ( hccparams1 ));
- USB_LOG_DBG("XHCI %s context %d bit\n",
- xhci->name, (xhci->addr64 ? 64 : 32) );
-
- /* Read page size */
- pagesize = readl ( xhci->op + XHCI_OP_PAGESIZE );
- xhci->pagesize = XHCI_PAGESIZE ( pagesize );
- USB_ASSERT ( xhci->pagesize != 0 );
- USB_ASSERT ( ( ( xhci->pagesize ) & ( xhci->pagesize - 1 ) ) == 0 );
- USB_LOG_DBG("XHCI %s page size %zd bytes\n",
- xhci->name, xhci->pagesize );
-}
-
-/**
- * Find extended capability
- *
- * @v xhci xHCI device
- * @v id Capability ID
- * @v offset Offset to previous extended capability instance, or zero
- * @ret offset Offset to extended capability, or zero if not found
- */
-static unsigned int xhci_extended_capability ( struct xhci_host *xhci,
- unsigned int id,
- unsigned int offset ) {
- uint32_t xecp;
- unsigned int next;
-
- /* Locate the extended capability */
- while ( 1 ) {
-
- /* Locate first or next capability as applicable */
- if ( offset ) {
- xecp = readl ( xhci->cap + offset );
- next = XHCI_XECP_NEXT ( xecp );
- } else {
- next = xhci->xecp;
- }
- if ( ! next )
- return 0;
- offset += next;
-
- /* Check if this is the requested capability */
- xecp = readl ( xhci->cap + offset );
- if ( XHCI_XECP_ID ( xecp ) == id )
- return offset;
- }
-}
-
-/**
- * Initialise USB legacy support
- *
- * @v xhci xHCI device
- */
-static void xhci_legacy_init ( struct xhci_host *xhci ) {
- unsigned int legacy;
- uint8_t bios;
-
- /* Locate USB legacy support capability (if present) */
- legacy = xhci_extended_capability ( xhci, XHCI_XECP_ID_LEGACY, 0 );
- if ( ! legacy ) {
- /* Not an error; capability may not be present */
- USB_LOG_DBG("XHCI %s has no USB legacy support capability\n",
- xhci->name );
- return;
- }
-
- /* Check if legacy USB support is enabled */
- USB_LOG_DBG("XHCI %s bios offset 0x%x\n", xhci->name, (xhci->cap + legacy + XHCI_USBLEGSUP_BIOS));
- /* bios = readb ( xhci->cap + legacy + XHCI_USBLEGSUP_BIOS ); cannot access offset 0x2, work around */
- bios = readl ( xhci->cap + legacy );
- bios = (bios >> 16) & 0xffff;
- if ( ! ( bios & XHCI_USBLEGSUP_BIOS_OWNED ) ) {
- /* Not an error; already owned by OS */
- USB_LOG_DBG("XHCI %s USB legacy support already disabled\n",
- xhci->name );
- return;
- }
-
- /* Record presence of USB legacy support capability */
- xhci->legacy = legacy;
-}
-
-/**
- * Claim ownership from BIOS
- *
- * @v xhci xHCI device
- */
-static void xhci_legacy_claim ( struct xhci_host *xhci ) {
- uint32_t ctlsts;
- uint8_t bios;
- unsigned int i;
-
- /* Do nothing unless legacy support capability is present */
- if ( ! xhci->legacy )
- return;
-
- /* Claim ownership */
- writeb ( XHCI_USBLEGSUP_OS_OWNED,
- xhci->cap + xhci->legacy + XHCI_USBLEGSUP_OS );
-
- /* Wait for BIOS to release ownership */
- for ( i = 0 ; i < XHCI_USBLEGSUP_MAX_WAIT_MS ; i++ ) {
-
- /* Check if BIOS has released ownership */
- bios = readb ( xhci->cap + xhci->legacy + XHCI_USBLEGSUP_BIOS );
- if ( ! ( bios & XHCI_USBLEGSUP_BIOS_OWNED ) ) {
- USB_LOG_DBG("XHCI %s claimed ownership from BIOS\n",
- xhci->name );
- ctlsts = readl ( xhci->cap + xhci->legacy +
- XHCI_USBLEGSUP_CTLSTS );
- if ( ctlsts ) {
- USB_LOG_DBG("XHCI %s warning: BIOS retained "
- "SMIs: %08x\n", xhci->name, ctlsts );
- }
- return;
- }
-
- /* Delay */
- usb_osal_msleep ( 1 );
- }
-
- /* BIOS did not release ownership. Claim it forcibly by
- * disabling all SMIs.
- */
- USB_LOG_DBG("XHCI %s could not claim ownership from BIOS: forcibly "
- "disabling SMIs\n", xhci->name );
- writel ( 0, xhci->cap + xhci->legacy + XHCI_USBLEGSUP_CTLSTS );
-}
-
-/** Prevent the release of ownership back to BIOS */
-static int xhci_legacy_prevent_release;
-
-/**
- * Release ownership back to BIOS
- *
- * @v xhci xHCI device
- */
-static void xhci_legacy_release ( struct xhci_host *xhci ) {
-
- /* Do nothing unless legacy support capability is present */
- if ( ! xhci->legacy )
- return;
-
- /* Do nothing if releasing ownership is prevented */
- if ( xhci_legacy_prevent_release ) {
- USB_LOG_DBG("XHCI %s not releasing ownership to BIOS\n",
- xhci->name );
- return;
- }
-
- /* Release ownership */
- writeb ( 0, xhci->cap + xhci->legacy + XHCI_USBLEGSUP_OS );
- USB_LOG_DBG("XHCI %s released ownership to BIOS\n", xhci->name );
-}
-
-/**
- * Stop xHCI device
- *
- * @v xhci xHCI device
- * @ret rc Return status code
- */
-static int xhci_stop ( struct xhci_host *xhci ) {
- uint32_t usbcmd;
- uint32_t usbsts;
- unsigned int i;
-
- /* Clear run/stop bit */
- usbcmd = readl ( xhci->op + XHCI_OP_USBCMD );
- usbcmd &= ~XHCI_USBCMD_RUN;
- writel ( usbcmd, xhci->op + XHCI_OP_USBCMD );
-
- /* Wait for device to stop */
- for ( i = 0 ; i < XHCI_STOP_MAX_WAIT_MS ; i++ ) {
-
- /* Check if device is stopped */
- usbsts = readl ( xhci->op + XHCI_OP_USBSTS );
- if ( usbsts & XHCI_USBSTS_HCH )
- return 0;
-
- /* Delay */
- usb_osal_msleep ( 1 );
- }
-
- USB_LOG_DBG("XHCI %s timed out waiting for stop\n", xhci->name );
- return -ETIMEDOUT;
-}
-
-/**
- * Reset xHCI device
- *
- * @v xhci xHCI device
- * @ret rc Return status code
- */
-static int xhci_reset ( struct xhci_host *xhci ) {
- uint32_t usbcmd;
- unsigned int i;
- int rc;
-
- /* The xHCI specification states that resetting a running
- * device may result in undefined behaviour, so try stopping
- * it first.
- */
- if ( ( rc = xhci_stop ( xhci ) ) != 0 ) {
- /* Ignore errors and attempt to reset the device anyway */
- }
-
- /* Reset device */
- writel ( XHCI_USBCMD_HCRST, xhci->op + XHCI_OP_USBCMD );
-
- /* Wait for reset to complete */
- for ( i = 0 ; i < XHCI_RESET_MAX_WAIT_MS ; i++ ) {
-
- /* Check if reset is complete */
- usbcmd = readl ( xhci->op + XHCI_OP_USBCMD );
- if ( ! ( usbcmd & XHCI_USBCMD_HCRST ) )
- return 0;
-
- /* Delay */
- usb_osal_msleep ( 1 );
- }
-
- USB_LOG_DBG("XHCI %s timed out waiting for reset\n", xhci->name );
- return -ETIMEDOUT;
-}
-
-
-/**
- * Find supported protocol extended capability for a port
- *
- * @v xhci xHCI device
- * @v port Port number
- * @ret supported Offset to extended capability, or zero if not found
- */
-static unsigned int xhci_supported_protocol ( struct xhci_host *xhci,
- unsigned int port ) {
- unsigned int supported = 0;
- unsigned int offset;
- unsigned int count;
- uint32_t ports;
-
- /* Iterate over all supported protocol structures */
- while ( ( supported = xhci_extended_capability ( xhci,
- XHCI_XECP_ID_SUPPORTED,
- supported ) ) ) {
-
- /* Determine port range */
- ports = readl ( xhci->cap + supported + XHCI_SUPPORTED_PORTS );
- offset = XHCI_SUPPORTED_PORTS_OFFSET ( ports );
- count = XHCI_SUPPORTED_PORTS_COUNT ( ports );
-
- /* Check if port lies within this range */
- if ( ( port - offset ) < count )
- return supported;
- }
-
- USB_LOG_DBG("XHCI %s Port-%d has no supported protocol\n",
- xhci->name, port );
- return 0;
-}
-
-/**
- * Transcribe port speed (for debugging)
- *
- * @v psi Protocol speed ID
- * @ret speed Transcribed speed
- */
-static inline const char * xhci_speed_name ( uint32_t psi ) {
- static const char *exponents[4] = { "", "k", "M", "G" };
- static char buf[ 10 /* "xxxxxXbps" + NUL */ ];
- unsigned int mantissa;
- unsigned int exponent;
-
- /* Extract mantissa and exponent */
- mantissa = XHCI_SUPPORTED_PSI_MANTISSA ( psi );
- exponent = XHCI_SUPPORTED_PSI_EXPONENT ( psi );
-
- /* Transcribe speed */
- snprintf ( buf, sizeof ( buf ), "%d%sbps",
- mantissa, exponents[exponent] );
- return buf;
-}
-
-/**
- * Find port protocol
- *
- * @v xhci xHCI device
- * @v port Port number
- * @ret protocol USB protocol, or zero if not found
- */
-static unsigned int xhci_port_protocol ( struct xhci_host *xhci,
- unsigned int port ) {
- unsigned int supported = xhci_supported_protocol ( xhci, port );
- union {
- uint32_t raw;
- char text[5];
- } name;
- unsigned int protocol;
- unsigned int type;
- unsigned int psic;
- unsigned int psiv;
- unsigned int i;
- uint32_t revision;
- uint32_t ports;
- uint32_t slot;
- uint32_t psi;
-
- /* Fail if there is no supported protocol */
- if ( ! supported )
- return 0;
-
- /* Determine protocol version */
- revision = readl ( xhci->cap + supported + XHCI_SUPPORTED_REVISION );
- protocol = XHCI_SUPPORTED_REVISION_VER ( revision );
-
- /* Describe port protocol */
-#if XHCI_DUMP
- {
- name.raw = CPU_TO_LE32 ( readl ( xhci->cap + supported +
- XHCI_SUPPORTED_NAME ) );
- name.text[4] = '\0';
- slot = readl ( xhci->cap + supported + XHCI_SUPPORTED_SLOT );
- type = XHCI_SUPPORTED_SLOT_TYPE ( slot );
- USB_LOG_DBG("XHCI %s-%d %sv%04x type %d \r\n",
- xhci->name, port, name.text, protocol, type );
- ports = readl ( xhci->cap + supported + XHCI_SUPPORTED_PORTS );
- psic = XHCI_SUPPORTED_PORTS_PSIC ( ports );
- if ( psic ) {
- USB_LOG_DBG(" speeds \r\n" );
- for ( i = 0 ; i < psic ; i++ ) {
- psi = readl ( xhci->cap + supported +
- XHCI_SUPPORTED_PSI ( i ) );
- psiv = XHCI_SUPPORTED_PSI_VALUE ( psi );
- USB_LOG_DBG(" %d:%s \r\n", psiv, xhci_speed_name ( psi ) );
- }
- }
- }
-#endif
-
- return protocol;
-}
-
-/**
- * Probe XCHI device
- *
- * @v xhci XCHI device
- * @v baseaddr XHCI device register base address
- * @ret rc Return status code
- */
-int xhci_probe ( struct xhci_host *xhci, unsigned long baseaddr ) {
- USB_ASSERT(xhci);
- int error = 0;
- struct usbh_hubport *port;
- unsigned int i;
-
- xhci->base = (void *)baseaddr;
- xhci->name[0] = '0' + xhci->id; /* Assert there are less than 10 xhci host */
- xhci->name[1] = '\0';
-
- /* Initialise xHCI device */
- xhci_init ( xhci, xhci->base );
-
- /* Initialise USB legacy support and claim ownership */
- xhci_legacy_init ( xhci );
- xhci_legacy_claim ( xhci );
-
- /* Reset device */
- if ( ( error = xhci_reset ( xhci ) ) != 0 )
- goto err_reset;
-
- /* Set port protocols */
- for ( i = 1 ; i <= xhci->ports ; i++ ) {
- port = usbh_get_roothub_port ( i );
- port->protocol = xhci_port_protocol ( xhci, i );
- }
-
- return error;
-
-err_reset:
- xhci_legacy_release ( xhci );
- return -1;
-}
-
-/*********************************************************************/
-
-/**
- * Allocate device context base address array
- *
- * @v xhci xHCI device
- * @ret rc Return status code
- */
-static int xhci_dcbaa_alloc ( struct xhci_host *xhci ) {
- size_t len;
- uintptr_t dcbaap;
- int rc;
-
- /* Allocate and initialise structure. Must be at least
- * 64-byte aligned and must not cross a page boundary, so
- * align on its own size (rounded up to a power of two and
- * with a minimum of 64 bytes).
- */
- len = ( ( xhci->slots + 1 ) * sizeof ( xhci->dcbaa.context[0] ) );
- xhci->dcbaa.context = usb_align(xhci_align ( len ), len);
- if ( ! xhci->dcbaa.context ) {
- USB_LOG_ERR("XHCI %s could not allocate DCBAA\n", xhci->name );
- rc = -ENOMEM;
- goto err_alloc;
- }
- memset ( xhci->dcbaa.context, 0, len );
-
- /* Program DCBAA pointer */
- dcbaap = (uintptr_t)( xhci->dcbaa.context );
- if ( ( rc = xhci_writeq ( xhci, dcbaap,
- xhci->op + XHCI_OP_DCBAAP ) ) != 0 )
- goto err_writeq;
-
- USB_LOG_DBG("XHCI %s DCBAA at [%08lx,%08lx)\n", xhci->name,
- ( xhci->dcbaa.context ),
- ( ( xhci->dcbaa.context ) + len ) );
- return 0;
-
- err_writeq:
- usb_free ( xhci->dcbaa.context );
- err_alloc:
- return rc;
-}
-
-
-/**
- * Allocate scratchpad buffers
- *
- * @v xhci xHCI device
- * @ret rc Return status code
- */
-static int xhci_scratchpad_alloc ( struct xhci_host *xhci ) {
- struct xhci_scratchpad *scratch = &xhci->scratch;
- size_t buffer_len;
- size_t array_len;
- uintptr_t addr;
- unsigned int i;
- int rc;
-
- /* Do nothing if no scratchpad buffers are used */
- if ( ! scratch->count ) {
- USB_LOG_INFO("XHCI %s no need to allocate scratchpad buffers\n",
- xhci->name );
- return 0;
- }
-
- /* Allocate scratchpad buffers */
- buffer_len = ( scratch->count * xhci->pagesize );
- scratch->buffer = (uintptr_t)usb_align ( xhci->pagesize, buffer_len );
- if ( ! scratch->buffer ) {
- USB_LOG_ERR("XHCI %s could not allocate scratchpad buffers\n",
- xhci->name );
- rc = -ENOMEM;
- goto err_alloc;
- }
- memset ( (void *)scratch->buffer, 0, buffer_len );
-
- /* Allocate scratchpad array */
- array_len = ( scratch->count * sizeof ( scratch->array[0] ) );
- scratch->array = usb_align(xhci_align ( array_len ), array_len);
- if ( ! scratch->array ) {
- USB_LOG_ERR("XHCI %s could not allocate scratchpad buffer "
- "array\n", xhci->name );
- rc = -ENOMEM;
- goto err_alloc_array;
- }
-
- /* Populate scratchpad array */
- addr = ( scratch->buffer + 0 );
- for ( i = 0 ; i < scratch->count ; i++ ) {
- scratch->array[i] = CPU_TO_LE64 ( addr );
- addr += xhci->pagesize;
- }
-
- /* Set scratchpad array pointer */
- USB_ASSERT ( xhci->dcbaa.context != NULL );
- xhci->dcbaa.context[0] = CPU_TO_LE64 ( ( scratch->array ) );
-
- USB_LOG_DBG("XHCI %s scratchpad [%08lx,%08lx) array [%08lx,%08lx)\n",
- xhci->name, ( scratch->buffer, 0 ),
- ( scratch->buffer, buffer_len ),
- ( scratch->array ),
- ( ( scratch->array ) + array_len ) );
- return 0;
-
- usb_free ( scratch->array );
- err_alloc_array:
- usb_free ( scratch->buffer );
- err_alloc:
- return rc;
-}
-
-/**
- * Allocate command ring
- *
- * @v xhci xHCI device
- * @ret rc Return status code
- */
-static int xhci_command_alloc ( struct xhci_host *xhci ) {
- uintptr_t crp;
- int rc;
-
- /* Allocate TRB ring */
- xhci->cmds = usb_align(XHCI_RING_SIZE, sizeof(*xhci->cmds)); /* command ring */
- if (! xhci->cmds)
- goto err_ring_alloc;
-
- memset(xhci->cmds, 0U, sizeof(*xhci->cmds));
-
- xhci->cmds->lock = usb_osal_mutex_create();
- USB_ASSERT(xhci->cmds->lock);
-
- xhci->cmds->cs = 1; /* cycle state = 1 */
-
- /* Program command ring control register */
- crp = (uintptr_t)( xhci->cmds );
- if ( ( rc = xhci_writeq ( xhci, ( crp | XHCI_CRCR_RCS ),
- xhci->op + XHCI_OP_CRCR ) ) != 0 )
- goto err_writeq;
-
- USB_LOG_DBG("XHCI %s CRCR at [%08lx,%08lx)\n", xhci->name,
- ( xhci->cmds->ring ),
- ( ( xhci->cmds->ring ) + sizeof(xhci->cmds->ring) ) );
- return 0;
-
- err_writeq:
- usb_free(xhci->cmds);;
- err_ring_alloc:
- return rc;
-}
-
-/**
- * Allocate event ring
- *
- * @v xhci xHCI device
- * @ret rc Return status code
- */
-static int xhci_event_alloc ( struct xhci_host *xhci ) {
- unsigned int count;
- size_t len;
- int rc;
-
- /* Allocate event ring */
- xhci->evts = usb_align(XHCI_RING_SIZE, sizeof(*xhci->evts)); /* event ring */
- if ( ! xhci->evts ) {
- rc = -ENOMEM;
- goto err_alloc_trb;
- }
-
- memset(xhci->evts, 0U, sizeof(*xhci->evts));
-
- /* Allocate event ring segment table */
- xhci->eseg = usb_align(XHCI_ALIGMENT, sizeof(*xhci->eseg)); /* event segment */
- if ( ! xhci->eseg ) {
- rc = -ENOMEM;
- goto err_alloc_segment;
- }
- memset(xhci->eseg, 0U, sizeof(*xhci->eseg));
- xhci->eseg->base = CPU_TO_LE64 ( ( xhci->evts ) );
- xhci->eseg->count = XHCI_RING_ITEMS; /* items of event ring TRB */
-
- /* Program event ring registers */
- writel ( 1, xhci->run + XHCI_RUN_ERSTSZ ( 0 ) ); /* bit[15:0] event ring segment table size */
- if ( ( rc = xhci_writeq ( xhci, (uintptr_t)( xhci->evts ),
- xhci->run + XHCI_RUN_ERDP ( 0 ) ) ) != 0 ) /* bit[63:4] event ring dequeue pointer */
- goto err_writeq_erdp;
- if ( ( rc = xhci_writeq ( xhci, (uintptr_t)( xhci->eseg ),
- xhci->run + XHCI_RUN_ERSTBA ( 0 ) ) ) != 0 ) /* bit[63:6] event ring segment table base addr */
- goto err_writeq_erstba;
-
- xhci->evts->cs = 1; /* cycle state = 1 */
- USB_LOG_DBG("XHCI %s event ring [%08lx,%08lx) table [%08lx,%08lx)\n",
- xhci->name, ( xhci->evts->ring ),
- ( ( xhci->evts->ring ) + sizeof(xhci->evts->ring) ),
- ( xhci->eseg ),
- ( ( xhci->eseg ) +
- sizeof ( xhci->eseg[0] ) ) );
- return 0;
-
- xhci_writeq ( xhci, 0, xhci->run + XHCI_RUN_ERSTBA ( 0 ) );
- err_writeq_erstba:
- xhci_writeq ( xhci, 0, xhci->run + XHCI_RUN_ERDP ( 0 ) );
- err_writeq_erdp:
- usb_free ( xhci->eseg );
- err_alloc_segment:
- usb_free ( xhci->evts );
- err_alloc_trb:
- return rc;
-}
-
-/**
- * Start xHCI device
- *
- * @v xhci xHCI device
- */
-static void xhci_run ( struct xhci_host *xhci ) {
- uint32_t config;
- uint32_t usbcmd;
- uint32_t runtime;
-
- /* Configure number of device slots */
- config = readl ( xhci->op + XHCI_OP_CONFIG );
- config &= ~XHCI_CONFIG_MAX_SLOTS_EN_MASK;
- config |= XHCI_CONFIG_MAX_SLOTS_EN ( xhci->slots );
- writel ( config, xhci->op + XHCI_OP_CONFIG );
-
- /* Enable port interrupt */
- writel ( 500U, xhci->run + XHCI_RUN_IR_IMOD ( 0 ) );
- runtime = readl(xhci->run + XHCI_RUN_IR_IMAN ( 0 ));
- runtime |= XHCI_RUN_IR_IMAN_IE;
- writel (runtime, xhci->run + XHCI_RUN_IR_IMAN ( 0 ));
-
- /* Set run/stop bit and enable interrupt */
- usbcmd = readl ( xhci->op + XHCI_OP_USBCMD );
- usbcmd |= XHCI_USBCMD_RUN | XHCI_USBCMD_INTE;
- writel ( usbcmd, xhci->op + XHCI_OP_USBCMD );
-
- USB_LOG_DBG("XHCI %s start running\n", xhci->name );
-}
-
-/**
- * Free event ring
- *
- * @v xhci xHCI device
- */
-static void xhci_event_free ( struct xhci_host *xhci ) {
-
- /* Clear event ring registers */
- 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_ERDP ( 0 ) );
-
- /* Free event ring segment table */
- usb_free ( xhci->eseg );
-
- /* Free event ring */
- usb_free ( xhci->evts );
-}
-
-/**
- * Free command ring
- *
- * @v xhci xHCI device
- */
-static void xhci_command_free ( struct xhci_host *xhci ) {
-
- /* Sanity check */
- USB_ASSERT ( ( readl ( xhci->op + XHCI_OP_CRCR ) & XHCI_CRCR_CRR ) == 0 );
-
- /* Clear command ring control register */
- xhci_writeq ( xhci, 0, xhci->op + XHCI_OP_CRCR );
-
- /* Free TRB ring */
- usb_free ( xhci->cmds );
-}
-
-/**
- * Free scratchpad buffers
- *
- * @v xhci xHCI device
- */
-static void xhci_scratchpad_free ( struct xhci_host *xhci ) {
- struct xhci_scratchpad *scratch = &xhci->scratch;
- size_t array_len;
- size_t buffer_len;
-
- /* Do nothing if no scratchpad buffers are used */
- if ( ! scratch->count )
- return;
-
- /* Clear scratchpad array pointer */
- USB_ASSERT ( xhci->dcbaa.context != NULL );
- xhci->dcbaa.context[0] = 0;
-
- /* Free scratchpad array */
- array_len = ( scratch->count * sizeof ( scratch->array[0] ) );
- usb_free ( scratch->array );
-
- /* Free scratchpad buffers */
- buffer_len = ( scratch->count * xhci->pagesize );
- usb_free ( scratch->buffer );
-}
-
-/**
- * Free device context base address array
- *
- * @v xhci xHCI device
- */
-static void xhci_dcbaa_free ( struct xhci_host *xhci ) {
- size_t len;
- unsigned int i;
-
- /* Sanity check */
- for ( i = 0 ; i <= xhci->slots ; i++ )
- USB_ASSERT ( xhci->dcbaa.context[i] == 0 );
-
- /* Clear DCBAA pointer */
- xhci_writeq ( xhci, 0, xhci->op + XHCI_OP_DCBAAP );
-
- /* Free DCBAA */
- len = ( ( xhci->slots + 1 ) * sizeof ( xhci->dcbaa.context[0] ) );
- usb_free ( xhci->dcbaa.context );
-}
-
-/**
- * Open XHCI device
- *
- * @v xhci XHCI device
- * @ret rc Return status code
- */
-int xhci_open ( struct xhci_host *xhci ) {
- int rc;
-
- /* Allocate device slot array */
- xhci->slot = usb_malloc ( ( xhci->slots + 1 ) * sizeof ( xhci->slot[0] ) );
- if ( ! xhci->slot ) {
- rc = -ENOMEM;
- goto err_slot_alloc;
- }
-
- /* Allocate device context base address array */
- if ( ( rc = xhci_dcbaa_alloc ( xhci ) ) != 0 )
- goto err_dcbaa_alloc;
-
- /* Allocate scratchpad buffers */
- if ( ( rc = xhci_scratchpad_alloc ( xhci ) ) != 0 )
- goto err_scratchpad_alloc;
-
- /* Allocate command ring */
- if ( ( rc = xhci_command_alloc ( xhci ) ) != 0 )
- goto err_command_alloc;
-
- /* Allocate event ring */
- if ( ( rc = xhci_event_alloc ( xhci ) ) != 0 )
- goto err_event_alloc;
-
- /* Start controller */
- xhci_run ( xhci );
-
- return 0;
-
- xhci_stop ( xhci );
- xhci_event_free ( xhci );
- err_event_alloc:
- xhci_command_free ( xhci );
- err_command_alloc:
- xhci_scratchpad_free ( xhci );
- err_scratchpad_alloc:
- xhci_dcbaa_free ( xhci );
- err_dcbaa_alloc:
- usb_free ( xhci->slot );
- err_slot_alloc:
- return rc;
-
-}
-
-/**
- * Close XHCI device
- *
- * @v xhci XHCI Device
- */
-void xhci_close ( struct xhci_host *xhci ) {
- unsigned int i;
-
- /* Sanity checks */
- USB_ASSERT ( xhci->slot != NULL );
- for ( i = 0 ; i <= xhci->slots ; i++ )
- USB_ASSERT ( xhci->slot[i] == NULL );
-
- xhci_stop ( xhci );
- usb_free (xhci->evts);
- usb_free (xhci->eseg);
- usb_free (xhci->cmds);
- xhci_scratchpad_free ( xhci );
- xhci_dcbaa_free ( xhci );
- usb_free ( xhci->slot );
-}
-
-/**
- * Remove XHCI device
- *
- * @v xhci XHCI device
- */
-void xhci_remove ( struct xhci_host *xhci ) {
- xhci_reset ( xhci );
- xhci_legacy_release ( xhci );
- usb_free ( xhci );
-
- /* If we are shutting down to boot an OS, then prevent the
- * release of ownership back to BIOS.
- */
- xhci_legacy_prevent_release = 0;
-}
-
-/*********************************************************************/
-
-/**
- * Enable port
- *
- * @v xhci XHCI device
- * @v port Port number
- * @ret rc Return status code
- */
-int xhci_port_enable(struct xhci_host *xhci, uint32_t port) {
- uint32_t portsc = readl ( xhci->op + XHCI_OP_PORTSC ( port ) );
-
- /* double check if connected */
- if (!(portsc & XHCI_PORTSC_CCS)) {
- USB_LOG_ERR("device connectiong lost !!! \r\n");
- return -ENOENT;
- }
-
- switch ( portsc & XHCI_PORTSC_PLS_MASK )
- {
- case XHCI_PORTSC_PLS_U0:
- /* A USB3 port - controller automatically performs reset */
- break;
- case XHCI_PORTSC_PLS_POLLING:
- /* A USB2 port - perform device reset */
- xhci_dump_port_status(port, portsc);
- writel ((portsc | XHCI_PORTSC_PR), (xhci->op + XHCI_OP_PORTSC ( port ))); /* reset port */
- break;
- default:
- USB_LOG_ERR("PLS: %d \r\n", (portsc & XHCI_PORTSC_PLS_MASK));
- return -ENOENT;
- }
-
- /* Wait for device to complete reset and be enabled */
- uint32_t end = 1000U, start = 0U;
- for (;;) {
- portsc = readl ( xhci->op + XHCI_OP_PORTSC ( port ) );
- if (!(portsc & XHCI_PORTSC_CCS)) {
- /* USB 2.0 port would be disconnected after reset */
- USB_LOG_INFO("USB 2.0 port disconnected during reset, need rescan \r\n");
- return 0;
- }
-
- if (portsc & XHCI_PORTSC_PED) { /* check if port enabled */
- /* Reset complete */
- break;
- }
-
- if (++start > end) {
- USB_LOG_ERR("Wait timeout, portsc=0x%x !!!\n", portsc);
- return -ENXIO;
- }
-
- usb_osal_msleep(1);
- }
-
- xhci_dump_port_status(port, portsc);
- return 0;
-}
-
-/**
- * Convert USB Speed to PSI
- *
- * @v speed USB speed
- * @ret psi USB speed in PSI
- */
-static unsigned int xhci_speed_to_psi(int speed) {
- unsigned int psi = USB_SPEED_UNKNOWN;
-
- switch (speed) {
- case USB_SPEED_LOW:
- psi = XCHI_PSI_LOW;
- break;
- case USB_SPEED_FULL:
- psi = XCHI_PSI_FULL;
- break;
- case USB_SPEED_HIGH:
- psi = XCHI_PSI_HIGH;
- break;
- case USB_SPEED_SUPER:
- psi = XCHI_PSI_SUPER;
- break;
- }
-
- return psi;
-}
-
-/**
- * Convert USB PSI to Speed
- *
- * @v psi USB speed in PSI
- * @ret speed USB speed
- */
-static int xhci_psi_to_speed(int psi) {
- int speed = USB_SPEED_UNKNOWN;
-
- switch (psi) {
- case XCHI_PSI_LOW:
- speed = USB_SPEED_LOW;
- break;
- case XCHI_PSI_FULL:
- speed = USB_SPEED_FULL;
- break;
- case XCHI_PSI_HIGH:
- speed = USB_SPEED_HIGH;
- break;
- case XCHI_PSI_SUPER:
- speed = USB_SPEED_SUPER;
- break;
- }
-
- return speed;
-}
-
-/**
- * Find port speed
- *
- * @v xhci xHCI device
- * @v port Port number
- * @v psiv Protocol speed ID value
- * @ret speed Port speed, or negative error
- */
-static int xhci_port_speed ( struct xhci_host *xhci, unsigned int port,
- unsigned int psiv ) {
- unsigned int supported = xhci_supported_protocol ( xhci, port );
- unsigned int psic;
- unsigned int mantissa;
- unsigned int exponent;
- unsigned int speed;
- unsigned int i;
- uint32_t ports;
- uint32_t psi;
-
- /* Fail if there is no supported protocol */
- if ( ! supported )
- return -ENOTSUP;
-
- /* Get protocol speed ID count */
- ports = readl ( xhci->cap + supported + XHCI_SUPPORTED_PORTS );
- psic = XHCI_SUPPORTED_PORTS_PSIC ( ports );
-
- /* Use protocol speed ID table unless device is known to be faulty */
- /* Iterate over PSI dwords looking for a match */
- for ( i = 0 ; i < psic ; i++ ) {
- psi = readl ( xhci->cap + supported +
- XHCI_SUPPORTED_PSI ( i ) );
- if ( psiv == XHCI_SUPPORTED_PSI_VALUE ( psi ) ) {
- mantissa = XHCI_SUPPORTED_PSI_MANTISSA ( psi );
- exponent = XHCI_SUPPORTED_PSI_EXPONENT ( psi );
- return xhci_psi_to_speed(XCHI_PSI ( mantissa, exponent ));
- }
- }
-
- /* Record device as faulty if no match is found */
- if ( psic != 0 ) {
- USB_LOG_ERR("XHCI %s-%d spurious PSI value %d: "
- "assuming PSI table is invalid\n",
- xhci->name, port, psiv );
- }
-
- /* Use the default mappings */
- switch ( psiv ) {
- case XHCI_SPEED_LOW : return USB_SPEED_LOW;
- case XHCI_SPEED_FULL : return USB_SPEED_FULL;
- case XHCI_SPEED_HIGH : return USB_SPEED_HIGH;
- case XHCI_SPEED_SUPER : return USB_SPEED_SUPER;
- default:
- USB_LOG_ERR("XHCI %s-%d unrecognised PSI value %d\n",
- xhci->name, port, psiv );
- return -ENOTSUP;
- }
-}
-
-/**
- * Find protocol speed ID value
- *
- * @v xhci xHCI device
- * @v port Port number
- * @v speed USB speed
- * @ret psiv Protocol speed ID value, or negative error
- */
-static int xhci_port_psiv ( struct xhci_host *xhci, unsigned int port,
- unsigned int speed ) {
- unsigned int supported = xhci_supported_protocol ( xhci, port );
- unsigned int psic;
- unsigned int mantissa;
- unsigned int exponent;
- unsigned int psiv;
- unsigned int i;
- uint32_t ports;
- uint32_t psi;
-
- /* Fail if there is no supported protocol */
- if ( ! supported )
- return -ENOTSUP;
-
- /* Get protocol speed ID count */
- ports = readl ( xhci->cap + supported + XHCI_SUPPORTED_PORTS );
- psic = XHCI_SUPPORTED_PORTS_PSIC ( ports );
-
- /* Use the default mappings if applicable */
- if ( psic == 0 ) {
- switch ( speed ) {
- case USB_SPEED_LOW : return XHCI_SPEED_LOW;
- case USB_SPEED_FULL : return XHCI_SPEED_FULL;
- case USB_SPEED_HIGH : return XHCI_SPEED_HIGH;
- case USB_SPEED_SUPER : return XHCI_SPEED_SUPER;
- default:
- USB_LOG_DBG("XHCI %s-%d non-standard speed %d\n",
- xhci->name, port, speed );
- return -ENOTSUP;
- }
- }
-
- /* Iterate over PSI dwords looking for a match */
- for ( i = 0 ; i < psic ; i++ ) {
- psi = readl ( xhci->cap + supported + XHCI_SUPPORTED_PSI ( i ));
- mantissa = XHCI_SUPPORTED_PSI_MANTISSA ( psi );
- exponent = XHCI_SUPPORTED_PSI_EXPONENT ( psi );
- if ( xhci_speed_to_psi(speed) == XCHI_PSI ( mantissa, exponent ) ) {
- psiv = XHCI_SUPPORTED_PSI_VALUE ( psi );
- return psiv;
- }
- }
-
- USB_LOG_DBG("XHCI %s-%d unrepresentable speed %#x\n",
- xhci->name, port, speed );
- return -ENOENT;
-}
-
-/**
- * Update root hub port speed
- *
- * @v xhci XHCI device
- * @v port Port number
- * @ret rc Return status code (speed)
- */
-uint32_t xhci_root_speed ( struct xhci_host *xhci, uint8_t port ) {
- uint32_t portsc;
- unsigned int psiv;
- int ccs;
- int ped;
- int csc;
- int speed;
- unsigned int protocol = xhci_port_protocol(xhci, port);
-
- /* Read port status */
- portsc = readl ( xhci->op + XHCI_OP_PORTSC ( port ) );
- USB_LOG_DBG("XHCI %s-%d status is 0x%08x, protocol 0x%x\n",
- xhci->name, port, portsc, protocol );
- ccs = ( portsc & XHCI_PORTSC_CCS );
- ped = ( portsc & XHCI_PORTSC_PED );
- csc = ( portsc & XHCI_PORTSC_CSC );
- psiv = XHCI_PORTSC_PSIV ( portsc );
-
- USB_LOG_DBG("XHCI %s port-%d ccs: %d, ped: %d, csc: %d, psiv: 0x%x\n",
- xhci->name, port, !!ccs, !!ped, !!csc, psiv);
-
- /* Port speed is not valid unless port is connected */
- if ( ! ccs ) {
- speed = USB_SPEED_UNKNOWN;
- USB_LOG_ERR("XHCI %s port-%d speed unkown\n", xhci->name, port);
- return speed;
- }
-
- /* For USB2 ports, the PSIV field is not valid until the port
- * completes reset and becomes enabled.
- */
- if ( ( protocol < USB_3_0 ) && ! ped ) {
- speed = USB_SPEED_FULL;
- return speed;
- }
-
- /* Get port speed and map to generic USB speed */
- speed = xhci_port_speed ( xhci, port, psiv );
- if ( speed < 0 ) {
- return speed;
- }
-
- return speed;
-}
-
-/*********************************************************************/
-/**
- * Add a TRB to the given ring
- *
- * @v ring XHCI TRB ring
- * @v trb TRB content to be added
- */
-static inline void xhci_trb_fill(struct xhci_ring *ring, union xhci_trb *trb) {
- union xhci_trb *dst = &ring->ring[ring->nidx];
- memcpy((void *)dst, (void *)trb, sizeof(*trb));
- dst->template.control |= (ring->cs ? XHCI_TRB_C : 0);
- xhci_dump_trbs(dst, 1);
-}
-
-/**
- * Queue a TRB onto a ring, wrapping ring as needed
- *
- * @v ring XHCI TRB ring
- * @v trb TRB content to be added
- */
-static void xhci_trb_queue(struct xhci_ring *ring, union xhci_trb *trb) {
-
- if (ring->nidx >= XHCI_RING_ITEMS - 1) {
- /* if it is the last trb in the list, put a link trb in the end */
- union xhci_trb link_trb;
- link_trb.link.type = XHCI_TRB_LINK;
- link_trb.link.flags = XHCI_TRB_TC;
- link_trb.link.next = CPU_TO_LE64((ring->ring));
-
- xhci_trb_fill(ring, &link_trb);
-
- ring->nidx = 0; /* adjust dequeue index to 0 */
- ring->cs ^= 1; /* toggle cycle interpretation of sw */
- }
-
- xhci_trb_fill(ring, trb);
- ring->nidx++; /* ahead dequeue index */
-}
-
-/**
- * Wait for a ring to empty (all TRBs processed by hardware)
- *
- * @v xhci XHCI Device
- * @v ep Owner Endpoint of current TRB ring
- * @ ring XHCI TRB ring
- */
-int xhci_event_wait(struct xhci_host *xhci,
- struct xhci_endpoint *ep,
- struct xhci_ring *ring) {
- int cc = XHCI_CMPLT_SUCCESS;
-
- if (ep->timeout > 0)
- {
- if (usb_osal_sem_take(ep->waitsem, ep->timeout) < 0)
- {
- cc = XHCI_CMPLT_TIMEOUT;
- }
- else
- {
- cc = ring->evt.complete.code; /* bit[31:24] completion code */
- }
- }
-
- return cc;
-}
-
-/**
- * Ring doorbell register
- *
- * @v xhci XHCI device
- * @v slotid Slot id to ring
- * @v value Value send to doorbell
- */
-static inline void xhci_doorbell ( struct xhci_host *xhci, uint32_t slotid, uint32_t value ) {
-
- DSB();
- writel ( value, xhci->db + slotid * XHCI_REG_DB_SIZE ); /* bit[7:0] db target, is ep_id */
-}
-
-/**
- * Abort command
- *
- * @v xhci xHCI device
- */
-static void xhci_abort ( struct xhci_host *xhci ) {
- uintptr_t crp;
-
- /* Abort the command */
- USB_LOG_WRN("XHCI %s aborting command\n", xhci->name );
- xhci_writeq ( xhci, XHCI_CRCR_CA, xhci->op + XHCI_OP_CRCR );
-
- /* Allow time for command to abort */
- usb_osal_msleep ( XHCI_COMMAND_ABORT_DELAY_MS );
-
- /* Sanity check */
- USB_ASSERT ( ( readl ( xhci->op + XHCI_OP_CRCR ) & XHCI_CRCR_CRR ) == 0 );
-
- /* Consume (and ignore) any final command status */
- int cc = xhci_event_wait(xhci, xhci->cur_cmd_pipe, xhci->cmds);
- if (XHCI_CMPLT_SUCCESS != cc) {
- USB_LOG_ERR("XHCI %s abort command failed, cc %d\n", xhci->name, cc);
- }
-
- /* Reset the command ring control register */
- memset(xhci->cmds->ring, 0U, XHCI_RING_ITEMS * sizeof(union xhci_trb));
- xhci_writeq ( xhci, ( (uint64_t)(uintptr_t)xhci->cmds | xhci->cmds->cs ), xhci->op + XHCI_OP_CRCR );
-}
-
-/**
- * Submit a command to the xhci controller ring
- *
- * @v xhci XHCI Device
- * @v ep Owner Endpoint of current TRB ring
- * @ trb Command TRB to be sent
- */
-static int xhci_cmd_submit(struct xhci_host *xhci, struct xhci_endpoint *ep, union xhci_trb *trb) {
-
- int rc = 0;
- usb_osal_mutex_take(xhci->cmds->lock); /* handle command one by one */
-
- ep->timeout = 5000;
- ep->waiter = true;
- xhci->cur_cmd_pipe = ep;
-
- xhci_trb_queue(xhci->cmds, trb);
-
- /* pass command trb to hardware */
- DSB();
-
- xhci_doorbell(xhci, 0, 0); /* 0 = db host controller, 0 = db targe hc command */
- int cc = xhci_event_wait(xhci, ep, xhci->cmds);
- if (XHCI_CMPLT_SUCCESS != cc) {
- USB_LOG_ERR("XHCI %s cmd failed, cc %d\n", xhci->name, cc);
- xhci_abort(xhci); /* Abort command */
- rc = -ENOTSUP;
- }
-
- usb_osal_mutex_give(xhci->cmds->lock);
- xhci->cur_cmd_pipe = NULL;
- return rc;
-}
-
-/**
- * Issue NOP and wait for completion
- *
- * @v xhci xHCI device
- * @v ep Command Endpoint
- * @ret rc Return status code
- */
-static int xhci_nop ( struct xhci_host *xhci, struct xhci_endpoint *ep ) {
- union xhci_trb trb;
- struct xhci_trb_common *nop = &trb.common;
- int rc;
-
- /* Construct command */
- memset ( nop, 0, sizeof ( *nop ) );
- nop->flags = XHCI_TRB_IOC;
- nop->type = XHCI_TRB_NOP_CMD;
-
- /* Issue command and wait for completion */
- if ( ( rc = xhci_cmd_submit(xhci, ep, &trb ) ) != 0 )
- return rc;
-
- return 0;
-}
-
-/**
- * Issue Enable slot and wait for completion
- *
- * @v xhci xHCI device
- * @v ep Command Endpoint
- * @v type Type of Slot to be enabled
- * @ret rc Return status code
- */
-static int xhci_enable_slot(struct xhci_host *xhci, struct xhci_endpoint *ep, unsigned int type) {
- union xhci_trb trb;
- struct xhci_trb_enable_slot *enable = &trb.enable;
- struct xhci_trb_complete *enabled;
- unsigned int slot;
- int rc;
-
- /* Construct command */
- memset ( enable, 0, sizeof ( *enable ) );
- enable->slot = type;
- enable->type = XHCI_TRB_ENABLE_SLOT;
-
- /* Issue command and Wait for completion */
- if ( ( rc = xhci_cmd_submit(xhci, ep, &trb) ) != 0 ) {
- USB_LOG_ERR("XHCI %s could not enable new slot, type %d\n",
- xhci->name, type );
- return rc;
- }
-
- /* Extract slot number */
- enabled = &(xhci->cmds->evt.complete);
- slot = enabled->slot;
-
- USB_LOG_DBG("XHCI %s slot %d enabled\n", xhci->name, slot );
- return slot;
-}
-
-/**
- * Disable slot
- *
- * @v xhci xHCI device
- * @v ep Command Endpoint
- * @v slot Device slot
- * @ret rc Return status code
- */
-static int xhci_disable_slot ( struct xhci_host *xhci, struct xhci_endpoint *ep,
- unsigned int slot ) {
- union xhci_trb trb;
- struct xhci_trb_disable_slot *disable = &trb.disable;
- int rc;
-
- /* Construct command */
- memset ( disable, 0, sizeof ( *disable ) );
- disable->type = XHCI_TRB_DISABLE_SLOT;
- disable->slot = slot;
-
- /* Issue command and wait for completion */
- if ( ( rc = xhci_cmd_submit ( xhci, ep, &trb ) ) != 0 ) {
- USB_LOG_DBG("XHCI %s could not disable slot %d: %s\n",
- xhci->name, slot, strerror ( rc ) );
- return rc;
- }
-
- USB_LOG_DBG("XHCI %s slot %d disabled\n", xhci->name, slot );
- return 0;
-}
-
-/**
- * Issue context-based command and wait for completion
- *
- * @v xhci xHCI device
- * @v slot Device slot
- * @v endpoint Endpoint
- * @v type TRB type
- * @v populate Input context populater
- * @ret rc Return status code
- */
-static int xhci_context ( struct xhci_host *xhci, struct xhci_slot *slot,
- struct xhci_endpoint *ep, unsigned int type,
- void ( * populate ) ( struct xhci_host *xhci,
- struct xhci_slot *slot,
- struct xhci_endpoint *ep,
- void *input ) ) {
- union xhci_trb trb;
- struct xhci_trb_context *context = &trb.context;
- size_t len;
- void *input;
- int rc;
-
- /* Allocate an input context */
- len = xhci_input_context_offset ( xhci, XHCI_CTX_END );
- input = usb_align(xhci_align ( len ), len);
- if ( ! input ) {
- rc = -ENOMEM;
- goto err_alloc;
- }
- memset ( input, 0, len );
-
- /* Populate input context */
- populate ( xhci, slot, ep, input );
-
- /* Construct command */
- memset ( context, 0, sizeof ( *context ) );
- context->type = type;
- context->input = CPU_TO_LE64 ( ( input ) );
- context->slot = slot->id;
-
- /* Issue command and wait for completion */
- if ( ( rc = xhci_cmd_submit ( xhci, ep, &trb ) ) != 0 ) {
- xhci_dump_input_ctx(xhci, ep, input);
- goto err_command;
- }
-
- err_command:
- usb_free ( input );
- err_alloc:
- return rc;
-}
-
-/**
- * Populate address device input context
- *
- * @v xhci xHCI device
- * @v slot Device slot
- * @v endpoint Endpoint
- * @v input Input context
- */
-static void xhci_address_device_input ( struct xhci_host *xhci,
- struct xhci_slot *slot,
- struct xhci_endpoint *endpoint,
- void *input ) {
- struct xhci_control_context *control_ctx;
- struct xhci_slot_context *slot_ctx;
- struct xhci_endpoint_context *ep_ctx;
-
- /* Sanity checks */
- USB_ASSERT ( endpoint->ctx == XHCI_CTX_EP0 );
-
- /* Populate control context, add slot context and ep context */
- control_ctx = input;
- control_ctx->add = CPU_TO_LE32 ( ( 1 << XHCI_CTX_SLOT ) |
- ( 1 << XHCI_CTX_EP0 ) );
-
- /* Populate slot context */
- slot_ctx = ( input + xhci_input_context_offset ( xhci, XHCI_CTX_SLOT ));
- slot_ctx->info = CPU_TO_LE32 ( XHCI_SLOT_INFO ( 1, 0, slot->psiv,
- slot->route ) );
- slot_ctx->port = slot->port;
- slot_ctx->tt_id = slot->tt_id;
- slot_ctx->tt_port = slot->tt_port;
-
- /* Populate control endpoint context */
- ep_ctx = ( input + xhci_input_context_offset ( xhci, XHCI_CTX_EP0 ) );
- ep_ctx->type = XHCI_EP_TYPE_CONTROL; /* bit[5:3] endpoint type */
- ep_ctx->burst = endpoint->burst; /* bit[16:8] max burst size */
- ep_ctx->mtu = CPU_TO_LE16 ( endpoint->mtu ); /* bit[31:16] max packet size */
-
- /*
- bit[63:4] tr dequeue pointer
- bit[0] dequeue cycle state
- */
- ep_ctx->dequeue = CPU_TO_LE64 ( (uint64_t)( &endpoint->reqs.ring[0] ) | XHCI_EP_DCS );
- ep_ctx->trb_len = CPU_TO_LE16 ( XHCI_EP0_TRB_LEN ); /* bit[15:0] average trb length */
-}
-
-/**
- * Address device
- *
- * @v xhci xHCI device
- * @v endpoint Endpoint
- * @v slot Device slot
- * @ret rc Return status code
- */
-static inline int xhci_address_device ( struct xhci_host *xhci,
- struct xhci_endpoint *ep,
- struct xhci_slot *slot ) {
- struct xhci_slot_context *slot_ctx;
- int rc;
-
- /* Assign device address */
- if ( ( rc = xhci_context ( xhci, slot, slot->endpoint[XHCI_CTX_EP0],
- XHCI_TRB_ADDRESS_DEVICE,
- xhci_address_device_input ) ) != 0 )
-
- USB_LOG_DBG("XHCI %s slot ctx 0x%x\n", xhci->name, slot->context);
-
- /* Get assigned address for check */
- slot_ctx = ( slot->context +
- xhci_device_context_offset ( xhci, XHCI_CTX_SLOT ) );
- USB_LOG_DBG("XHCI %s slot ctx 0x%x assigned address 0x%x\n",
- xhci->name, slot_ctx, slot_ctx->address );
-
- return rc;
-}
-
-/**
- * Reset endpoint
- *
- * @v xhci xHCI device
- * @v slot Device slot
- * @v endpoint Endpoint
- * @ret rc Return status code
- */
-int xhci_reset_endpoint ( struct xhci_host *xhci,
- struct xhci_slot *slot,
- struct xhci_endpoint *endpoint ) {
- union xhci_trb trb;
- struct xhci_trb_reset_endpoint *reset = &trb.reset;
- int rc;
-
- /* Construct command */
- memset ( reset, 0, sizeof ( *reset ) );
- reset->slot = slot->id;
- reset->endpoint = endpoint->ctx;
- reset->type = XHCI_TRB_RESET_ENDPOINT;
-
- /* Issue command and wait for completion */
- if ( ( rc = xhci_cmd_submit ( xhci, endpoint, &trb ) ) != 0 ) {
- USB_LOG_DBG("XHCI %s slot %d ctx %d could not reset endpoint "
- "in state %d: %s\n", xhci->name, slot->id, endpoint->ctx,
- endpoint->context->state, strerror ( rc ) );
- return rc;
- }
-
- return 0;
-}
-
-/**
- * Stop endpoint
- *
- * @v xhci xHCI device
- * @v slot Device slot
- * @v endpoint Endpoint
- * @ret rc Return status code
- */
-static inline int xhci_stop_endpoint ( struct xhci_host *xhci,
- struct xhci_slot *slot,
- struct xhci_endpoint *endpoint ) {
- union xhci_trb trb;
- struct xhci_trb_stop_endpoint *stop = &trb.stop;
- int rc;
-
- /* Construct command */
- memset ( stop, 0, sizeof ( *stop ) );
- stop->slot = slot->id;
- stop->endpoint = endpoint->ctx;
- stop->type = XHCI_TRB_STOP_ENDPOINT;
-
- /* Issue command and wait for completion */
- if ( ( rc = xhci_cmd_submit ( xhci, endpoint, &trb ) ) != 0 ) {
- USB_LOG_DBG("XHCI %s slot %d ctx %d could not stop endpoint "
- "in state %d: %s\n", xhci->name, slot->id, endpoint->ctx,
- endpoint->context->state, strerror ( rc ) );
- return rc;
- }
-
- return 0;
-}
-
-/*********************************************************************/
-
-/**
- * Find port slot type
- *
- * @v xhci xHCI device
- * @v port Port number
- * @ret type Slot type, or negative error
- */
-static int xhci_port_slot_type ( struct xhci_host *xhci, unsigned int port ) {
- unsigned int supported = xhci_supported_protocol ( xhci, port );
- unsigned int type;
- uint32_t slot;
-
- /* Fail if there is no supported protocol */
- if ( ! supported )
- return -ENOTSUP;
-
- /* Get slot type */
- slot = readl ( xhci->cap + supported + XHCI_SUPPORTED_SLOT );
- type = XHCI_SUPPORTED_SLOT_TYPE ( slot );
-
- return type;
-}
-
-/**
- * Open device
- *
- * @v xhci XHCI device
- * @v ep Endpoint
- * @ret slot_id Return device slot id
- * @ret rc Return status code
- */
-int xhci_device_open ( struct xhci_host *xhci, struct xhci_endpoint *ep, int *slot_id ) {
- struct usbh_hubport *hport = ep->hport;
- struct usbh_hubport *tt = usbh_transaction_translator(hport);
- struct xhci_slot *slot;
- struct xhci_slot *tt_slot;
- int type;
- int rc;
- int id;
- size_t len;
-
- /* Determine applicable slot type */
- type = xhci_port_slot_type ( xhci, hport->port );
- if ( type < 0 ) {
- rc = type;
- USB_LOG_ERR("XHCI %s-%d has no slot type\n",
- xhci->name, hport->port );
- goto err_type;
- }
-
- /* Allocate a device slot number */
- id = xhci_enable_slot ( xhci, ep, type );
- if ( id < 0 ) {
- rc = id;
- goto err_enable_slot;
- }
-
- USB_ASSERT ( ( id > 0 ) && ( ( unsigned int ) id <= xhci->slots ) );
- USB_ASSERT ( xhci->slot[id] == NULL );
-
- /* Allocate and initialise structure */
- slot = usb_malloc ( sizeof ( *slot ) );
- if ( ! slot ) {
- rc = -ENOMEM;
- goto err_alloc;
- }
- slot->id = id;
- xhci->slot[id] = slot;
- slot->xhci = xhci;
- if ( tt ) {
- tt_slot = xhci->slot[tt->dev_addr];
- slot->tt_id = tt_slot->id;
- slot->tt_port = tt->port;
- }
-
- /* Allocate a device context */
- len = xhci_device_context_offset ( xhci, XHCI_CTX_END );
- slot->context = usb_align(xhci_align ( len ), len);
- if ( ! slot->context ) {
- rc = -ENOMEM;
- goto err_alloc_context;
- }
- memset ( slot->context, 0, len );
-
- /* Set device context base address */
- USB_ASSERT ( xhci->dcbaa.context[id] == 0 );
- xhci->dcbaa.context[id] = CPU_TO_LE64 ( ( slot->context ) );
-
- USB_LOG_DBG("XHCI %s slot %d device context [%08lx,%08lx)\n",
- xhci->name, slot->id, ( slot->context ),
- ( ( slot->context ) + len ) );
- *slot_id = id;
- return 0;
-
- xhci->dcbaa.context[id] = 0;
- usb_free ( slot->context );
-
-err_alloc_context:
- xhci->slot[id] = NULL;
- usb_free ( slot );
-err_alloc:
- xhci_disable_slot ( xhci, ep, id );
-err_enable_slot:
-err_type:
- return rc;
-}
-
-/*********************************************************************/
-
-/**
- * Assign device address
- *
- * @v xhci XHCI device
- * @v slot Slot
- * @v ep Endpoint
- * @ret rc Return status code
- */
-int xhci_device_address ( struct xhci_host *xhci, struct xhci_slot *slot, struct xhci_endpoint *ep ) {
- USB_ASSERT((slot->xhci) && (ep->hport));
- struct usbh_hubport *hport = ep->hport;
- int psiv;
- int rc;
-
- /* Calculate route string */
- slot->route = usbh_route_string (hport);
-
- /* Calculate root hub port number */
- struct usbh_hubport *root_port = usbh_root_hub_port (hport);
- slot->port = root_port->port;
-
- /* Calculate protocol speed ID */
- psiv = xhci_port_psiv ( xhci, slot->port, hport->speed );
- if ( psiv < 0 ) {
- rc = psiv;
- return rc;
- }
- slot->psiv = psiv;
-
- /* Address device */
- if ( ( rc = xhci_address_device ( xhci, ep, slot ) ) != 0 )
- return rc;
-
- return 0;
-}
-
-
-/**
- * Close device
- *
- * @v slot Slot
- */
-void xhci_device_close ( struct xhci_slot *slot ) {
- struct xhci_host *xhci = slot->xhci;
- size_t len = xhci_device_context_offset ( xhci, XHCI_CTX_END );
- unsigned int id = slot->id;
- int rc;
-
- /* Disable slot */
- if ( ( rc = xhci_disable_slot ( xhci, slot->endpoint[0], id ) ) != 0 ) {
- /* Slot is still enabled. Leak the slot context,
- * since the controller may still write to this
- * memory, and leave the DCBAA entry intact.
- *
- * If the controller later reports that this same slot
- * has been re-enabled, then some assertions will be
- * triggered.
- */
- USB_LOG_DBG("XHCI %s slot %d leaking context memory\n",
- xhci->name, slot->id );
- slot->context = NULL;
- }
-
- /* Free slot */
- if ( slot->context ) {
- usb_free ( slot->context );
- xhci->dcbaa.context[id] = 0;
- }
- xhci->slot[id] = NULL;
- usb_free ( slot );
-}
-
-
-/**
- * Populate configure endpoint input context
- *
- * @v xhci xHCI device
- * @v slot Device slot
- * @v endpoint Endpoint
- * @v input Input context
- */
-static void xhci_configure_endpoint_input ( struct xhci_host *xhci,
- struct xhci_slot *slot,
- struct xhci_endpoint *endpoint,
- void *input ) {
- struct xhci_control_context *control_ctx;
- struct xhci_slot_context *slot_ctx;
- struct xhci_endpoint_context *ep_ctx;
-
- xhci_dump_endpoint(endpoint);
-
- /* Populate control context */
- control_ctx = input;
- control_ctx->add = CPU_TO_LE32 (( 1 << XHCI_CTX_SLOT ) | ( 1 << endpoint->ctx ) );
- control_ctx->drop = CPU_TO_LE32 (( 1 << XHCI_CTX_SLOT ) | ( 1 << endpoint->ctx ) );
-
- /* Populate slot context */
- slot_ctx = ( input + xhci_input_context_offset ( xhci, XHCI_CTX_SLOT ));
- slot_ctx->info = CPU_TO_LE32 ( XHCI_SLOT_INFO ( ( XHCI_CTX_END - 1 ),
- ( slot->ports ? 1 : 0 ),
- slot->psiv, 0 ) );
- slot_ctx->ports = slot->ports;
-
- /* Populate endpoint context */
- ep_ctx = ( input + xhci_input_context_offset ( xhci, endpoint->ctx ) );
- ep_ctx->interval = endpoint->interval; /* bit[23:16] for interrupt ep, set interval to control interrupt period */
- /*
- Value Endpoint Type Direction
- 0 Not Valid N/A
- 1 Isoch Out
- 2 Bulk Out
- 3 Interrupt Out
- 4 Control Bidirectional
- 5 Isoch In
- 6 Bulk In
- 7 Interrupt In
- */
- ep_ctx->type = endpoint->ctx_type;
- ep_ctx->burst = endpoint->burst;
- 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 );
-
- /* TODO: endpoint attached on hub may need different setting here */
- if (endpoint->ep_type == USB_ENDPOINT_TYPE_BULK) {
- ep_ctx->trb_len = CPU_TO_LE16 ( 256U ); /* bit[15:0] average trb length */
- } else if (endpoint->ep_type == USB_ENDPOINT_TYPE_INTERRUPT) {
- ep_ctx->trb_len = CPU_TO_LE16 (16U);
- ep_ctx->esit_low = CPU_TO_LE16 ( endpoint->mtu ); /* bit[31:16] max ESIT payload */
- }
-
- xhci_dump_input_ctx(xhci, endpoint, input);
-}
-
-/**
- * Configure endpoint
- *
- * @v xhci xHCI device
- * @v slot Device slot
- * @v endpoint Endpoint
- * @ret rc Return status code
- */
-static inline int xhci_configure_endpoint ( struct xhci_host *xhci,
- struct xhci_slot *slot,
- struct xhci_endpoint *endpoint ){
- int rc;
-
- /* Configure endpoint */
- if ( ( rc = xhci_context ( xhci, slot, endpoint,
- XHCI_TRB_CONFIGURE_ENDPOINT,
- xhci_configure_endpoint_input ) ) != 0 ){
- USB_LOG_ERR("XHCI %s slot %d ctx %d configure failed, error %d !!!\n",
- xhci->name, slot->id, endpoint->ctx, rc );
- return rc;
- }
-
- /* Sanity check */
- if ( ( endpoint->context->state & XHCI_ENDPOINT_STATE_MASK )
- != XHCI_ENDPOINT_RUNNING ){
- xhci_dump_slot_ctx(endpoint->slot->context);
- xhci_dump_ep_ctx(endpoint->context);
- USB_LOG_ERR("XHCI %s slot %d ctx %d configure failed !!!\n",
- xhci->name, slot->id, endpoint->ctx );
- return -1;
- }
-
- USB_LOG_DBG("XHCI %s slot %d ctx %d configured\n",
- xhci->name, slot->id, endpoint->ctx );
- return 0;
-}
-
-/**
- * Populate deconfigure endpoint input context
- *
- * @v xhci xHCI device
- * @v slot Device slot
- * @v endpoint Endpoint
- * @v input Input context
- */
-static void
-xhci_deconfigure_endpoint_input ( struct xhci_host *xhci,
- struct xhci_slot *slot,
- struct xhci_endpoint *endpoint,
- void *input ) {
- struct xhci_control_context *control_ctx;
- struct xhci_slot_context *slot_ctx;
-
- /* Populate control context */
- control_ctx = input;
- control_ctx->add = CPU_TO_LE32 ( 1 << XHCI_CTX_SLOT );
- control_ctx->drop = CPU_TO_LE32 ( 1 << endpoint->ctx );
-
- /* Populate slot context */
- slot_ctx = ( input + xhci_input_context_offset ( xhci, XHCI_CTX_SLOT ));
- slot_ctx->info = CPU_TO_LE32 ( XHCI_SLOT_INFO ( ( XHCI_CTX_END - 1 ),
- 0, 0, 0 ) );
-}
-
-/**
- * Deconfigure endpoint
- *
- * @v xhci xHCI device
- * @v slot Device slot
- * @v endpoint Endpoint
- * @ret rc Return status code
- */
-static inline int xhci_deconfigure_endpoint ( struct xhci_host *xhci,
- struct xhci_slot *slot,
- struct xhci_endpoint *endpoint ) {
- int rc;
-
- /* Deconfigure endpoint */
- if ( ( rc = xhci_context ( xhci, slot, endpoint,
- XHCI_TRB_CONFIGURE_ENDPOINT,
- xhci_deconfigure_endpoint_input ) ) != 0 )
- return rc;
-
- USB_LOG_DBG("XHCI %s slot %d ctx %d deconfigured\n",
- xhci->name, slot->id, endpoint->ctx );
- return 0;
-}
-
-/*********************************************************************/
-
-/**
- * Open control endpoint
- *
- * @v xhci XHCI device
- * @v slot Slot
- * @v ep Endpoint
- * @ret rc Return status code
- */
-int xhci_ctrl_endpoint_open ( struct xhci_host *xhci, struct xhci_slot *slot, struct xhci_endpoint *ep ) {
- unsigned int ctx;
-
- /* Calculate context index */
- ctx = XHCI_CTX ( ep->address );
- USB_ASSERT ( slot->endpoint[ctx] == NULL );
-
- if (USB_ENDPOINT_TYPE_CONTROL != ep->ep_type) {
- return -EINVAL;
- }
-
- /* initialise structure */
- slot->endpoint[ctx] = ep;
- ep->xhci = xhci;
- ep->slot = slot;
- ep->ctx = ctx;
- ep->ctx_type = XHCI_EP_TYPE_CONTROL;
- ep->context = ( ( ( void * ) slot->context ) +
- xhci_device_context_offset ( xhci, ctx ) );
- 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",
- xhci->name, slot->id, ep->address, ep->ep_type,
- (ep->ctx_type >> 3) );
-
- USB_LOG_DBG("XHCI %s slot %d ctx %d ring [%08lx,%08lx)\n",
- xhci->name, slot->id, ctx, ( ep->reqs.ring ),
- ( ( ep->reqs.ring ) + sizeof(ep->reqs.ring) ) );
-
- return 0;
-}
-
-/*********************************************************************/
-
-/**
- * Open work endpoint
- *
- * @v xhci XHCI device
- * @v slot Slot
- * @v ep USB endpoint
- * @ret rc Return status code
- */
-int xhci_work_endpoint_open ( struct xhci_host *xhci, struct xhci_slot *slot, struct xhci_endpoint *ep ) {
- unsigned int ctx;
- unsigned int interval;
- unsigned int ctx_type;
- int rc;
-
- /* Calculate context index */
- ctx = XHCI_CTX ( ep->address );
- USB_ASSERT ( slot->endpoint[ctx] == NULL );
-
- if (USB_ENDPOINT_TYPE_CONTROL == ep->ep_type) {
- return -EINVAL;
- }
-
- /* Calculate endpoint type */
- /*
- Value Endpoint Type Direction, bit[5:3]
- 0 Not Valid N/A
- 1 Isoch Out
- 2 Bulk Out
- 3 Interrupt Out
- 4 Control Bidirectional
- 5 Isoch In
- 6 Bulk In
- 7 Interrupt In
- */
- ctx_type = XHCI_EP_TYPE ( ep->ep_type );
- if ( ep->address & USB_EP_DIR_IN )
- ctx_type |= XHCI_EP_TYPE_IN;
-
- /* initialise structure */
- slot->endpoint[ctx] = ep;
- ep->xhci = xhci;
- ep->slot = slot;
- ep->ctx = ctx;
-
- /* Calculate interval */
- if ( ctx_type & XHCI_EP_TYPE_PERIODIC ) {
- ep->interval = ( xhci_fls ( ep->interval ) - 1 );
- }
-
- ep->ctx_type = ctx_type;
- ep->context = ( ( ( void * ) slot->context ) +
- xhci_device_context_offset ( xhci, ctx ) );
- 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",
- xhci->name, slot->id, ep->address, ep->ep_type,
- (ep->ctx_type >> 3) );
-
- /* Configure endpoint */
- if (( rc = xhci_configure_endpoint ( xhci, slot, ep ) ) != 0) {
- goto err_configure_endpoint;
- }
-
- USB_LOG_DBG("XHCI %s slot %d ctx %d ring [%08lx,%08lx)\n",
- xhci->name, slot->id, ctx, ( ep->reqs.ring ),
- ( ( ep->reqs.ring ) + sizeof(ep->reqs.ring) ) );
-
- return 0;
- err_configure_endpoint:
- (void)xhci_deconfigure_endpoint ( xhci, slot, ep );
- slot->endpoint[ctx] = NULL;
- return rc;
-}
-
-/**
- * Close endpoint
- *
- * @v ep USB endpoint
- */
-void xhci_endpoint_close ( struct xhci_endpoint *ep ) {
- struct xhci_slot *slot = ep->slot;
- struct xhci_host *xhci = slot->xhci;
- unsigned int ctx = ep->ctx;
-
- /* Deconfigure endpoint, if applicable */
- if ( ctx != XHCI_CTX_EP0 )
- (void)xhci_deconfigure_endpoint ( xhci, slot, ep );
-
- slot->endpoint[ctx] = NULL;
- usb_free(ep);
-}
-
-/*********************************************************************/
-
-/**
- * Enqueue message transfer
- *
- * @v ep USB endpoint
- * @v packet Setup packet buffer
- * @v data_buff Data buffer
- * @v datalen Data length
- * @ret rc Return status code
- */
-void xhci_endpoint_message ( struct xhci_endpoint *ep,
- struct usb_setup_packet *packet,
- void *data_buff,
- int datalen ) {
- struct xhci_host *xhci = ep->xhci;
- struct xhci_slot *slot = ep->slot;
- union xhci_trb trb;
- struct xhci_trb_setup *setup;
- struct xhci_trb_data *data;
- struct xhci_trb_status *status;
- unsigned int input;
-
- /* Construct setup stage TRB */
- setup = &(trb.setup);
- memset ( setup, 0, sizeof ( *setup ) );
-
- memcpy ( &setup->packet, packet, sizeof ( setup->packet ) );
- setup->len = CPU_TO_LE32 ( sizeof ( *packet ) ); /* bit[16:0] trb transfer length, always 8 */
- setup->flags = XHCI_TRB_IDT; /* bit[6] Immediate Data (IDT), parameters take effect */
- setup->type = XHCI_TRB_SETUP; /* bit[15:10] trb type */
- input = ( packet->bmRequestType & CPU_TO_LE16 ( USB_REQUEST_DIR_IN ) );
- if (datalen > 0) {
- /* bit[17:16] Transfer type, 2 = OUT Data, 3 = IN Data */
- setup->direction = ( input ? XHCI_SETUP_IN : XHCI_SETUP_OUT );
- }
-
- xhci_trb_queue(&(ep->reqs), &trb);
-
- /* Construct data stage TRB, if applicable */
- if (datalen > 0) {
- data = &(trb.data);
- memset ( data, 0, sizeof ( *data ) );
-
- data->data = CPU_TO_LE64 ( data_buff );
- data->len = CPU_TO_LE32 ( datalen );
- data->type = XHCI_TRB_DATA; /* bit[15:10] trb type */
- data->direction = ( input ? XHCI_DATA_IN : XHCI_DATA_OUT ); /* bit[16] Direction, 0 = OUT, 1 = IN */
-
- xhci_trb_queue(&(ep->reqs), &trb);
- }
-
- status = &(trb.status);
- memset ( status, 0, sizeof ( *status ) );
- status->flags = XHCI_TRB_IOC;
- status->type = XHCI_TRB_STATUS;
- status->direction =
- ( ( datalen && input ) ? XHCI_STATUS_OUT : XHCI_STATUS_IN );
-
- xhci_trb_queue(&(ep->reqs), &trb);
-
- /* pass command trb to hardware */
- DSB();
-
- USB_LOG_DBG("ring doorbell slot-%d ep-%d \r\n", slot->id, ep->ctx);
- xhci_doorbell(xhci, slot->id, ep->ctx); /* 0 = db host controller, 0 = db targe hc command */
-
- return;
-}
-
-/*********************************************************************/
-
-/**
- * Enqueue stream transfer
- *
- * @v ep USB endpoint
- * @v data_buff Data buffer
- * @v datalen Data length
- * @ret rc Return status code
- */
-void xhci_endpoint_stream ( struct xhci_endpoint *ep,
- void *data_buff,
- int datalen ) {
- struct xhci_host *xhci = ep->xhci;
- struct xhci_slot *slot = ep->slot;
- union xhci_trb trbs;
- union xhci_trb *trb = &trbs;
- struct xhci_trb_normal *normal;
- int trb_len;
-
- /* Calculate TRB length */
- trb_len = XHCI_MTU;
- if ( trb_len > datalen ) {
- trb_len = datalen;
- } else {
- USB_LOG_ERR("transfer length %d exceed MTU %d \r\n", datalen, trb_len);
- goto err_enqueue;
- }
-
- /* Construct normal TRBs */
- normal = &trb->normal;
- memset ( normal, 0, sizeof ( *normal ) );
- normal->data = CPU_TO_LE64 ( (uintptr_t)data_buff );
- normal->len = CPU_TO_LE32 ( trb_len );
- normal->type = XHCI_TRB_NORMAL;
- normal->flags = XHCI_TRB_IOC;
-
- xhci_trb_queue(&(ep->reqs), trb);
-
- /* pass command trb to hardware */
- DSB();
-
- xhci_doorbell(xhci, slot->id, ep->ctx);
-
-err_enqueue:
- return;
-}
-
-/*********************************************************************/
-
-/**
- * Populate evaluate context input context
- *
- * @v xhci xHCI device
- * @v slot Device slot
- * @v endpoint Endpoint
- * @v input Input context
- */
-static void xhci_evaluate_context_input ( struct xhci_host *xhci,
- struct xhci_slot *slot,
- struct xhci_endpoint *endpoint,
- void *input ) {
- struct xhci_control_context *control_ctx;
- struct xhci_slot_context *slot_ctx;
- struct xhci_endpoint_context *ep_ctx;
-
- /* Populate control context */
- control_ctx = input;
- control_ctx->add = CPU_TO_LE32 ( ( 1 << XHCI_CTX_SLOT ) /*|
- ( 1 << endpoint->ctx )*/ );
- control_ctx->drop = CPU_TO_LE32 ( ( 1 << XHCI_CTX_SLOT ) /* |
- ( 1 << endpoint->ctx )*/ );
-
- /* Populate slot context */
- slot_ctx = ( input + xhci_input_context_offset ( xhci, XHCI_CTX_SLOT ));
- slot_ctx->info = CPU_TO_LE32 ( XHCI_SLOT_INFO ( ( XHCI_CTX_END - 1 ),
- 0, 0, 0 ) );
-
- /* Populate endpoint context */
- ep_ctx = ( input + xhci_input_context_offset ( xhci, endpoint->ctx ) );
- ep_ctx->mtu = CPU_TO_LE16 ( endpoint->mtu );
-}
-
-/**
- * Evaluate context
- *
- * @v xhci xHCI device
- * @v slot Device slot
- * @v endpoint Endpoint
- * @ret rc Return status code
- */
-static inline int xhci_evaluate_context ( struct xhci_host *xhci,
- struct xhci_slot *slot,
- struct xhci_endpoint *endpoint ) {
- int rc;
-
- /* Configure endpoint */
- if ( ( rc = xhci_context ( xhci, slot, endpoint,
- XHCI_TRB_EVALUATE_CONTEXT,
- xhci_evaluate_context_input ) ) != 0 )
- return rc;
-
- USB_LOG_DBG("XHCI %s slot %d ctx %d (re-)evaluated\n",
- xhci->name, slot->id, endpoint->ctx );
- return 0;
-}
-
-/**
- * Update MTU
- *
- * @v ep USB endpoint
- * @ret rc Return status code
- */
-int xhci_endpoint_mtu ( struct xhci_endpoint *ep ) {
- struct xhci_endpoint *endpoint = ( ep );
- struct xhci_slot *slot = endpoint->slot;
- struct xhci_host *xhci = slot->xhci;
- int rc;
-
- /* Evalulate context */
- if ( ( rc = xhci_evaluate_context ( xhci, slot, endpoint ) ) != 0 )
- return rc;
-
- return 0;
-}
-
-/*********************************************************************/
-
-/**
- * Handle port status event
- *
- * @v xhci xHCI device
- * @v trb Port status event
- */
-static void xhci_port_status ( struct xhci_host *xhci,
- struct xhci_trb_port_status *trb ) {
- uint32_t portsc;
-
- /* Sanity check */
- USB_ASSERT ( ( trb->port > 0 ) && ( trb->port <= xhci->ports ) );
-
- /* Record disconnections, changes flag will be cleared later */
- portsc = readl ( xhci->op + XHCI_OP_PORTSC ( trb->port ) );
- xhci_dump_port_status(trb->port, portsc);
-
- if (portsc & XHCI_PORTSC_CSC) {
- /* Report port status change */
- usbh_roothub_thread_wakeup ( trb->port );
- }
-}
-
-/**
- * Handle transfer event
- *
- * @v xhci xHCI device
- * @v trb Transfer event TRB
- */
-static void xhci_transfer ( struct xhci_host *xhci,
- struct xhci_trb_transfer *trb ) {
- struct xhci_slot *slot;
- struct xhci_endpoint *endpoint;
- 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 */
- 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 */
- int rc;
-
- /* Identify slot */
- if ( ( trb->slot > xhci->slots ) ||
- ( ( slot = xhci->slot[trb->slot] ) == NULL ) ) {
- USB_LOG_DBG("XHCI %s transfer event invalid slot %d:\n",
- xhci->name, trb->slot );
- return;
- }
-
- /* Identify endpoint */
- if ( ( trb->endpoint >= XHCI_CTX_END ) ||
- ( ( endpoint = slot->endpoint[trb->endpoint] ) == NULL ) ) {
- USB_LOG_DBG("XHCI %s slot %d transfer event invalid epid "
- "%d:\n", xhci->name, slot->id, trb->endpoint );
- return;
- }
-
- /* Record completion */
- memcpy(pending, trb, sizeof(*trb)); /* copy current trb to cmd/transfer ring */
- trans_ring->eidx = eidx;
-
- /* Check for errors */
- if ( ! ( ( trb->code == XHCI_CMPLT_SUCCESS ) ||
- ( trb->code == XHCI_CMPLT_SHORT ) ) ) {
- USB_LOG_ERR("XHCI %s slot %d ctx %d failed (code %d)\n",
- xhci->name, slot->id, endpoint->ctx, trb->code);
-
- /* Sanity check */
- USB_ASSERT ( ( endpoint->context->state & XHCI_ENDPOINT_STATE_MASK )
- != XHCI_ENDPOINT_RUNNING );
-
- xhci_dump_ep_ctx(endpoint->context);
- return;
- }
-
- if (endpoint->waiter) {
- endpoint->waiter = false;
- usb_osal_sem_give(endpoint->waitsem);
- }
-
- if (endpoint->urb) {
- struct usbh_urb *cur_urb = endpoint->urb;
- cur_urb->errorcode = trb->code;
- /* bit [23:0] TRB Transfer length, residual number of bytes not transferred
- for OUT, is the value of (len of trb) - (data bytes transmitted), '0' means successful
- for IN, is the value of (len of trb) - (data bytes received),
- if cc is Short Packet, value is the diff between expected trans size and actual recv bytes
- if cc is other error, value is the diff between expected trans size and actual recv bytes */
- cur_urb->actual_length += cur_urb->transfer_buffer_length - trb->residual; /* bit [23:0] */
-
- if (cur_urb->complete) {
- if (cur_urb->errorcode < 0) {
- cur_urb->complete(cur_urb->arg, cur_urb->errorcode);
- } else {
- cur_urb->complete(cur_urb->arg, cur_urb->actual_length);
- }
- }
- }
-
- return;
-}
-
-/**
- * Handle command completion event
- *
- * @v xhci xHCI device
- * @v trb Command completion event
- */
-static void xhci_complete ( struct xhci_host *xhci,
- struct xhci_trb_complete *trb ) {
- int rc;
- union xhci_trb *cmd_trb = (void *)(uintptr_t)(trb->command);
- struct xhci_ring *cmd_ring = XHCI_RING(cmd_trb); /* to align addr is ring base */
- union xhci_trb *pending = &cmd_ring->evt; /* preserve event trb pending to handle */
- uint32_t eidx = cmd_trb - cmd_ring->ring + 1; /* calculate current evt trb index */
- struct xhci_endpoint *work_pipe = xhci->cur_cmd_pipe;
-
- /* Ignore "command ring stopped" notifications */
- if ( trb->code == XHCI_CMPLT_CMD_STOPPED ) {
- USB_LOG_DBG("XHCI %s command ring stopped\n", xhci->name );
- return;
- }
-
- /* Record completion */
- USB_LOG_DBG("command-0x%x completed !!! \r\n", pending);
- memcpy(pending, trb, sizeof(*trb)); /* copy current trb to cmd/transfer ring */
- cmd_ring->eidx = eidx;
-
- USB_ASSERT(work_pipe);
- if (work_pipe->waiter)
- {
- work_pipe->waiter = false;
- usb_osal_sem_give(work_pipe->waitsem);
- }
-}
-
-/**
- * Handle host controller event
- *
- * @v xhci xHCI device
- * @v trb Host controller event
- */
-static void xhci_host_controller ( struct xhci_host *xhci,
- struct xhci_trb_host_controller *trb ) {
- int rc;
-
- /* Construct error */
- rc = -( trb->code );
- USB_LOG_ERR("XHCI %s host controller event (code %d)\n",
- xhci->name, trb->code );
-}
-
-/**
- * Process event ring in interrupt
- *
- * @v xhci xHCI device
- * @r workpip current work endpoint
- */
-struct xhci_endpoint *xhci_event_process(struct xhci_host *xhci) {
- struct xhci_endpoint *work_pipe = NULL;
- struct xhci_ring *evts = xhci->evts;
- unsigned int evt_type;
- unsigned int evt_cc;
-
- /* check and ack event */
- for (;;) {
- /* Stop if we reach an empty TRB */
- DSB();
-
- uint32_t nidx = evts->nidx; /* index of dequeue trb */
- uint32_t cs = evts->cs; /* cycle state toggle by xHc */
- union xhci_trb *trb = evts->ring + nidx; /* current trb */
- uint32_t control = trb->common.flags; /* trb control field */
-
- if ((control & XHCI_TRB_C) != (cs ? 1 : 0)) { /* if cycle state not toggle, no events need to handle */
- break;
- }
-
- /* Handle TRB */
- evt_type = ( trb->common.type & XHCI_TRB_TYPE_MASK );
- switch ( evt_type ) {
-
- case XHCI_TRB_TRANSFER :
- evt_cc = trb->transfer.code;
- xhci_transfer ( xhci, &trb->transfer );
- break;
-
- case XHCI_TRB_COMPLETE :
- evt_cc = trb->complete.code;
- xhci_complete ( xhci, &trb->complete );
- break;
-
- case XHCI_TRB_PORT_STATUS:
- evt_cc = trb->port.code;
- xhci_port_status ( xhci, &trb->port );
- break;
-
- case XHCI_TRB_HOST_CONTROLLER:
- evt_cc = trb->host.code;
- xhci_host_controller ( xhci, &trb->host );
- break;
-
- default:
- USB_LOG_DBG("XHCI %s unrecognised event type %d, cc %d\n:",
- xhci->name, ( evt_type ) );
- break;
- }
-
- /* move ring index, notify xhci */
- nidx++; /* head to next trb */
- if (nidx == XHCI_RING_ITEMS)
- {
- nidx = 0; /* roll-back if reach end of list */
- cs = cs ? 0 : 1;
- evts->cs = cs; /* sw toggle cycle state */
- }
- evts->nidx = nidx;
-
- /* Update dequeue pointer if applicable */
- uint64_t erdp = (uint64_t)(unsigned long)(evts->ring + nidx);
- xhci_writeq ( xhci, (uintptr_t)( erdp ) | XHCI_RUN_ERDP_EHB,
- xhci->run + XHCI_RUN_ERDP ( 0 ) );
- }
-
- return work_pipe;
-} \ No newline at end of file
diff --git a/port/xhci/xhci.h b/port/xhci/xhci.h
deleted file mode 100644
index eafd5843..00000000
--- a/port/xhci/xhci.h
+++ /dev/null
@@ -1,940 +0,0 @@
-/*
- * Copyright : (C) 2022 Phytium Information Technology, Inc.
- * All Rights Reserved.
- *
- * This program is OPEN SOURCE software: you can redistribute it and/or modify it
- * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd,
- * either version 1.0 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the Phytium Public License for more details.
- *
- *
- * FilePath: xhci.h
- * Date: 2022-07-19 09:26:25
- * LastEditTime: 2022-07-19 09:26:25
- * Description:  This file is for xhci register definition.
- *
- * Modify History:
- * Ver   Who        Date         Changes
- * ----- ------     --------    --------------------------------------
- * 1.0 zhugengyu 2022/9/19 init commit
- * 2.0 zhugengyu 2023/3/29 support usb3.0 device attached at roothub
- */
-#ifndef XHCI_H
-#define XHCI_H
-
-#include "xhci_reg.h"
-
-#include "usbh_core.h"
-
-/** @file
- *
- * USB eXtensible Host Controller Interface (xHCI) driver
- *
- */
-
-#define XHCI_RING_ITEMS 16U
-#define XHCI_ALIGMENT 64U
-#define XHCI_RING_SIZE (XHCI_RING_ITEMS * sizeof(union xhci_trb))
-
-/*
- * xhci_ring structs are allocated with XHCI_RING_SIZE alignment,
- * then we can get it from a trb pointer (provided by evt ring).
- */
-#define XHCI_RING(_trb) \
- ((struct xhci_ring*)((unsigned long)(_trb) & ~(XHCI_RING_SIZE-1)))
-
-/** Device context base address array */
-struct xhci_dcbaa {
- /** Context base addresses */
- uint64_t *context;
-};
-
-/** Scratchpad buffer */
-struct xhci_scratchpad {
- /** Number of page-sized scratchpad buffers */
- unsigned int count;
- /** Scratchpad buffer area */
- uintptr_t buffer;
- /** Scratchpad array */
- uint64_t *array;
-};
-
-/** An input control context */
-struct xhci_control_context {
- /** Drop context flags */
- uint32_t drop;
- /** Add context flags */
- uint32_t add;
- /** Reserved */
- uint32_t reserved_a[5];
- /** Configuration value */
- uint8_t config;
- /** Interface number */
- uint8_t intf;
- /** Alternate setting */
- uint8_t alt;
- /** Reserved */
- uint8_t reserved_b;
-} __attribute__ (( packed ));
-
-/** A slot context */
-struct xhci_slot_context {
- /** Device info 03-00h */
- uint32_t info;
- /** Maximum exit latency */
- uint16_t latency;
- /** Root hub port number */
- uint8_t port;
- /** Number of downstream ports 07-04h */
- uint8_t ports;
- /** TT hub slot ID */
- uint8_t tt_id;
- /** TT port number */
- uint8_t tt_port;
- /** Interrupter target 0b-08h */
- uint16_t intr;
- /** USB address */
- uint8_t address;
- /** Reserved */
- uint16_t reserved_a;
- /** Slot state 0f-0ch */
- uint8_t state;
- /** Reserved */
- uint32_t reserved_b[4];
-} __attribute__ (( packed ));
-
-/** Construct slot context device info */
-#define XHCI_SLOT_INFO( entries, hub, speed, route ) \
- ( ( (entries) << 27 ) | ( (hub) << 26 ) | ( (speed) << 20 ) | (route) )
-
-/** An endpoint context */
-struct xhci_endpoint_context {
- /** Endpoint state 03-00h*/
- uint8_t state;
- /** Stream configuration */
- uint8_t stream;
-#define XHCI_EPCTX_MULT_GET(stream) XHCI32_GET_BITS(stream, 1, 0)
-#define XHCI_EPCTX_STREAM_GET(stream) XHCI32_GET_BITS(stream, 6, 2)
-#define XHCI_EPCTX_LSA BIT(7)
- /** Polling interval */
- uint8_t interval;
- /** Max ESIT payload high */
- uint8_t esit_high;
- /** Endpoint type 04-04h */
- uint8_t type;
-#define XHCI_EPCTX_CERR_GET(type) XHCI32_GET_BITS(type, 2, 1)
-#define XHCI_EPCTX_TYPE_GET(type) XHCI32_GET_BITS(type, 5, 3)
-#define XHCI_EPCTX_HID BIT(7)
- /** Maximum burst size */
- uint8_t burst;
- /** Maximum packet size */
- uint16_t mtu;
- /** Transfer ring dequeue pointer 0f-08h */
- uint64_t dequeue;
-#define XHCI_EPCTX_DCS BIT(0)
- /** Average TRB length 13-10h */
- uint16_t trb_len;
- /** Max ESIT payload low */
- uint16_t esit_low;
- /** Reserved */
- uint32_t reserved[3];
-} __attribute__ (( packed ));
-
-/** Endpoint states */
-enum {
- /** Endpoint is disabled */
- XHCI_ENDPOINT_DISABLED = 0,
- /** Endpoint is running */
- XHCI_ENDPOINT_RUNNING = 1,
- /** Endpoint is halted due to a USB Halt condition */
- XHCI_ENDPOINT_HALTED = 2,
- /** Endpoint is stopped */
- XHCI_ENDPOINT_STOPPED = 3,
- /** Endpoint is halted due to a TRB error */
- XHCI_ENDPOINT_ERROR = 4,
-};
-
-/** Endpoint state mask */
-#define XHCI_ENDPOINT_STATE_MASK 0x07
-
-/** Endpoint type */
-#define XHCI_EP_TYPE(type) ( (type) << 3 )
-
-/** Control endpoint type */
-#define XHCI_EP_TYPE_CONTROL XHCI_EP_TYPE ( 4 )
-
-/** Input endpoint type */
-#define XHCI_EP_TYPE_IN XHCI_EP_TYPE ( 4 )
-
-/** Periodic endpoint type */
-#define XHCI_EP_TYPE_PERIODIC XHCI_EP_TYPE ( 1 )
-
-/** Endpoint dequeue cycle state */
-#define XHCI_EP_DCS 0x00000001UL
-
-/** Control endpoint average TRB length */
-#define XHCI_EP0_TRB_LEN 8
-
-/**
- * Calculate doorbell register value
- *
- * @v target Doorbell target
- * @v stream Doorbell stream ID
- * @ret dbval Doorbell register value
- */
-#define XHCI_DBVAL( target, stream ) ( (target) | ( (stream) << 16 ) )
-
-
-/** Slot context index */
-#define XHCI_CTX_SLOT 0
-
-/** Calculate context index from USB endpoint address */
-/* refer to spec. Figure 4-4: Endpoint Context Addressing
- ep0 = 1, ep1-out = 2, ep1-in = 3, ... ep15-out = 30, ep15-in = 31 */
-#define XHCI_CTX(address) \
- ( (address) ? ( ( ( (address) & 0x0f ) << 1 ) | \
- ( ( (address) & 0x80 ) >> 7 ) ) : 1 )
-
-/** Endpoint zero context index */
-#define XHCI_CTX_EP0 XHCI_CTX ( 0x00 )
-
-/** End of contexts */
-#define XHCI_CTX_END 32
-
-/** Device context index */
-#define XHCI_DCI(ctx) ( (ctx) + 0 )
-
-/** Input context index */
-#define XHCI_ICI(ctx) ( (ctx) + 1 )
-
-/** Number of TRBs (excluding Link TRB) in the command ring
- *
- * This is a policy decision.
- */
-#define XHCI_CMD_TRBS_LOG2 2
-
-/** Number of TRBs in the event ring
- *
- * This is a policy decision.
- */
-#define XHCI_EVENT_TRBS_LOG2 6
-
-/** Number of TRBs in a transfer ring
- *
- * This is a policy decision.
- */
-#define XHCI_TRANSFER_TRBS_LOG2 6
-
-/** Maximum time to wait for BIOS to release ownership
- *
- * This is a policy decision.
- */
-#define XHCI_USBLEGSUP_MAX_WAIT_MS 100
-
-/** Maximum time to wait for host controller to stop
- *
- * This is a policy decision.
- */
-#define XHCI_STOP_MAX_WAIT_MS 100
-
-/** Maximum time to wait for reset to complete
- *
- * This is a policy decision.
- */
-#define XHCI_RESET_MAX_WAIT_MS 500
-
-/** Maximum time to wait for a command to complete
- *
- * The "address device" command involves waiting for a response to a
- * USB control transaction, and so we must wait for up to the 5000ms
- * that USB allows for devices to respond to control transactions.
- */
-#define XHCI_COMMAND_MAX_WAIT_MS 5000
-
-/** Time to delay after aborting a command
- *
- * This is a policy decision
- */
-#define XHCI_COMMAND_ABORT_DELAY_MS 500
-
-/** Maximum time to wait for a port reset to complete
- *
- * This is a policy decision.
- */
-#define XHCI_PORT_RESET_MAX_WAIT_MS 500
-
-/** A transfer request block template */
-struct xhci_trb_template {
- /** Parameter */
- uint64_t parameter;
- /** Status */
- uint32_t status;
- /** Control */
- uint32_t control;
-};
-
-/** A transfer request block */
-struct xhci_trb_common {
- /** Reserved */
- uint64_t reserved_a;
- /** Reserved */
- uint32_t reserved_b;
- /** Flags */
- uint8_t flags;
- /** Type */
- uint8_t type;
- /** Reserved */
- uint16_t reserved_c;
-} __attribute__ (( packed ));
-
-/** Transfer request block cycle bit flag */
-#define XHCI_TRB_C 0x01
-
-/** Transfer request block toggle cycle bit flag */
-#define XHCI_TRB_TC 0x02
-
-/** Transfer request block chain flag */
-#define XHCI_TRB_CH 0x10
-
-/** Transfer request block interrupt on completion flag */
-#define XHCI_TRB_IOC 0x20
-
-/** Transfer request block immediate data flag */
-#define XHCI_TRB_IDT 0x40
-
-/** Transfer request block type */
-#define XHCI_TRB_TYPE(type) ( (type) << 2 )
-
-/** Transfer request block type mask */
-#define XHCI_TRB_TYPE_MASK XHCI_TRB_TYPE ( 0x3f )
-
-/** A normal transfer request block */
-struct xhci_trb_normal {
- /** Data buffer */
- uint64_t data;
- /** Length */
- uint32_t len;
- /** Flags */
- uint8_t flags;
- /** Type */
- uint8_t type;
- /** Reserved */
- uint16_t reserved;
-} __attribute__ (( packed ));
-
-/** A normal transfer request block */
-#define XHCI_TRB_NORMAL XHCI_TRB_TYPE ( 1 )
-
-/** Construct TD size field */
-#define XHCI_TD_SIZE(remaining) \
- ( ( ( (remaining) <= 0xf ) ? remaining : 0xf ) << 17 )
-
-/** A setup stage transfer request block */
-struct xhci_trb_setup {
- /** Setup packet, 04-00h sw will copy request content to this field */
- struct usb_setup_packet packet;
- /** Length 08h */
- uint32_t len;
- /** Flags 0ch */
- uint8_t flags;
- /** Type */
- uint8_t type;
- /** Transfer direction */
- uint8_t direction;
- /** Reserved */
- uint8_t reserved;
-} __attribute__ (( packed ));
-
-/** A setup stage transfer request block */
-#define XHCI_TRB_SETUP XHCI_TRB_TYPE ( 2 )
-
-/** Setup stage input data direction */
-#define XHCI_SETUP_IN 3
-
-/** Setup stage output data direction */
-#define XHCI_SETUP_OUT 2
-
-/** A data stage transfer request block */
-struct xhci_trb_data {
- /** Data buffer */
- uint64_t data;
- /** Length */
- uint32_t len;
- /** Flags */
- uint8_t flags;
- /** Type */
- uint8_t type;
- /** Transfer direction */
- uint8_t direction;
- /** Reserved */
- uint8_t reserved;
-} __attribute__ (( packed ));
-
-/** A data stage transfer request block */
-#define XHCI_TRB_DATA XHCI_TRB_TYPE ( 3 )
-
-/** Input data direction */
-#define XHCI_DATA_IN 0x01
-
-/** Output data direction */
-#define XHCI_DATA_OUT 0x00
-
-/** A status stage transfer request block */
-struct xhci_trb_status {
- /** Reserved */
- uint64_t reserved_a;
- /** Reserved */
- uint32_t reserved_b;
- /** Flags */
- uint8_t flags;
- /** Type */
- uint8_t type;
- /** Direction */
- uint8_t direction;
- /** Reserved */
- uint8_t reserved_c;
-} __attribute__ (( packed ));
-
-/** A status stage transfer request block */
-#define XHCI_TRB_STATUS XHCI_TRB_TYPE ( 4 )
-
-/** Input status direction */
-#define XHCI_STATUS_IN 0x01
-
-/** Output status direction */
-#define XHCI_STATUS_OUT 0x00
-
-/** A link transfer request block */
-struct xhci_trb_link {
- /** Next ring segment */
- uint64_t next;
- /** Reserved */
- uint32_t reserved_a;
- /** Flags */
- uint8_t flags;
- /** Type */
- uint8_t type;
- /** Reserved */
- uint16_t reserved_c;
-} __attribute__ (( packed ));
-
-/** A link transfer request block */
-#define XHCI_TRB_LINK XHCI_TRB_TYPE ( 6 )
-
-/** A no-op transfer request block */
-#define XHCI_TRB_NOP XHCI_TRB_TYPE ( 8 )
-
-/** An enable slot transfer request block */
-struct xhci_trb_enable_slot {
- /** Reserved */
- uint64_t reserved_a;
- /** Reserved */
- uint32_t reserved_b;
- /** Flags */
- uint8_t flags;
- /** Type */
- uint8_t type;
- /** Slot type */
- uint8_t slot;
- /** Reserved */
- uint8_t reserved_c;
-} __attribute__ (( packed ));
-
-/** An enable slot transfer request block */
-#define XHCI_TRB_ENABLE_SLOT XHCI_TRB_TYPE ( 9 )
-
-/** A disable slot transfer request block */
-struct xhci_trb_disable_slot {
- /** Reserved */
- uint64_t reserved_a;
- /** Reserved */
- uint32_t reserved_b;
- /** Flags */
- uint8_t flags;
- /** Type */
- uint8_t type;
- /** Reserved */
- uint8_t reserved_c;
- /** Slot ID */
- uint8_t slot;
-} __attribute__ (( packed ));
-
-/** A disable slot transfer request block */
-#define XHCI_TRB_DISABLE_SLOT XHCI_TRB_TYPE ( 10 )
-
-/** A context transfer request block */
-struct xhci_trb_context {
- /** Input context */
- uint64_t input;
- /** Reserved */
- uint32_t reserved_a;
- /** Flags */
- uint8_t flags;
- /** Type */
- uint8_t type;
- /** Reserved */
- uint8_t reserved_b;
- /** Slot ID */
- uint8_t slot;
-} __attribute__ (( packed ));
-
-/** An address device transfer request block */
-#define XHCI_TRB_ADDRESS_DEVICE XHCI_TRB_TYPE ( 11 )
-
-/** A configure endpoint transfer request block */
-#define XHCI_TRB_CONFIGURE_ENDPOINT XHCI_TRB_TYPE ( 12 )
-
-/** An evaluate context transfer request block */
-#define XHCI_TRB_EVALUATE_CONTEXT XHCI_TRB_TYPE ( 13 )
-
-/** A reset endpoint transfer request block */
-struct xhci_trb_reset_endpoint {
- /** Reserved */
- uint64_t reserved_a;
- /** Reserved */
- uint32_t reserved_b;
- /** Flags */
- uint8_t flags;
- /** Type */
- uint8_t type;
- /** Endpoint ID */
- uint8_t endpoint;
- /** Slot ID */
- uint8_t slot;
-} __attribute__ (( packed ));
-
-/** A reset endpoint transfer request block */
-#define XHCI_TRB_RESET_ENDPOINT XHCI_TRB_TYPE ( 14 )
-
-/** A stop endpoint transfer request block */
-struct xhci_trb_stop_endpoint {
- /** Reserved */
- uint64_t reserved_a;
- /** Reserved */
- uint32_t reserved_b;
- /** Flags */
- uint8_t flags;
- /** Type */
- uint8_t type;
- /** Endpoint ID */
- uint8_t endpoint;
- /** Slot ID */
- uint8_t slot;
-} __attribute__ (( packed ));
-
-/** A stop endpoint transfer request block */
-#define XHCI_TRB_STOP_ENDPOINT XHCI_TRB_TYPE ( 15 )
-
-/** A set transfer ring dequeue pointer transfer request block */
-struct xhci_trb_set_tr_dequeue_pointer {
- /** Dequeue pointer */
- uint64_t dequeue;
- /** Reserved */
- uint32_t reserved;
- /** Flags */
- uint8_t flags;
- /** Type */
- uint8_t type;
- /** Endpoint ID */
- uint8_t endpoint;
- /** Slot ID */
- uint8_t slot;
-} __attribute__ (( packed ));
-
-/** A set transfer ring dequeue pointer transfer request block */
-#define XHCI_TRB_SET_TR_DEQUEUE_POINTER XHCI_TRB_TYPE ( 16 )
-
-/** A no-op command transfer request block */
-#define XHCI_TRB_NOP_CMD XHCI_TRB_TYPE ( 23 )
-
-/** A transfer event transfer request block */
-struct xhci_trb_transfer {
- /** Transfer TRB pointer */
- uint64_t transfer;
- /** Residual transfer length */
- uint16_t residual;
- /** Reserved */
- uint8_t reserved;
- /** Completion code */
- uint8_t code;
- /** Flags */
- uint8_t flags;
- /** Type */
- uint8_t type;
- /** Endpoint ID */
- uint8_t endpoint;
- /** Slot ID */
- uint8_t slot;
-} __attribute__ (( packed ));
-
-/** A transfer event transfer request block */
-#define XHCI_TRB_TRANSFER XHCI_TRB_TYPE ( 32 )
-
-/** A command completion event transfer request block */
-struct xhci_trb_complete {
- /** Command TRB pointer */
- uint64_t command;
- /** Parameter */
- uint8_t parameter[3];
- /** Completion code */
- uint8_t code;
- /** Flags */
- uint8_t flags;
- /** Type */
- uint8_t type;
- /** Virtual function ID */
- uint8_t vf;
- /** Slot ID */
- uint8_t slot;
-} __attribute__ (( packed ));
-
-/** A command completion event transfer request block */
-#define XHCI_TRB_COMPLETE XHCI_TRB_TYPE ( 33 )
-
-/** xHCI completion codes */
-enum xhci_completion_code {
- /** Timeout */
- XHCI_CMPLT_TIMEOUT = -1,
- /** Success */
- XHCI_CMPLT_SUCCESS = 1,
- /** Stall Error */
- XHCI_CMPLT_STALL = 6,
- /** Bandwidth Error */
- XHCI_CMPLT_BANDWIDTH = 8,
- /** Endpoint Not Enabled Error */
- XHCI_CMPLT_ENDPOINT_NOT_ENABLED = 12,
- /** Short packet */
- XHCI_CMPLT_SHORT = 13,
- /** Parameter Error */
- XHCI_CMPLT_PARAMETER = 17,
- /** Command ring stopped */
- XHCI_CMPLT_CMD_STOPPED = 24,
-};
-
-/** A port status change transfer request block */
-struct xhci_trb_port_status {
- /** Reserved */
- uint8_t reserved_a[3];
- /** Port ID */
- uint8_t port;
- /** Reserved */
- uint8_t reserved_b[7];
- /** Completion code */
- uint8_t code;
- /** Flags */
- uint8_t flags;
- /** Type */
- uint8_t type;
- /** Reserved */
- uint16_t reserved_c;
-} __attribute__ (( packed ));
-
-/** A port status change transfer request block */
-#define XHCI_TRB_PORT_STATUS XHCI_TRB_TYPE ( 34 )
-
-/** A port status change transfer request block */
-struct xhci_trb_host_controller {
- /** Reserved */
- uint64_t reserved_a;
- /** Reserved */
- uint8_t reserved_b[3];
- /** Completion code */
- uint8_t code;
- /** Flags */
- uint8_t flags;
- /** Type */
- uint8_t type;
- /** Reserved */
- uint16_t reserved_c;
-} __attribute__ (( packed ));
-
-/** A port status change transfer request block */
-#define XHCI_TRB_HOST_CONTROLLER XHCI_TRB_TYPE ( 37 )
-
-/** A transfer request block */
-union xhci_trb {
- /** Template */
- struct xhci_trb_template template;
- /** Common fields */
- struct xhci_trb_common common;
- /** Normal TRB */
- struct xhci_trb_normal normal;
- /** Setup stage TRB */
- struct xhci_trb_setup setup;
- /** Data stage TRB */
- struct xhci_trb_data data;
- /** Status stage TRB */
- struct xhci_trb_status status;
- /** Link TRB */
- struct xhci_trb_link link;
- /** Enable slot TRB */
- struct xhci_trb_enable_slot enable;
- /** Disable slot TRB */
- struct xhci_trb_disable_slot disable;
- /** Input context TRB */
- struct xhci_trb_context context;
- /** Reset endpoint TRB */
- struct xhci_trb_reset_endpoint reset;
- /** Stop endpoint TRB */
- struct xhci_trb_stop_endpoint stop;
- /** Set transfer ring dequeue pointer TRB */
- struct xhci_trb_set_tr_dequeue_pointer dequeue;
- /** Transfer event */
- struct xhci_trb_transfer transfer;
- /** Command completion event */
- struct xhci_trb_complete complete;
- /** Port status changed event */
- struct xhci_trb_port_status port;
- /** Host controller event */
- struct xhci_trb_host_controller host;
-} __attribute__ (( packed ));
-
-struct xhci_ring {
- union xhci_trb ring[XHCI_RING_ITEMS];
- union xhci_trb evt;
- uint32_t eidx;
- uint32_t nidx;
- uint32_t cs;
- usb_osal_mutex_t lock;
-};
-
-/** An event ring segment */
-struct xhci_er_seg {
- /** Base address */
- uint64_t base;
- /** Number of TRBs */
- uint32_t count;
- /** Reserved */
- uint32_t reserved;
-} __attribute__ (( packed ));
-
-/** An xHCI endpoint */
-struct xhci_endpoint {
- struct xhci_ring reqs; /* DO NOT MOVE reqs from structure beg */
- /** xHCI device */
- struct xhci_host *xhci;
- /** xHCI slot */
- struct xhci_slot *slot;
- /** Endpoint address */
- unsigned int address;
- /** Context index */
- unsigned int ctx;
- /** Endpoint type in USB definition */
- unsigned int ep_type;
- /** Endpoint type in XHCI Endpoint context definition */
- unsigned int ctx_type;
-
- /** Maximum transfer size (Maximum packet size) */
- unsigned int mtu;
- /** Maximum burst size */
- unsigned int burst;
- /** Endpoint interval */
- unsigned int interval;
-
- /** Endpoint context */
- struct xhci_endpoint_context *context;
-
- /* command or transfer waiter */
- int timeout; /* = 0 no need to wait */
- bool waiter;
- usb_osal_sem_t waitsem;
-
- /* handle urb */
- struct usbh_hubport *hport;
- struct usbh_urb *urb; /* NULL if no active URB */
-};
-
-/** An xHCI device slot */
-struct xhci_slot {
- /** xHCI device */
- struct xhci_host *xhci;
- /** Slot ID */
- unsigned int id;
- /** Slot context */
- struct xhci_slot_context *context;
-
- /** Route string */
- unsigned int route;
- /** Root hub port number */
- unsigned int port;
- /** Protocol speed ID */
- unsigned int psiv;
- /** Number of ports (if this device is a hub) */
- unsigned int ports;
- /** Transaction translator slot ID */
- unsigned int tt_id;
- /** Transaction translator port */
- unsigned int tt_port;
-
- /** Endpoints, indexed by context ID */
- struct xhci_endpoint *endpoint[XHCI_CTX_END];
-};
-
-/** An xHCI device */
-struct xhci_host {
- /** ID */
- uint32_t id;
- /** Name */
- char name[4];
-
- /* xhci registers base addr */
- /** Registers base */
- void *base;
- /** Capability registers */
- void *cap;
- /** Operational registers */
- void *op;
- /** Runtime registers */
- void *run;
- /** Doorbell registers */
- void *db;
- /** extended capability */
- unsigned int xecp;
- /** capability cache */
- uint32_t hcs[3];
- uint32_t hcc;
- /** xhci version */
- uint16_t version;
-
- /** Number of device slots */
- unsigned int slots;
- /** Number of interrupters */
- unsigned int intrs;
- /** Number of ports */
- unsigned int ports;
-
- /** 64-bit addressing capability */
- int addr64;
- /** Context size shift */
- unsigned int csz_shift;
- /** Page size */
- size_t pagesize;
-
- /** USB legacy support capability (if present and enabled) */
- unsigned int legacy;
-
- /** Device context base address array */
- struct xhci_dcbaa dcbaa;
-
- /** Scratchpad buffer */
- struct xhci_scratchpad scratch;
-
- /** Device slots, indexed by slot ID */
- struct xhci_slot **slot;
-
- /** Command ring */
- struct xhci_ring *cmds;
- /** Event ring */
- struct xhci_ring *evts;
- struct xhci_er_seg *eseg;
-
- struct xhci_endpoint *cur_cmd_pipe;
-};
-
-/**
- * Calculate input context offset
- *
- * @v xhci xHCI device
- * @v ctx Context index
- */
-static inline size_t xhci_input_context_offset ( struct xhci_host *xhci,
- unsigned int ctx ) {
-
- return ( XHCI_ICI ( ctx ) << xhci->csz_shift );
-}
-
-/**
- * Calculate device context offset
- *
- * @v xhci xHCI device
- * @v ctx Context index
- */
-static inline size_t xhci_device_context_offset ( struct xhci_host *xhci,
- unsigned int ctx ) {
-
- return ( XHCI_DCI ( ctx ) << xhci->csz_shift );
-}
-
-/* Probe XCHI device */
-int xhci_probe ( struct xhci_host *xhci, unsigned long baseaddr );
-
-/* Open XHCI device and start running */
-int xhci_open ( struct xhci_host *xhci );
-
-/* Close XHCI device and stop running */
-void xhci_close ( struct xhci_host *xhci );
-
-/* Remove XHCI device and free allocated memory */
-void xhci_remove ( struct xhci_host *xhci );
-
-/* Enable port */
-int xhci_port_enable (struct xhci_host *xhci, uint32_t port);
-
-/* Get port speed */
-uint32_t xhci_root_speed ( struct xhci_host *xhci, uint8_t port );
-
-/* Open and enable device */
-int xhci_device_open ( struct xhci_host *xhci, struct xhci_endpoint *pipe, int *slot_id );
-
-/* Assign device address */
-int xhci_device_address ( struct xhci_host *xhci, struct xhci_slot *slot, struct xhci_endpoint *pipe );
-
-/* Close device and free allocated memory */
-void xhci_device_close ( struct xhci_slot *slot );
-
-/* Open control endpoint for slot */
-int xhci_ctrl_endpoint_open ( struct xhci_host *xhci, struct xhci_slot *slot, struct xhci_endpoint *pipe );
-
-/* Open work endpoint for slot */
-int xhci_work_endpoint_open ( struct xhci_host *xhci, struct xhci_slot *slot, struct xhci_endpoint *pipe );
-
-/* Close endpoint and free allocated memory */
-void xhci_endpoint_close ( struct xhci_endpoint *ep );
-
-/* Update MTU (Max packet size) of endpoint */
-int xhci_endpoint_mtu ( struct xhci_endpoint *ep );
-
-/* Enqueue message transfer, usually for control transfer */
-void xhci_endpoint_message ( struct xhci_endpoint *ep, struct usb_setup_packet *packet,
- void *data_buff, int datalen );
-
-/* Enqueue stream transfer, usually for bulk/interrupt transfer */
-void xhci_endpoint_stream ( struct xhci_endpoint *ep, void *data_buff, int datalen );
-
-/* Process event ring in interrupt */
-struct xhci_endpoint *xhci_event_process(struct xhci_host *xhci);
-
-/* Wait for a ring to empty (all TRBs processed by hardware) */
-int xhci_event_wait(struct xhci_host *xhci,
- struct xhci_endpoint *pipe,
- struct xhci_ring *ring);
-
-/* Dump host controller registers */
-void xhci_dump(struct xhci_host *xhci);
-
-/* Dump port registers */
-void xhci_dump_port ( struct xhci_host *xhci,
- unsigned int port );
-
-/* Dump Port status */
-void xhci_dump_port_status(uint32_t port, uint32_t portsc);
-
-/* Dump input context */
-void xhci_dump_input_ctx( struct xhci_host *xhci, const struct xhci_endpoint *endpoint, const void *input);
-
-/* Dump Endpoint */
-void xhci_dump_endpoint(const struct xhci_endpoint *ep);
-
-/* Dump endpoint context */
-void xhci_dump_ep_ctx(const struct xhci_endpoint_context *ep);
-
-/* Dump TRB */
-void xhci_dump_trbs(const union xhci_trb *trbs, unsigned int count);
-
-/* Dump slot context */
-void xhci_dump_slot_ctx(const struct xhci_slot_context *const sc);
-
-#endif /* XHCI_H */ \ No newline at end of file
diff --git a/port/xhci/xhci_dbg.c b/port/xhci/xhci_dbg.c
deleted file mode 100644
index 61ca296f..00000000
--- a/port/xhci/xhci_dbg.c
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * Copyright : (C) 2022 Phytium Information Technology, Inc.
- * All Rights Reserved.
- *
- * This program is OPEN SOURCE software: you can redistribute it and/or modify it
- * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd,
- * either version 1.0 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the Phytium Public License for more details.
- *
- *
- * FilePath: xhci_dbg.c
- * Date: 2022-07-19 09:26:25
- * LastEditTime: 2022-07-19 09:26:25
- * Description:  This file is for implment xhci debug functions
- *
- * Modify History:
- * Ver   Who        Date         Changes
- * ----- ------     --------    --------------------------------------
- * 1.0 zhugengyu 2022/9/19 init commit
- * 2.0 zhugengyu 2023/3/29 support usb3.0 device attached at roothub
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <strings.h>
-
-#include "usbh_core.h"
-
-#include "xhci.h"
-
-/* macro to enable dump */
-#define XHCI_DUMP 1
-#define XHCI_DUMP_PORT 1
-#define XHCI_DUMP_TRB 0
-#define XHCI_DUMP_SLOT 0
-#define XHCI_DUMP_EP_CTX 0
-#define XHCI_DUMP_INPUT_CTX 0
-#define XHCI_DUMP_ENDPOINT 0
-#define XHCI_DUMP_PORT_STATUS 0
-
-/**
- * Dump host controller registers
- *
- * @v xhci xHCI device
- */
-void xhci_dump(struct xhci_host *xhci) {
-#if XHCI_DUMP
- uint32_t usbcmd;
- uint32_t usbsts;
- uint32_t pagesize;
- uint32_t dnctrl;
- uint32_t config;
-
- /* Dump USBCMD */
- usbcmd = readl ( xhci->op + XHCI_OP_USBCMD );
- USB_LOG_DBG ( "XHCI %s USBCMD %08x%s%s\n", xhci->name, usbcmd,
- ( ( usbcmd & XHCI_USBCMD_RUN ) ? " run" : "" ),
- ( ( usbcmd & XHCI_USBCMD_HCRST ) ? " hcrst" : "" ) );
-
- /* Dump USBSTS */
- usbsts = readl ( xhci->op + XHCI_OP_USBSTS );
- USB_LOG_DBG ( "XHCI %s USBSTS %08x%s\n", xhci->name, usbsts,
- ( ( usbsts & XHCI_USBSTS_HCH ) ? " hch" : "" ) );
-
- /* Dump PAGESIZE */
- pagesize = readl ( xhci->op + XHCI_OP_PAGESIZE );
- USB_LOG_DBG ( "XHCI %s PAGESIZE %08x\n", xhci->name, pagesize );
-
- /* Dump DNCTRL */
- dnctrl = readl ( xhci->op + XHCI_OP_DNCTRL );
- USB_LOG_DBG ( "XHCI %s DNCTRL %08x\n", xhci->name, dnctrl );
-
- /* Dump CONFIG */
- config = readl ( xhci->op + XHCI_OP_CONFIG );
- USB_LOG_DBG ( "XHCI %s CONFIG %08x\n", xhci->name, config );
-#endif
-}
-
-/**
- * Dump port registers
- *
- * @v xhci xHCI device
- * @v port Port number
- */
-void xhci_dump_port ( struct xhci_host *xhci,
- unsigned int port ) {
-#if XHCI_DUMP_PORT
- uint32_t portsc;
- uint32_t portpmsc;
- uint32_t portli;
- uint32_t porthlpmc;
-
- /* Dump PORTSC */
- portsc = readl ( xhci->op + XHCI_OP_PORTSC ( port ) );
- USB_LOG_DBG ( "XHCI %s-%d PORTSC %08x%s%s%s%s psiv=%d\n",
- xhci->name, port, portsc,
- ( ( portsc & XHCI_PORTSC_CCS ) ? " ccs" : "" ),
- ( ( portsc & XHCI_PORTSC_PED ) ? " ped" : "" ),
- ( ( portsc & XHCI_PORTSC_PR ) ? " pr" : "" ),
- ( ( portsc & XHCI_PORTSC_PP ) ? " pp" : "" ),
- XHCI_PORTSC_PSIV ( portsc ) );
-
- /* Dump PORTPMSC */
- portpmsc = readl ( xhci->op + XHCI_OP_PORTPMSC ( port ) );
- USB_LOG_DBG ( "XHCI %s-%d PORTPMSC %08x\n", xhci->name, port, portpmsc );
-
- /* Dump PORTLI */
- portli = readl ( xhci->op + XHCI_OP_PORTLI ( port ) );
- USB_LOG_DBG ( "XHCI %s-%d PORTLI %08x\n", xhci->name, port, portli );
-
- /* Dump PORTHLPMC */
- porthlpmc = readl ( xhci->op + XHCI_OP_PORTHLPMC ( port ) );
- USB_LOG_DBG ( "XHCI %s-%d PORTHLPMC %08x\n",
- xhci->name, port, porthlpmc );
-#endif
-}
-
-/**
- * Dump slot context
- *
- * @v sc Slot context
- */
-void xhci_dump_slot_ctx(const struct xhci_slot_context *const sc) {
-#if XHCI_DUMP_SLOT
- const uint8_t *ctx = (uint8_t *)sc;
-
- USB_LOG_DBG("===== slot ctx ===== \r\n");
- USB_LOG_DBG("ctx[0]=0x%x\n", *((uint32_t*)ctx));
- USB_LOG_DBG(" info: 0x%x \r\n", sc->info);
- USB_LOG_DBG("ctx[1]=0x%x\n", *((uint32_t*)ctx + 1));
- USB_LOG_DBG(" latency: 0x%x \r\n", sc->latency);
- USB_LOG_DBG(" port: 0x%x \r\n", sc->port);
- USB_LOG_DBG(" ports: 0x%x \r\n", sc->ports);
- USB_LOG_DBG("ctx[2]=0x%x\n", *((uint32_t*)ctx + 2));
- USB_LOG_DBG(" tt_id: 0x%x \r\n", sc->tt_id);
- USB_LOG_DBG(" tt_port: 0x%x \r\n", sc->tt_port);
- USB_LOG_DBG("ctx[3]=0x%x\n", *((uint32_t*)ctx + 3));
- USB_LOG_DBG(" intr: 0x%x \r\n", sc->intr);
- USB_LOG_DBG(" address: 0x%x \r\n", sc->address);
- USB_LOG_DBG(" state: 0x%x \r\n", sc->state);
- USB_LOG_DBG("=====+++++++++===== \r\n");
-#endif
-}
-
-/**
- * Dump endpoint context
- *
- * @v ep Endpoint context
- */
-void xhci_dump_ep_ctx(const struct xhci_endpoint_context *ep) {
-#if XHCI_DUMP_EP_CTX
- const uint8_t *ctx = (uint8_t *)ep;
-
- USB_LOG_DBG("===== ep ctx ===== \r\n");
- USB_LOG_DBG("ctx[0]=0x%x\n", *((uint32_t*)ctx));
- USB_LOG_DBG(" ep_state: 0x%x \r\n", ep->state);
- USB_LOG_DBG(" mult: 0x%x \r\n", XHCI_EPCTX_MULT_GET(ep->stream));
- USB_LOG_DBG(" stream: 0x%x \r\n", XHCI_EPCTX_STREAM_GET(ep->stream));
- USB_LOG_DBG(" lsa: 0x%x \r\n", !!(XHCI_EPCTX_LSA & (ep->stream)));
- USB_LOG_DBG(" interval: 0x%x \r\n", ep->interval);
- USB_LOG_DBG(" esit_high: 0x%x \r\n", ep->esit_high);
- USB_LOG_DBG("ctx[1]=0x%x\n", *((uint32_t*)ctx + 1));
- USB_LOG_DBG(" cerr: 0x%x \r\n", XHCI_EPCTX_CERR_GET(ep->type));
- USB_LOG_DBG(" type: 0x%x \r\n", XHCI_EPCTX_TYPE_GET(ep->type));
- USB_LOG_DBG(" hid: 0x%x \r\n", !!(XHCI_EPCTX_HID & (ep->type)));
- USB_LOG_DBG(" burst: 0x%x \r\n", ep->burst);
- USB_LOG_DBG(" mtu: 0x%x \r\n", ep->mtu);
- USB_LOG_DBG("ctx[2]=0x%x\n", *((uint32_t*)ctx + 2));
- USB_LOG_DBG("ctx[3]=0x%x\n", *((uint32_t*)ctx + 3));
- USB_LOG_DBG(" dequeue: 0x%lx \r\n", ep->dequeue);
- USB_LOG_DBG(" dcs: 0x%lx \r\n", !!(XHCI_EPCTX_DCS & ep->dequeue));
- USB_LOG_DBG("ctx[4]=0x%x\n", *((uint32_t*)ctx + 4));
- USB_LOG_DBG(" trb_len: 0x%x \r\n", ep->trb_len);
- USB_LOG_DBG(" esit_low: 0x%x \r\n", ep->esit_low);
- USB_LOG_DBG("=====+++++++++===== \r\n");
-#endif
-}
-
-/**
- * Dump input context
- *
- * @v xhci XHCI device
- * @v endpoint Endpoint
- * @v input Input context
- */
-void xhci_dump_input_ctx( struct xhci_host *xhci, const struct xhci_endpoint *endpoint, const void *input) {
-#if XHCI_DUMP_INPUT_CTX
- const struct xhci_control_context *control_ctx;
- const struct xhci_slot_context *slot_ctx;
- const struct xhci_endpoint_context *ep_ctx;
-
- control_ctx = input;
- slot_ctx = ( input + xhci_input_context_offset ( xhci, XHCI_CTX_SLOT ));
- ep_ctx = ( input + xhci_input_context_offset ( xhci, endpoint->ctx ) );
-
- USB_LOG_DBG("===input ctx====\n");
- USB_LOG_DBG("ctrl@%p=0x%x\n", control_ctx, *control_ctx);
- USB_LOG_DBG("add=0x%x\n", control_ctx->add);
- USB_LOG_DBG("del=0x%x\n", control_ctx->drop);
-
- USB_LOG_DBG("slot@%p\n", slot_ctx);
- xhci_dump_slot_ctx(slot_ctx);
-
- USB_LOG_DBG("ep-%d@%p\n", endpoint->ctx, ep_ctx);
- xhci_dump_ep_ctx(ep_ctx);
-
- USB_LOG_DBG("=====+++++++++===== \r\n");
-#endif
-}
-
-/**
- * Get next TRB in ring
- *
- * @v trbs TRB in ring
- * @v trb Next TRB
- */
-static const union xhci_trb * xhci_get_next_trb(const union xhci_trb *trbs) {
- const struct xhci_trb_link *link = &(trbs->link);
- if (link->type == XHCI_TRB_LINK) {
- return (link->next) ? (const union xhci_trb *)(link->next) : NULL;
- } else {
- return trbs + 1;
- }
-}
-
-/**
- * Dump TRB
- *
- * @v trbs TRB header
- * @v count Number of TRB to dump
- */
-void xhci_dump_trbs(const union xhci_trb *trbs, unsigned int count) {
-#if XHCI_DUMP_TRB
- const union xhci_trb *cur;
- const struct xhci_trb_common *comm;
- const uint8_t *dword;
-
- USB_LOG_DBG("===trbs ====\n");
- for (unsigned int i = 0; i < count; i++) {
- cur = &(trbs[i]);
- dword = (const uint8_t *)cur;
-
- comm = &(cur->common);
- USB_LOG_DBG("[0x%x-0x%x-0x%x-0x%x]\n",
- *((uint32_t *)dword), *((uint32_t *)dword + 1),
- *((uint32_t *)dword + 2), *((uint32_t *)dword + 3));
- if (XHCI_TRB_SETUP == comm->type) {
- const struct xhci_trb_setup *setup = (const struct xhci_trb_setup *)comm;
-
- USB_LOG_DBG("setup trb\n");
- USB_LOG_DBG(" packet=0x%x\n", setup->packet);
- USB_LOG_DBG(" bmRequestType type=0x%x\n", setup->packet.bmRequestType);
- USB_LOG_DBG(" bRequest=0x%x\n", setup->packet.bRequest);
- USB_LOG_DBG(" wValue=0x%x\n", setup->packet.wValue);
- USB_LOG_DBG(" wIndex=0x%x\n", setup->packet.wIndex);
- USB_LOG_DBG(" wLength=0x%x\n", setup->packet.wLength);
- USB_LOG_DBG(" trb_trans_len=%d\n", setup->len);
- USB_LOG_DBG(" flags=0x%x\n", setup->flags);
- USB_LOG_DBG(" direction=%d\n", setup->direction);
- } else if (XHCI_TRB_DATA == comm->type) {
- const struct xhci_trb_data *data = (const struct xhci_trb_data *)comm;
-
- USB_LOG_DBG("data trb......\n");
- USB_LOG_DBG(" data=0x%x\n", data->data);
- USB_LOG_DBG(" len=%d\n", data->len);
- USB_LOG_DBG(" direction=%d\n", data->direction);
- } else if (XHCI_TRB_STATUS == comm->type) {
- const struct xhci_trb_status *status = (const struct xhci_trb_status *)comm;
-
- USB_LOG_DBG("status trb......\n");
- USB_LOG_DBG(" direction=%d\n", status->direction);
- }
- }
- USB_LOG_DBG("=====+++++++++===== \r\n");
-#endif
-}
-
-static const char *xhci_endpoint_xhci_type (unsigned int ep_xhci_type) {
- static const char *ep_names[] = {"not_valid", "isoc_out", "bulk_out",
- "intr_out", "ctrl", "isoc_in",
- "bulk_in", "intr_in"};
- unsigned int index = ep_xhci_type >> 3;
- if (index < sizeof(ep_names)/sizeof(ep_names[0])) {
- return ep_names[index];
- }
-
- return "unkown";
-}
-
-static const char *xhci_endpoint_type (unsigned int ep_type) {
- const char *ep_name = "unkown";
-
- switch (ep_type)
- {
- case USB_ENDPOINT_TYPE_CONTROL:
- ep_name = "ctrl-ep";
- break;
- case USB_ENDPOINT_TYPE_ISOCHRONOUS:
- ep_name = "isoc-ep";
- break;
- case USB_ENDPOINT_TYPE_BULK:
- ep_name = "bulk-ep";
- break;
- case USB_ENDPOINT_TYPE_INTERRUPT:
- ep_name = "intr-ep";
- break;
- default:
- break;
- }
-
- return ep_name;
-}
-
-/**
- * Dump Endpoint
- *
- * @v ep Endpoint
- */
-void xhci_dump_endpoint(const struct xhci_endpoint *ep) {
-#if XHCI_DUMP_ENDPOINT
- USB_LOG_DBG("===endpoint====\n");
- USB_LOG_DBG("xhci=0x%x\n", ep->xhci);
- USB_LOG_DBG("slot=0x%x\n", ep->slot);
- USB_LOG_DBG("address=0x%x\n", ep->address);
- USB_LOG_DBG("mtu=0x%x\n", ep->mtu);
- USB_LOG_DBG("burst=0x%x\n", ep->burst);
- USB_LOG_DBG("ctx=0x%x\n", ep->ctx);
- USB_LOG_DBG("ep_type=%s\n", xhci_endpoint_type(ep->ep_type));
- USB_LOG_DBG("xhci_type=%s\n", xhci_endpoint_xhci_type(ep->ctx_type));
- USB_LOG_DBG("interval=0x%x\n", ep->interval);
- USB_LOG_DBG("=====+++++++++===== \r\n");
-#endif
-}
-
-/**
- * Dump Port status
- *
- * @v port Port number
- * @v portsc Port status
- */
-void xhci_dump_port_status(uint32_t port, uint32_t portsc) {
-#if XHCI_DUMP_PORT_STATUS
- USB_LOG_DBG("====port-%d====\n");
- USB_LOG_DBG("connect=%d \n", !!(XHCI_PORTSC_CCS & port));
- USB_LOG_DBG("enabled=%d \n", !!(XHCI_PORTSC_PED & port));
- USB_LOG_DBG("powered=%d \n", !!(XHCI_PORTSC_PP & port));
- USB_LOG_DBG("=====+++++++++===== \r\n");
-#endif
-} \ No newline at end of file
diff --git a/port/xhci/xhci_reg.h b/port/xhci/xhci_reg.h
deleted file mode 100644
index a981daa6..00000000
--- a/port/xhci/xhci_reg.h
+++ /dev/null
@@ -1,499 +0,0 @@
-/*
- * Copyright : (C) 2022 Phytium Information Technology, Inc.
- * All Rights Reserved.
- *
- * This program is OPEN SOURCE software: you can redistribute it and/or modify it
- * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd,
- * either version 1.0 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the Phytium Public License for more details.
- *
- *
- * FilePath: xhci_reg.h
- * Date: 2022-07-19 09:26:25
- * LastEditTime: 2022-07-19 09:26:25
- * Description:  This file is for xhci register definition.
- *
- * Modify History:
- * Ver   Who        Date         Changes
- * ----- ------     --------    --------------------------------------
- * 1.0 zhugengyu 2022/9/19 init commit
- * 2.0 zhugengyu 2023/3/29 support usb3.0 device attached at roothub
- */
-
-#ifndef XHCI_REG_H
-#define XHCI_REG_H
-
-#if defined(__aarch64__)
-#define BITS_PER_LONG 64U
-#define XHCI_AARCH64
-#else
-#define BITS_PER_LONG 32U
-#define XHCI_AARCH32
-#endif
-
-#define XHCI_GENMASK(h, l) \
- (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
-
-#define XHCI_GENMASK_ULL(h, l) \
- (((~0ULL) - (1ULL << (l)) + 1) & \
- (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h))))
-
-#define XHCI32_GET_BITS(x, a, b) (uint32_t)((((uint32_t)(x)) & XHCI_GENMASK(a, b)) >> b)
-#define XHCI32_SET_BITS(x, a, b) (uint32_t)((((uint32_t)(x)) << b) & XHCI_GENMASK(a, b))
-#define XHCI64_GET_BITS(x, a, b) (uint64_t)((((uint64_t)(x)) & XHCI_GENMASK_ULL(a, b)) >> b)
-#define XHCI64_SET_BITS(x, a, b) (uint64_t)((((uint64_t)(x)) << b) & XHCI_GENMASK_ULL(a, b))
-
-/** Capability register length */
-#define XHCI_CAP_CAPLENGTH 0x00
-
-/** Host controller interface version number */
-#define XHCI_CAP_HCIVERSION 0x02
-
-/** Structural parameters 1 */
-#define XHCI_CAP_HCSPARAMS1 0x04
-
-/** Number of device slots */
-#define XHCI_HCSPARAMS1_SLOTS(params) ( ( (params) >> 0 ) & 0xff )
-
-/** Number of interrupters */
-#define XHCI_HCSPARAMS1_INTRS(params) ( ( (params) >> 8 ) & 0x3ff )
-
-/** Number of ports */
-#define XHCI_HCSPARAMS1_PORTS(params) ( ( (params) >> 24 ) & 0xff )
-
-/** Structural parameters 2 */
-#define XHCI_CAP_HCSPARAMS2 0x08
-
-/** Number of page-sized scratchpad buffers */
-#define XHCI_HCSPARAMS2_SCRATCHPADS(params) \
- ( ( ( (params) >> 16 ) & 0x3e0 ) | ( ( (params) >> 27 ) & 0x1f ) )
-
-/** Capability parameters */
-#define XHCI_CAP_HCCPARAMS1 0x10
-
-/** 64-bit addressing capability */
-#define XHCI_HCCPARAMS1_ADDR64(params) ( ( (params) >> 0 ) & 0x1 )
-
-/** Context size shift */
-#define XHCI_HCCPARAMS1_CSZ_SHIFT(params) ( 5 + ( ( (params) >> 2 ) & 0x1 ) )
-
-/** xHCI extended capabilities pointer */
-#define XHCI_HCCPARAMS1_XECP(params) ( ( ( (params) >> 16 ) & 0xffff ) << 2 )
-
-/** Doorbell offset */
-#define XHCI_CAP_DBOFF 0x14
-
-/** Runtime register space offset */
-#define XHCI_CAP_RTSOFF 0x18
-
-/** xHCI extended capability ID */
-#define XHCI_XECP_ID(xecp) ( ( (xecp) >> 0 ) & 0xff )
-
-/** Next xHCI extended capability pointer */
-#define XHCI_XECP_NEXT(xecp) ( ( ( (xecp) >> 8 ) & 0xff ) << 2 )
-
-/** USB legacy support extended capability */
-#define XHCI_XECP_ID_LEGACY 1
-
-/** USB legacy support BIOS owned semaphore */
-#define XHCI_USBLEGSUP_BIOS 0x02
-
-/** USB legacy support BIOS ownership flag */
-#define XHCI_USBLEGSUP_BIOS_OWNED 0x01
-
-/** USB legacy support OS owned semaphore */
-#define XHCI_USBLEGSUP_OS 0x03
-
-/** USB legacy support OS ownership flag */
-#define XHCI_USBLEGSUP_OS_OWNED 0x01
-
-/** USB legacy support control/status */
-#define XHCI_USBLEGSUP_CTLSTS 0x04
-
-/** Supported protocol extended capability */
-#define XHCI_XECP_ID_SUPPORTED 2
-
-/** Supported protocol revision */
-#define XHCI_SUPPORTED_REVISION 0x00
-
-/** Supported protocol minor revision */
-#define XHCI_SUPPORTED_REVISION_VER(revision) ( ( (revision) >> 16 ) & 0xffff )
-
-/** Supported protocol name */
-#define XHCI_SUPPORTED_NAME 0x04
-
-/** Supported protocol ports */
-#define XHCI_SUPPORTED_PORTS 0x08
-
-/** Supported protocol port offset */
-#define XHCI_SUPPORTED_PORTS_OFFSET(ports) ( ( (ports) >> 0 ) & 0xff )
-
-/** Supported protocol port count */
-#define XHCI_SUPPORTED_PORTS_COUNT(ports) ( ( (ports) >> 8 ) & 0xff )
-
-/** Supported protocol PSI count */
-#define XHCI_SUPPORTED_PORTS_PSIC(ports) ( ( (ports) >> 28 ) & 0x0f )
-
-/** Supported protocol slot */
-#define XHCI_SUPPORTED_SLOT 0x0c
-
-/** Supported protocol slot type */
-#define XHCI_SUPPORTED_SLOT_TYPE(slot) ( ( (slot) >> 0 ) & 0x1f )
-
-/** Supported protocol PSI */
-#define XHCI_SUPPORTED_PSI(index) ( 0x10 + ( (index) * 4 ) )
-
-/** Supported protocol PSI value */
-#define XHCI_SUPPORTED_PSI_VALUE(psi) ( ( (psi) >> 0 ) & 0x0f )
-
-/** Supported protocol PSI mantissa */
-#define XHCI_SUPPORTED_PSI_MANTISSA(psi) ( ( (psi) >> 16 ) & 0xffff )
-
-/** Supported protocol PSI exponent */
-#define XHCI_SUPPORTED_PSI_EXPONENT(psi) ( ( (psi) >> 4 ) & 0x03 )
-
-/** Default PSI values */
-enum {
- /** Full speed (12Mbps) */
- XHCI_SPEED_FULL = 1,
- /** Low speed (1.5Mbps) */
- XHCI_SPEED_LOW = 2,
- /** High speed (480Mbps) */
- XHCI_SPEED_HIGH = 3,
- /** Super speed */
- XHCI_SPEED_SUPER = 4,
-};
-
-/** USB command register */
-#define XHCI_OP_USBCMD 0x00
-
-/** Run/stop */
-#define XHCI_USBCMD_RUN 0x00000001UL
-
-/* Interrupter Enable (INTE) 1: enabled - RW */
-#define XHCI_USBCMD_INTE (1UL << 2)
-
-/** Host controller reset */
-#define XHCI_USBCMD_HCRST 0x00000002UL
-
-/** USB status register */
-#define XHCI_OP_USBSTS 0x04
-
-/** Host controller halted */
-#define XHCI_USBSTS_HCH 0x00000001UL
-
-/** Interrupt Pending (IP) */
-#define XHCI_USBSTS_EINT (1UL << 3)
-
-/** Page size register */
-#define XHCI_OP_PAGESIZE 0x08
-
-/** Page size */
-#define XHCI_PAGESIZE(pagesize) ( (pagesize) << 12 )
-
-/** Device notifcation control register */
-#define XHCI_OP_DNCTRL 0x14
-
-/** Command ring control register */
-#define XHCI_OP_CRCR 0x18
-
-/** Command ring cycle state */
-#define XHCI_CRCR_RCS 0x00000001UL
-
-/** Command abort */
-#define XHCI_CRCR_CA 0x00000004UL
-
-/** Command ring running */
-#define XHCI_CRCR_CRR 0x00000008UL
-
-/** Device context base address array pointer */
-#define XHCI_OP_DCBAAP 0x30
-
-/** Configure register */
-#define XHCI_OP_CONFIG 0x38
-
-/** Maximum device slots enabled */
-#define XHCI_CONFIG_MAX_SLOTS_EN(slots) ( (slots) << 0 )
-
-/** Maximum device slots enabled mask */
-#define XHCI_CONFIG_MAX_SLOTS_EN_MASK \
- XHCI_CONFIG_MAX_SLOTS_EN ( 0xff )
-
-/** Port status and control register */
-#define XHCI_OP_PORTSC(port) ( 0x400 - 0x10 + ( (port) << 4 ) )
-
-/** Current connect status */
-#define XHCI_PORTSC_CCS 0x00000001UL
-
-/** Port enabled */
-#define XHCI_PORTSC_PED 0x00000002UL
-
-#define XHCI_PORTSC_OCA (1 << 3)
-
-/** Port reset */
-#define XHCI_PORTSC_PR 0x00000010UL
-
-/** Port link state */
-#define XHCI_PORTSC_PLS(pls) ( (pls) << 5 )
-
-/** U0 state */
-#define XHCI_PORTSC_PLS_U0 XHCI_PORTSC_PLS ( 0 )
-
-/** Disabled port link state */
-#define XHCI_PORTSC_PLS_DISABLED XHCI_PORTSC_PLS ( 4 )
-
-/** RxDetect port link state */
-#define XHCI_PORTSC_PLS_RXDETECT XHCI_PORTSC_PLS ( 5 )
-
-/** Polling state */
-#define XHCI_PORTSC_PLS_POLLING XHCI_PORTSC_PLS ( 7 )
-
-/** Port link state mask */
-#define XHCI_PORTSC_PLS_MASK XHCI_PORTSC_PLS ( 0xf )
-
-/** Port power */
-#define XHCI_PORTSC_PP 0x00000200UL
-
-/** Time to delay after enabling power to a port */
-#define XHCI_PORT_POWER_DELAY_MS 20
-
-/** Port speed ID value */
-#define XHCI_PORTSC_PSIV(portsc) ( ( (portsc) >> 10 ) & 0xf )
-
-/** Port indicator control */
-#define XHCI_PORTSC_PIC(indicators) ( (indicators) << 14 )
-
-/** Port indicator control mask */
-#define XHCI_PORTSC_PIC_MASK XHCI_PORTSC_PIC ( 3 )
-
-/** Port link state write strobe */
-#define XHCI_PORTSC_LWS 0x00010000UL
-
-/** Time to delay after writing the port link state */
-#define XHCI_LINK_STATE_DELAY_MS 100
-
-/** Connect status change */
-#define XHCI_PORTSC_CSC (1 << 17)
-
-/** Port enabled/disabled change */
-#define XHCI_PORTSC_PEC (1 << 18)
-
-/** Warm port reset change */
-#define XHCI_PORTSC_WRC (1 << 19)
-
-/** Over-current change */
-#define XHCI_PORTSC_OCC (1 << 20)
-
-/** Port reset change */
-#define XHCI_PORTSC_PRC (1 << 21)
-
-/** Port link state change */
-#define XHCI_PORTSC_PLC (1 << 22)
-
-/** Port config error change */
-#define XHCI_PORTSC_CEC (1 << 23)
-
-/* Cold Attach Status 1: Far-end Receiver Terminations were detected */
-#define XHCI_PORTSC_CAS (1 << 24)
-
-/* Wake on Connect Enable 1: enable port to be sensitive to device connects */
-#define XHCI_PORTSC_WCE (1 << 25)
-
-/* Wake on Disconnect Enable 1: enable port to be sensitive to device disconnects */
-#define XHCI_PORTSC_WDE (1 << 26)
-
-/* Wake on Over-current Enable 1: enable port to be sensitive to over-current conditions */
-#define XHCI_PORTSC_WOE (1 << 27)
-
-/* Device Removable, 0: Device is removable. 1: Device is non-removable */
-#define XHCI_PORTSC_DR (1 << 30)
-
-/* Warm Port Reset 1: follow Warm Reset sequence */
-#define XHCI_PORTSC_WPR (1 << 31)
-
-/** Port status change mask */
-#define XHCI_PORTSC_CHANGE \
- ( XHCI_PORTSC_CSC | XHCI_PORTSC_PEC | XHCI_PORTSC_WRC | \
- XHCI_PORTSC_OCC | XHCI_PORTSC_PRC | XHCI_PORTSC_PLC | \
- XHCI_PORTSC_CEC )
-
-#define XHCI_PORTSC_RW_MASK (XHCI_PORTSC_PR | XHCI_PORTSC_PLS_MASK | XHCI_PORTSC_PP \
- | XHCI_PORTSC_PIC_MASK | XHCI_PORTSC_LWS | XHCI_PORTSC_WCE \
- | XHCI_PORTSC_WDE | XHCI_PORTSC_WOE)
-
-/** Port status and control bits which should be preserved
- *
- * The port status and control register is a horrendous mix of
- * differing semantics. Some bits are written to only when a separate
- * write strobe bit is set. Some bits should be preserved when
- * modifying other bits. Some bits will be cleared if written back as
- * a one. Most excitingly, the "port enabled" bit has the semantics
- * that 1=enabled, 0=disabled, yet writing a 1 will disable the port.
- */
-#define XHCI_PORTSC_PRESERVE ( XHCI_PORTSC_PP | XHCI_PORTSC_PIC_MASK )
-
-/** Port power management status and control register */
-#define XHCI_OP_PORTPMSC(port) ( 0x404 - 0x10 + ( (port) << 4 ) )
-
-/** Port link info register */
-#define XHCI_OP_PORTLI(port) ( 0x408 - 0x10 + ( (port) << 4 ) )
-
-/** Port hardware link power management control register */
-#define XHCI_OP_PORTHLPMC(port) ( 0x40c - 0x10 + ( (port) << 4 ) )
-
-/* Doorbell registers are 32 bits in length */
-#define XHCI_REG_DB_SIZE 4
-
-/** Interrupter Management Register */
-#define XHCI_RUN_IR_IMAN(intr) ( 0x20 + ( (intr) << 5 ) )
-
-/* Interrupt Pending, 1: an interrupt is pending for this Interrupter */
-#define XHCI_RUN_IR_IMAN_IP (1 << 0)
-
-/* Interrupt Enable, 1: capable of generating an interrupt. */
-#define XHCI_RUN_IR_IMAN_IE (1 << 1)
-
-/** Interrupter Moderation Register */
-#define XHCI_RUN_IR_IMOD(intr) ( 0x24 + ( (intr) << 5 ) )
-
-/** Event ring segment table size register */
-#define XHCI_RUN_ERSTSZ(intr) ( 0x28 + ( (intr) << 5 ) )
-
-/** Event ring segment table base address register */
-#define XHCI_RUN_ERSTBA(intr) ( 0x30 + ( (intr) << 5 ) )
-
-/** Event ring dequeue pointer register */
-#define XHCI_RUN_ERDP(intr) ( 0x38 + ( (intr) << 5 ) )
-
-/** Event Handler Busy */
-#define XHCI_RUN_ERDP_EHB (1 << 3)
-
-/** Minimum alignment required for data structures
- *
- * With the exception of the scratchpad buffer pages (which are
- * page-aligned), data structures used by xHCI generally require from
- * 16 to 64 byte alignment and must not cross an (xHCI) page boundary.
- * We simplify this requirement by aligning each structure on its own
- * size, with a minimum of a 64 byte alignment.
- */
-#define XHCI_MIN_ALIGN 64
-
-/** Maximum transfer size */
-#define XHCI_MTU 65536
-
-/** Read/Write Data Barrier for ARM */
-#define BARRIER() __asm__ __volatile__("": : :"memory")
-
-#ifdef XHCI_AARCH64
-#define DSB() __asm__ __volatile__("dsb sy": : : "memory")
-#else
-#define DSB() __asm__ __volatile__("dsb": : : "memory")
-#endif
-
-/**
- * Read byte from memory-mapped device
- *
- * @v io_addr I/O address
- * @ret data Value read
- */
-static inline uint8_t readb(void *io_addr ) {
- uint8_t val = *(volatile const uint8_t *)io_addr;
- BARRIER();
- return val;
-}
-
-/**
- * Read 16-bit word from memory-mapped device
- *
- * @v io_addr I/O address
- * @ret data Value read
- */
-static inline uint16_t readw(void * io_addr ) {
- uint16_t val = *(volatile const uint16_t *)io_addr;
- BARRIER();
- return val;
-}
-
-/**
- * Read 32-bit dword from memory-mapped device
- *
- * @v io_addr I/O address
- * @ret data Value read
- */
-static inline uint32_t readl(void * io_addr ) {
- uint32_t val = *(volatile const uint32_t *)io_addr;
- BARRIER();
- return val;
-}
-
-/**
- * Read 64-bit qword from memory-mapped device
- *
- * @v io_addr I/O address
- * @ret data Value read
- */
-static inline uint64_t readq(void * io_addr ) {
- uint64_t val = *(volatile const uint64_t *)io_addr;
- BARRIER();
- return val;
-}
-
-/**
- * Write byte to memory-mapped device
- *
- * @v data Value to write
- * @v io_addr I/O address
- */
-static inline void writeb(uint8_t data, void * io_addr ) {
- BARRIER();
- *(volatile uint8_t *)io_addr = data;
-}
-
-/**
- * Write 16-bit word to memory-mapped device
- *
- * @v data Value to write
- * @v io_addr I/O address
- */
-static inline void writew(uint16_t data, void * io_addr ) {
- BARRIER();
- *(volatile uint16_t *)io_addr = data;
-}
-
-/**
- * Write 32-bit dword to memory-mapped device
- *
- * @v data Value to writed
- * @v io_addr I/O address
- */
-static inline void writel(uint32_t data, void * io_addr ) {
- BARRIER();
- *(volatile uint32_t *)io_addr = data;
-}
-
-/**
- * Write 64-bit qword to memory-mapped device
- *
- * @v data Value to write
- * @v io_addr I/O address
- */
-static inline void writeq(uint64_t data, void * io_addr ) {
- BARRIER();
- *(volatile uint64_t *)io_addr = data;
-}
-
-/**
- * Byte-order converter for ARM-Little-End
- */
-#define CPU_TO_LE64(x) ((uint64_t)(x))
-#define LE64_to_CPU(x) ((uint64_t)(x))
-#define CPU_TO_LE32(x) ((uint32_t)(x))
-#define LE32_TO_CPU(x) ((uint32_t)(x))
-#define CPU_TO_LE16(x) ((uint16_t)(x))
-#define LE16_TO_CPU(x) ((uint16_t)(x))
-
-
-#endif /* XHCI_REG_H */ \ No newline at end of file