[U-Boot] [RFC] [UBOOT] [PATCH v3 7/7] USB: Modify the xHCI to adapt to the uBoot code base

Dan Murphy
2013-07-02T15:15:13Z

Modify the xHCI Linux kernel code base with #ifdefs __UBOOT__ to
adapt the xHCI to the uBoot code.

DMA and Radix needs investigating.

Signed-off-by: Dan Murphy <dmurphy@ti.com>
---
common/usb.c | 1 +
common/usb_hub.c | 1 +
drivers/usb/host/Makefile | 7 +
drivers/usb/host/xhci-ext-caps.h | 12 ++
drivers/usb/host/xhci-hub.c | 19 +-
drivers/usb/host/xhci-mem.c | 113 ++++++++++--
drivers/usb/host/xhci-pci.c | 356 -------------------------------------
drivers/usb/host/xhci-plat.c | 8 +-
drivers/usb/host/xhci-ring.c | 52 +++++-
drivers/usb/host/xhci.c | 82 +++++++--
drivers/usb/host/xhci.h | 20 ++-
include/asm-generic/scatterlist.h | 34 ++++
include/configs/omap5_common.h | 1 +
include/linux/usb/ch11.h | 13 ++
include/linux/usb/hcd.h | 10 +-
include/linux/usb/linux-compat.h | 47 +++++
include/linux/usb/usb-compat.h | 4 +-
include/usb.h | 34 +---
18 files changed, 382 insertions(+), 432 deletions(-)
delete mode 100644 drivers/usb/host/xhci-pci.c
create mode 100644 include/asm-generic/scatterlist.h

diff --git a/common/usb.c b/common/usb.c
index 55fff5b..99aead8 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -53,6 +53,7 @@
#include <asm/unaligned.h>

#include <usb.h>
+#include <linux/usb/hcd.h>
#ifdef CONFIG_4xx
#include <asm/4xx_pci.h>
#endif
diff --git a/common/usb_hub.c b/common/usb_hub.c
index 774ba63..e18e34d 100644
--- a/common/usb_hub.c
+++ b/common/usb_hub.c
@@ -49,6 +49,7 @@
#include <asm/unaligned.h>

#include <usb.h>
+#include <linux/usb/ch11.h> /* usb structure information */
#ifdef CONFIG_4xx
#include <asm/4xx_pci.h>
#endif
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 98f2a10..a483182 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -58,6 +58,12 @@ COBJS-$(CONFIG_USB_EHCI_SPEAR) += ehci-spear.o
COBJS-$(CONFIG_USB_EHCI_TEGRA) += ehci-tegra.o
COBJS-$(CONFIG_USB_EHCI_VCT) += ehci-vct.o

+COBJS-$(CONFIG_USB_XHCI) += xhci.o
+COBJS-$(CONFIG_USB_XHCI) += xhci-hub.o
+COBJS-$(CONFIG_USB_XHCI) += xhci-ring.o
+COBJS-$(CONFIG_USB_XHCI) += xhci-mem.o
+COBJS-$(CONFIG_USB_XHCI) += xhci-plat.o
+
COBJS := $(COBJS-y)
SRCS := $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
@@ -75,3 +81,4 @@ include $(SRCTREE)/rules.mk
sinclude $(obj).depend

#########################################################################
+
diff --git a/drivers/usb/host/xhci-ext-caps.h b/drivers/usb/host/xhci-ext-caps.h
index 377f424..f3cddb1 100644
--- a/drivers/usb/host/xhci-ext-caps.h
+++ b/drivers/usb/host/xhci-ext-caps.h
@@ -87,6 +87,8 @@
/* true: Controller Not Ready to accept doorbell or op reg writes after reset */
#define XHCI_STS_CNR (1 << 11)

+#define __UBOOT__
+#ifndef __UBOOT__
#include <linux/io.h>

/**
@@ -153,3 +155,13 @@ static inline int xhci_find_ext_cap_by_id(void __iomem *base, int ext_offset, in
return ext_offset;
return 0;
}
+#else
+static inline int xhci_find_next_cap_offset(void __iomem *base, int ext_offset)
+{
+ return 0;
+}
+static inline int xhci_find_ext_cap_by_id(void __iomem *base, int ext_offset, int id)
+{
+ return 0;
+}
+#endif
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 187a3ec..8f01cb3 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -19,10 +19,11 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
+#define __UBOOT__
+#ifndef __UBOOT__
#include <linux/gfp.h>
#include <asm/unaligned.h>
-
+#endif
#include "xhci.h"

#define PORT_WAKE_BITS (PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E)
@@ -632,8 +633,13 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
!DEV_SUPERSPEED(temp)) {
if ((temp & PORT_RESET) || !(temp & PORT_PE))
goto error;
+#ifndef __UBOOT__
if (time_after_eq(jiffies,
bus_state->resume_done[wIndex])) {
+#else
+ /* TODO fix this to equate to time_after_eq API */
+ if (bus_state->resume_done[wIndex]) {
+#endif
xhci_dbg(xhci, "Resume USB2 port %d\n",
wIndex + 1);
bus_state->resume_done[wIndex] = 0;
@@ -1009,10 +1015,19 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf)
retval = -ENODEV;
break;
}
+#ifndef __UBOOT__
if ((temp & mask) != 0 ||
(bus_state->port_c_suspend & 1 << i) ||
(bus_state->resume_done[i] && time_after_eq(
jiffies, bus_state->resume_done[i]))) {
+#else
+ /* TODO Fix this for the time_after_eq api */
+ if ((temp & mask) != 0 ||
+ (bus_state->port_c_suspend & 1 << i) ||
+ (bus_state->resume_done[i] &&
+ (bus_state->resume_done[i]))) {
+
+#endif
buf[(i + 1) / 8] |= 1 << (i + 1) % 8;
status = 1;
}
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 2cfc465..4b3f559 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -19,12 +19,20 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
+#define __UBOOT__
+#ifndef __UBOOT__
#include <linux/usb.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/dmapool.h>

+#else
+#include <common.h>
+#include <linux/list.h> /* for struct list_head */
+#include <linux/usb/linux-compat.h>
+#include <linux/usb/usb-compat.h>
+#endif
+
#include "xhci.h"

/*
@@ -44,13 +52,14 @@ static struct xhci_segment *xhci_segment_alloc(struct xhci_hcd *xhci,
seg = kzalloc(sizeof *seg, flags);
if (!seg)
return NULL;
-
+#ifndef __UBOOT__
+ /* DMA */
seg->trbs = dma_pool_alloc(xhci->segment_pool, flags, &dma);
if (!seg->trbs) {
kfree(seg);
return NULL;
}
-
+#endif
memset(seg->trbs, 0, TRB_SEGMENT_SIZE);
/* If the cycle state is 0, set the cycle bit to 1 for all the TRBs */
if (cycle_state == 0) {
@@ -66,7 +75,10 @@ static struct xhci_segment *xhci_segment_alloc(struct xhci_hcd *xhci,
static void xhci_segment_free(struct xhci_hcd *xhci, struct xhci_segment *seg)
{
if (seg->trbs) {
+#ifndef __UBOOT__
+ /* DMA */
dma_pool_free(xhci->segment_pool, seg->trbs, seg->dma);
+#endif
seg->trbs = NULL;
}
kfree(seg);
@@ -367,8 +379,10 @@ static struct xhci_container_ctx *xhci_alloc_container_ctx(struct xhci_hcd *xhci
ctx->size = HCC_64BYTE_CONTEXT(xhci->hcc_params) ? 2048 : 1024;
if (type == XHCI_CTX_TYPE_INPUT)
ctx->size += CTX_SIZE(xhci->hcc_params);
-
+#ifndef __UBOOT__
+ /* DMA */
ctx->bytes = dma_pool_alloc(xhci->device_pool, flags, &ctx->dma);
+#endif
memset(ctx->bytes, 0, ctx->size);
return ctx;
}
@@ -378,7 +392,10 @@ static void xhci_free_container_ctx(struct xhci_hcd *xhci,
{
if (!ctx)
return;
+#ifndef __UBOOT__
+ /* DMA */
dma_pool_free(xhci->device_pool, ctx->bytes, ctx->dma);
+#endif
kfree(ctx);
}

@@ -419,6 +436,8 @@ static void xhci_free_stream_ctx(struct xhci_hcd *xhci,
unsigned int num_stream_ctxs,
struct xhci_stream_ctx *stream_ctx, dma_addr_t dma)
{
+#ifndef __UBOOT__
+ /* PCI */
struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);

if (num_stream_ctxs > MEDIUM_STREAM_ARRAY_SIZE)
@@ -431,6 +450,9 @@ static void xhci_free_stream_ctx(struct xhci_hcd *xhci,
else
return dma_pool_free(xhci->medium_streams_pool,
stream_ctx, dma);
+#else
+ return;
+#endif
}

/*
@@ -447,6 +469,8 @@ static struct xhci_stream_ctx *xhci_alloc_stream_ctx(struct xhci_hcd *xhci,
unsigned int num_stream_ctxs, dma_addr_t *dma,
gfp_t mem_flags)
{
+#ifndef __UBOOT__
+ /* PCI */
struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);

if (num_stream_ctxs > MEDIUM_STREAM_ARRAY_SIZE)
@@ -459,15 +483,21 @@ static struct xhci_stream_ctx *xhci_alloc_stream_ctx(struct xhci_hcd *xhci,
else
return dma_pool_alloc(xhci->medium_streams_pool,
mem_flags, dma);
+#else
+ return NULL;
+#endif
}

struct xhci_ring *xhci_dma_to_transfer_ring(
struct xhci_virt_ep *ep,
u64 address)
{
+#ifndef __UBOOT__
+ /* RADIX */
if (ep->ep_state & EP_HAS_STREAMS)
return radix_tree_lookup(&ep->stream_info->trb_address_map,
address >> TRB_SEGMENT_SHIFT);
+#endif
return ep->ring;
}

@@ -597,7 +627,10 @@ struct xhci_stream_info *xhci_alloc_stream_info(struct xhci_hcd *xhci,
struct xhci_stream_info *stream_info;
u32 cur_stream;
struct xhci_ring *cur_ring;
+#ifndef __UBOOT__
+ /* ilog2 */
unsigned long key;
+#endif
u64 addr;
int ret;

@@ -638,8 +671,10 @@ struct xhci_stream_info *xhci_alloc_stream_info(struct xhci_hcd *xhci,
xhci_alloc_command(xhci, true, true, mem_flags);
if (!stream_info->free_streams_command)
goto cleanup_ctx;
-
+#ifndef __UBOOT__
+ /* RADIX */
INIT_RADIX_TREE(&stream_info->trb_address_map, GFP_ATOMIC);
+#endif

/* Allocate rings for all the streams that the driver will use,
* and add their segment DMA addresses to the radix tree.
@@ -660,11 +695,16 @@ struct xhci_stream_info *xhci_alloc_stream_info(struct xhci_hcd *xhci,
cpu_to_le64(addr);
xhci_dbg(xhci, "Setting stream %d ring ptr to 0x%08llx\n",
cur_stream, (unsigned long long) addr);
-
+#ifndef __UBOOT__
+ /* ilog2 */
key = (unsigned long)
(cur_ring->first_seg->dma >> TRB_SEGMENT_SHIFT);
+#endif
+#ifndef __UBOOT__
+ /* RADIX */
ret = radix_tree_insert(&stream_info->trb_address_map,
key, cur_ring);
+#endif
if (ret) {
xhci_ring_free(xhci, cur_ring);
stream_info->stream_rings[cur_stream] = NULL;
@@ -692,8 +732,11 @@ cleanup_rings:
cur_ring = stream_info->stream_rings[cur_stream];
if (cur_ring) {
addr = cur_ring->first_seg->dma;
+#ifndef __UBOOT__
+ /* RADIX */
radix_tree_delete(&stream_info->trb_address_map,
addr >> TRB_SEGMENT_SHIFT);
+#endif
xhci_ring_free(xhci, cur_ring);
stream_info->stream_rings[cur_stream] = NULL;
}
@@ -763,8 +806,11 @@ void xhci_free_stream_info(struct xhci_hcd *xhci,
cur_ring = stream_info->stream_rings[cur_stream];
if (cur_ring) {
addr = cur_ring->first_seg->dma;
+#ifndef __UBOOT__
+ /* RADIX */
radix_tree_delete(&stream_info->trb_address_map,
addr >> TRB_SEGMENT_SHIFT);
+#endif
xhci_ring_free(xhci, cur_ring);
stream_info->stream_rings[cur_stream] = NULL;
}
@@ -788,9 +834,12 @@ void xhci_free_stream_info(struct xhci_hcd *xhci,
static void xhci_init_endpoint_timer(struct xhci_hcd *xhci,
struct xhci_virt_ep *ep)
{
+#ifndef __UBOOT__
+ /* Timer */
init_timer(&ep->stop_cmd_timer);
ep->stop_cmd_timer.data = (unsigned long) ep;
ep->stop_cmd_timer.function = xhci_stop_endpoint_command_watchdog;
+#endif
ep->xhci = xhci;
}

@@ -973,8 +1022,9 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id,
if (!dev->ring_cache)
goto fail;
dev->num_rings_cached = 0;
-
+#ifndef __UBOOT__
init_completion(&dev->cmd_completion);
+#endif
INIT_LIST_HEAD(&dev->cmd_list);
dev->udev = udev;

@@ -1680,6 +1730,8 @@ static int scratchpad_alloc(struct xhci_hcd *xhci, gfp_t flags)

static void scratchpad_free(struct xhci_hcd *xhci)
{
+#ifndef __UBOOT__
+ /* PCI */
int num_sp;
int i;
struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
@@ -1699,6 +1751,7 @@ static void scratchpad_free(struct xhci_hcd *xhci)
dma_free_coherent(&pdev->dev, num_sp * sizeof(u64),
xhci->scratchpad->sp_array,
xhci->scratchpad->sp_dma);
+#endif
kfree(xhci->scratchpad);
xhci->scratchpad = NULL;
}
@@ -1731,7 +1784,9 @@ struct xhci_command *xhci_alloc_command(struct xhci_hcd *xhci,
kfree(command);
return NULL;
}
+#ifndef __UBOOT__
init_completion(command->completion);
+#endif
}

command->status = 0;
@@ -1758,7 +1813,12 @@ void xhci_free_command(struct xhci_hcd *xhci,

void xhci_mem_cleanup(struct xhci_hcd *xhci)
{
+#ifndef __UBOOT__
+ /* PCI */
struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
+#else
+ struct pci_dev *pdev = NULL;
+#endif
struct dev_info *dev_info, *next;
struct xhci_cd *cur_cd, *next_cd;
unsigned long flags;
@@ -1767,9 +1827,12 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)

/* Free the Event Ring Segment Table and the actual Event Ring */
size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries);
+#ifndef __UBOOT__
+ /* DMA */
if (xhci->erst.entries)
dma_free_coherent(&pdev->dev, size,
xhci->erst.entries, xhci->erst.erst_dma_addr);
+#endif
xhci->erst.entries = NULL;
xhci_dbg(xhci, "Freed ERST\n");
if (xhci->event_ring)
@@ -1792,30 +1855,40 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)

for (i = 1; i < MAX_HC_SLOTS; ++i)
xhci_free_virt_device(xhci, i);
-
+#ifndef __UBOOT__
+ /* DMA */
if (xhci->segment_pool)
dma_pool_destroy(xhci->segment_pool);
+#endif
xhci->segment_pool = NULL;
xhci_dbg(xhci, "Freed segment pool\n");
-
+#ifndef __UBOOT__
+ /* DMA */
if (xhci->device_pool)
dma_pool_destroy(xhci->device_pool);
+#endif
xhci->device_pool = NULL;
xhci_dbg(xhci, "Freed device context pool\n");
-
+#ifndef __UBOOT__
+ /* DMA */
if (xhci->small_streams_pool)
dma_pool_destroy(xhci->small_streams_pool);
+#endif
xhci->small_streams_pool = NULL;
xhci_dbg(xhci, "Freed small stream array pool\n");
-
+#ifndef __UBOOT__
+ /* DMA */
if (xhci->medium_streams_pool)
dma_pool_destroy(xhci->medium_streams_pool);
+#endif
xhci->medium_streams_pool = NULL;
xhci_dbg(xhci, "Freed medium stream array pool\n");
-
+#ifndef __UBOOT__
+ /* DMA */
if (xhci->dcbaa)
dma_free_coherent(&pdev->dev, sizeof(*xhci->dcbaa),
xhci->dcbaa, xhci->dcbaa->dma);
+#endif
xhci->dcbaa = NULL;

scratchpad_free(xhci);
@@ -2022,7 +2095,11 @@ static void xhci_set_hc_event_deq(struct xhci_hcd *xhci)

deq = xhci_trb_virt_to_dma(xhci->event_ring->deq_seg,
xhci->event_ring->dequeue);
+#ifndef __UBOOT__
if (deq == 0 && !in_interrupt())
+#else
+ if (deq == 0)
+#endif
xhci_warn(xhci, "WARN something wrong with SW event ring "
"dequeue ptr.\n");
/* Update HC event ring dequeue pointer */
@@ -2305,24 +2382,32 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
* however, the command ring segment needs 64-byte aligned segments,
* so we pick the greater alignment need.
*/
+#ifndef __UBOOT__
+ /* DMA */
xhci->segment_pool = dma_pool_create("xHCI ring segments", dev,
TRB_SEGMENT_SIZE, 64, xhci->page_size);
-
+#endif
/* See Table 46 and Note on Figure 55 */
+#ifndef __UBOOT__
+ /* DMA */
xhci->device_pool = dma_pool_create("xHCI input/output contexts", dev,
2112, 64, xhci->page_size);
+#endif
if (!xhci->segment_pool || !xhci->device_pool)
goto fail;

/* Linear stream context arrays don't have any boundary restrictions,
* and only need to be 16-byte aligned.
*/
+#ifndef __UBOOT__
+ /* DMA */
xhci->small_streams_pool =
dma_pool_create("xHCI 256 byte stream ctx arrays",
dev, SMALL_STREAM_ARRAY_SIZE, 16, 0);
xhci->medium_streams_pool =
dma_pool_create("xHCI 1KB stream ctx arrays",
dev, MEDIUM_STREAM_ARRAY_SIZE, 16, 0);
+#endif
/* Any stream context array bigger than MEDIUM_STREAM_ARRAY_SIZE
* will be allocated with dma_alloc_coherent()
*/
@@ -2432,7 +2517,9 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
* something other than the default (~1ms minimum between interrupts).
* See section 5.5.1.2.
*/
+#ifndef __UBOOT__
init_completion(&xhci->addr_dev);
+#endif
for (i = 0; i < MAX_HC_SLOTS; ++i)
xhci->devs[i] = NULL;
for (i = 0; i < USB_MAXCHILDREN; ++i) {
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
deleted file mode 100644
index 1a30c38..0000000
--- a/drivers/usb/host/xhci-pci.c
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * xHCI host controller driver PCI Bus Glue.
- *
- * Copyright (C) 2008 Intel Corp.
- *
- * Author: Sarah Sharp
- * Some code borrowed from the Linux EHCI driver.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * 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 GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-
-#include "xhci.h"
-
-/* Device for a quirk */
-#define PCI_VENDOR_ID_FRESCO_LOGIC 0x1b73
-#define PCI_DEVICE_ID_FRESCO_LOGIC_PDK 0x1000
-#define PCI_DEVICE_ID_FRESCO_LOGIC_FL1400 0x1400
-
-#define PCI_VENDOR_ID_ETRON 0x1b6f
-#define PCI_DEVICE_ID_ASROCK_P67 0x7023
-
-static const char hcd_name[] = "xhci_hcd";
-
-/* called after powerup, by probe or system-pm "wakeup" */
-static int xhci_pci_reinit(struct xhci_hcd *xhci, struct pci_dev *pdev)
-{
- /*
- * TODO: Implement finding debug ports later.
- * TODO: see if there are any quirks that need to be added to handle
- * new extended capabilities.
- */
-
- /* PCI Memory-Write-Invalidate cycle support is optional (uncommon) */
- if (!pci_set_mwi(pdev))
- xhci_dbg(xhci, "MWI active\n");
-
- xhci_dbg(xhci, "Finished xhci_pci_reinit\n");
- return 0;
-}
-
-static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
-{
- struct pci_dev *pdev = to_pci_dev(dev);
-
- /* Look for vendor-specific quirks */
- if (pdev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC &&
- (pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK ||
- pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_FL1400)) {
- if (pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK &&
- pdev->revision == 0x0) {
- xhci->quirks |= XHCI_RESET_EP_QUIRK;
- xhci_dbg(xhci, "QUIRK: Fresco Logic xHC needs configure"
- " endpoint cmd after reset endpoint\n");
- }
- /* Fresco Logic confirms: all revisions of this chip do not
- * support MSI, even though some of them claim to in their PCI
- * capabilities.
- */
- xhci->quirks |= XHCI_BROKEN_MSI;
- xhci_dbg(xhci, "QUIRK: Fresco Logic revision %u "
- "has broken MSI implementation\n",
- pdev->revision);
- xhci->quirks |= XHCI_TRUST_TX_LENGTH;
- }
-
- if (pdev->vendor == PCI_VENDOR_ID_NEC)
- xhci->quirks |= XHCI_NEC_HOST;
-
- if (pdev->vendor == PCI_VENDOR_ID_AMD && xhci->hci_version == 0x96)
- xhci->quirks |= XHCI_AMD_0x96_HOST;
-
- /* AMD PLL quirk */
- if (pdev->vendor == PCI_VENDOR_ID_AMD && usb_amd_find_chipset_info())
- xhci->quirks |= XHCI_AMD_PLL_FIX;
- if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
- xhci->quirks |= XHCI_LPM_SUPPORT;
- xhci->quirks |= XHCI_INTEL_HOST;
- }
- if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
- pdev->device == PCI_DEVICE_ID_INTEL_PANTHERPOINT_XHCI) {
- xhci->quirks |= XHCI_SPURIOUS_SUCCESS;
- xhci->quirks |= XHCI_EP_LIMIT_QUIRK;
- xhci->limit_active_eps = 64;
- xhci->quirks |= XHCI_SW_BW_CHECKING;
- /*
- * PPT desktop boards DH77EB and DH77DF will power back on after
- * a few seconds of being shutdown. The fix for this is to
- * switch the ports from xHCI to EHCI on shutdown. We can't use
- * DMI information to find those particular boards (since each
- * vendor will change the board name), so we have to key off all
- * PPT chipsets.
- */
- xhci->quirks |= XHCI_SPURIOUS_REBOOT;
- xhci->quirks |= XHCI_AVOID_BEI;
- }
- if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
- pdev->device == PCI_DEVICE_ID_ASROCK_P67) {
- xhci->quirks |= XHCI_RESET_ON_RESUME;
- xhci_dbg(xhci, "QUIRK: Resetting on resume\n");
- xhci->quirks |= XHCI_TRUST_TX_LENGTH;
- }
- if (pdev->vendor == PCI_VENDOR_ID_VIA)
- xhci->quirks |= XHCI_RESET_ON_RESUME;
-}
-
-/* called during probe() after chip reset completes */
-static int xhci_pci_setup(struct usb_hcd *hcd)
-{
- struct xhci_hcd *xhci;
- struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
- int retval;
-
- retval = xhci_gen_setup(hcd, xhci_pci_quirks);
- if (retval)
- return retval;
-
- xhci = hcd_to_xhci(hcd);
- if (!usb_hcd_is_primary_hcd(hcd))
- return 0;
-
- pci_read_config_byte(pdev, XHCI_SBRN_OFFSET, &xhci->sbrn);
- xhci_dbg(xhci, "Got SBRN %u\n", (unsigned int) xhci->sbrn);
-
- /* Find any debug ports */
- retval = xhci_pci_reinit(xhci, pdev);
- if (!retval)
- return retval;
-
- kfree(xhci);
- return retval;
-}
-
-/*
- * We need to register our own PCI probe function (instead of the USB core's
- * function) in order to create a second roothub under xHCI.
- */
-static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
-{
- int retval;
- struct xhci_hcd *xhci;
- struct hc_driver *driver;
- struct usb_hcd *hcd;
-
- driver = (struct hc_driver *)id->driver_data;
- /* Register the USB 2.0 roothub.
- * FIXME: USB core must know to register the USB 2.0 roothub first.
- * This is sort of silly, because we could just set the HCD driver flags
- * to say USB 2.0, but I'm not sure what the implications would be in
- * the other parts of the HCD code.
- */
- retval = usb_hcd_pci_probe(dev, id);
-
- if (retval)
- return retval;
-
- /* USB 2.0 roothub is stored in the PCI device now. */
- hcd = dev_get_drvdata(&dev->dev);
- xhci = hcd_to_xhci(hcd);
- xhci->shared_hcd = usb_create_shared_hcd(driver, &dev->dev,
- pci_name(dev), hcd);
- if (!xhci->shared_hcd) {
- retval = -ENOMEM;
- goto dealloc_usb2_hcd;
- }
-
- /* Set the xHCI pointer before xhci_pci_setup() (aka hcd_driver.reset)
- * is called by usb_add_hcd().
- */
- *((struct xhci_hcd **) xhci->shared_hcd->hcd_priv) = xhci;
-
- retval = usb_add_hcd(xhci->shared_hcd, dev->irq,
- IRQF_SHARED);
- if (retval)
- goto put_usb3_hcd;
- /* Roothub already marked as USB 3.0 speed */
-
- /* We know the LPM timeout algorithms for this host, let the USB core
- * enable and disable LPM for devices under the USB 3.0 roothub.
- */
- if (xhci->quirks & XHCI_LPM_SUPPORT)
- hcd_to_bus(xhci->shared_hcd)->root_hub->lpm_capable = 1;
-
- return 0;
-
-put_usb3_hcd:
- usb_put_hcd(xhci->shared_hcd);
-dealloc_usb2_hcd:
- usb_hcd_pci_remove(dev);
- return retval;
-}
-
-static void xhci_pci_remove(struct pci_dev *dev)
-{
- struct xhci_hcd *xhci;
-
- xhci = hcd_to_xhci(pci_get_drvdata(dev));
- if (xhci->shared_hcd) {
- usb_remove_hcd(xhci->shared_hcd);
- usb_put_hcd(xhci->shared_hcd);
- }
- usb_hcd_pci_remove(dev);
- kfree(xhci);
-}
-
-#ifdef CONFIG_PM
-static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
-{
- struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-
- return xhci_suspend(xhci);
-}
-
-static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated)
-{
- struct xhci_hcd *xhci = hcd_to_xhci(hcd);
- struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
- int retval = 0;
-
- /* The BIOS on systems with the Intel Panther Point chipset may or may
- * not support xHCI natively. That means that during system resume, it
- * may switch the ports back to EHCI so that users can use their
- * keyboard to select a kernel from GRUB after resume from hibernate.
- *
- * The BIOS is supposed to remember whether the OS had xHCI ports
- * enabled before resume, and switch the ports back to xHCI when the
- * BIOS/OS semaphore is written, but we all know we can't trust BIOS
- * writers.
- *
- * Unconditionally switch the ports back to xHCI after a system resume.
- * We can't tell whether the EHCI or xHCI controller will be resumed
- * first, so we have to do the port switchover in both drivers. Writing
- * a '1' to the port switchover registers should have no effect if the
- * port was already switched over.
- */
- if (usb_is_intel_switchable_xhci(pdev))
- usb_enable_xhci_ports(pdev);
-
- retval = xhci_resume(xhci, hibernated);
- return retval;
-}
-#endif /* CONFIG_PM */
-
-static const struct hc_driver xhci_pci_hc_driver = {
- .description = hcd_name,
- .product_desc = "xHCI Host Controller",
- .hcd_priv_size = sizeof(struct xhci_hcd *),
-
- /*
- * generic hardware linkage
- */
- .irq = xhci_irq,
- .flags = HCD_MEMORY | HCD_USB3 | HCD_SHARED,
-
- /*
- * basic lifecycle operations
- */
- .reset = xhci_pci_setup,
- .start = xhci_run,
-#ifdef CONFIG_PM
- .pci_suspend = xhci_pci_suspend,
- .pci_resume = xhci_pci_resume,
-#endif
- .stop = xhci_stop,
- .shutdown = xhci_shutdown,
-
- /*
- * managing i/o requests and associated device resources
- */
- .urb_enqueue = xhci_urb_enqueue,
- .urb_dequeue = xhci_urb_dequeue,
- .alloc_dev = xhci_alloc_dev,
- .free_dev = xhci_free_dev,
- .alloc_streams = xhci_alloc_streams,
- .free_streams = xhci_free_streams,
- .add_endpoint = xhci_add_endpoint,
- .drop_endpoint = xhci_drop_endpoint,
- .endpoint_reset = xhci_endpoint_reset,
- .check_bandwidth = xhci_check_bandwidth,
- .reset_bandwidth = xhci_reset_bandwidth,
- .address_device = xhci_address_device,
- .update_hub_device = xhci_update_hub_device,
- .reset_device = xhci_discover_or_reset_device,
-
- /*
- * scheduling support
- */
- .get_frame_number = xhci_get_frame,
-
- /* Root hub support */
- .hub_control = xhci_hub_control,
- .hub_status_data = xhci_hub_status_data,
- .bus_suspend = xhci_bus_suspend,
- .bus_resume = xhci_bus_resume,
- /*
- * call back when device connected and addressed
- */
- .update_device = xhci_update_device,
- .set_usb2_hw_lpm = xhci_set_usb2_hardware_lpm,
- .enable_usb3_lpm_timeout = xhci_enable_usb3_lpm_timeout,
- .disable_usb3_lpm_timeout = xhci_disable_usb3_lpm_timeout,
- .find_raw_port_number = xhci_find_raw_port_number,
-};
-
-/*-------------------------------------------------------------------------*/
-
-/* PCI driver selection metadata; PCI hotplugging uses this */
-static const struct pci_device_id pci_ids[] = { {
- /* handle any USB 3.0 xHCI controller */
- PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_XHCI, ~0),
- .driver_data = (unsigned long) &xhci_pci_hc_driver,
- },
- { /* end: all zeroes */ }
-};
-MODULE_DEVICE_TABLE(pci, pci_ids);
-
-/* pci driver glue; this is a "new style" PCI driver module */
-static struct pci_driver xhci_pci_driver = {
- .name = (char *) hcd_name,
- .id_table = pci_ids,
-
- .probe = xhci_pci_probe,
- .remove = xhci_pci_remove,
- /* suspend and resume implemented later */
-
- .shutdown = usb_hcd_pci_shutdown,
-#ifdef CONFIG_PM_SLEEP
- .driver = {
- .pm = &usb_hcd_pci_pm_ops
- },
-#endif
-};
-
-int __init xhci_register_pci(void)
-{
- return pci_register_driver(&xhci_pci_driver);
-}
-
-void xhci_unregister_pci(void)
-{
- pci_unregister_driver(&xhci_pci_driver);
-}
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index df90fe5..3472816 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -10,11 +10,12 @@
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/
-
+#define __UBOOT__
+#ifndef __UBOOT__
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/slab.h>
-
+#endif
#include "xhci.h"

static void xhci_plat_quirks(struct device *dev, struct xhci_hcd *xhci)
@@ -81,7 +82,7 @@ static const struct hc_driver xhci_plat_xhci_driver = {
.bus_suspend = xhci_bus_suspend,
.bus_resume = xhci_bus_resume,
};
-
+#ifndef __UBOOT__
static int xhci_plat_probe(struct platform_device *pdev)
{
const struct hc_driver *driver;
@@ -203,3 +204,4 @@ void xhci_unregister_plat(void)
{
platform_driver_unregister(&usb_xhci_driver);
}
+#endif
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 1969c00..02fa41f 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -64,8 +64,18 @@
* endpoint rings; it generates events on the event ring for these.
*/

+#define __UBOOT__
+#ifndef __UBOOT__
#include <linux/scatterlist.h>
#include <linux/slab.h>
+#else
+
+#include <common.h>
+#include <linux/list.h> /* for struct list_head */
+#include <linux/usb/linux-compat.h>
+#include <linux/usb/usb-compat.h>
+#endif
+
#include "xhci.h"

static int handle_cmd_in_cmd_wait_list(struct xhci_hcd *xhci,
@@ -699,7 +709,9 @@ static void xhci_stop_watchdog_timer_in_irq(struct xhci_hcd *xhci,
* timer is running on another CPU, we don't decrement stop_cmds_pending
* (since we didn't successfully stop the watchdog timer).
*/
+#ifndef __UBOOT__
if (del_timer(&ep->stop_cmd_timer))
+#endif
ep->stop_cmds_pending--;
}

@@ -720,10 +732,12 @@ static void xhci_giveback_urb_in_irq(struct xhci_hcd *xhci,
if (urb_priv->td_cnt == urb_priv->length) {
if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs--;
+#ifndef __UBOOT__
if (xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs == 0) {
if (xhci->quirks & XHCI_AMD_PLL_FIX)
usb_amd_quirk_pll_enable();
}
+#endif
}
usb_hcd_unlink_urb_from_ep(hcd, urb);

@@ -1178,8 +1192,10 @@ static void xhci_complete_cmd_in_cmd_wait_list(struct xhci_hcd *xhci,
command->status = status;
list_del(&command->cmd_list);
if (command->completion)
+#ifndef __UBOOT__
complete(command->completion);
else
+#endif
xhci_free_command(xhci, command);
}

@@ -1354,6 +1370,7 @@ static int handle_stopped_cmd_ring(struct xhci_hcd *xhci,
static void handle_cmd_completion(struct xhci_hcd *xhci,
struct xhci_event_cmd *event)
{
+
int slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event->flags));
u64 cmd_dma;
dma_addr_t cmd_dequeue_dma;
@@ -1399,7 +1416,9 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
xhci->slot_id = slot_id;
else
xhci->slot_id = 0;
+#ifndef __UBOOT__
complete(&xhci->addr_dev);
+#endif
break;
case TRB_TYPE(TRB_DISABLE_SLOT):
if (xhci->devs[slot_id]) {
@@ -1453,18 +1472,24 @@ bandwidth_change:
xhci_dbg(xhci, "Completed config ep cmd\n");
xhci->devs[slot_id]->cmd_status =
GET_COMP_CODE(le32_to_cpu(event->status));
+#ifndef __UBOOT__
complete(&xhci->devs[slot_id]->cmd_completion);
+#endif
break;
case TRB_TYPE(TRB_EVAL_CONTEXT):
virt_dev = xhci->devs[slot_id];
if (handle_cmd_in_cmd_wait_list(xhci, virt_dev, event))
break;
xhci->devs[slot_id]->cmd_status = GET_COMP_CODE(le32_to_cpu(event->status));
+#ifndef __UBOOT__
complete(&xhci->devs[slot_id]->cmd_completion);
+#endif
break;
case TRB_TYPE(TRB_ADDR_DEV):
xhci->devs[slot_id]->cmd_status = GET_COMP_CODE(le32_to_cpu(event->status));
+#ifndef __UBOOT__
complete(&xhci->addr_dev);
+#endif
break;
case TRB_TYPE(TRB_STOP_RING):
handle_stopped_endpoint(xhci, xhci->cmd_ring->dequeue, event);
@@ -1677,11 +1702,17 @@ static void handle_port_status(struct xhci_hcd *xhci,
goto cleanup;
} else {
xhci_dbg(xhci, "resume HS port %d\n", port_id);
+#ifndef __UBOOT__
bus_state->resume_done[faked_port_index] = jiffies +
msecs_to_jiffies(20);
+#else
+ bus_state->resume_done[faked_port_index] = 20;
+#endif
set_bit(faked_port_index, &bus_state->resuming_ports);
+#ifndef __UBOOT__
mod_timer(&hcd->rh_timer,
bus_state->resume_done[faked_port_index]);
+#endif
/* Do the rest in GetPortStatus */
}
}
@@ -1960,11 +1991,13 @@ td_cleanup:
ret = 1;
if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs--;
+#ifndef __UBOOT__
if (xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs
== 0) {
if (xhci->quirks & XHCI_AMD_PLL_FIX)
usb_amd_quirk_pll_enable();
}
+#endif
}
}
}
@@ -2374,9 +2407,14 @@ static int handle_tx_event(struct xhci_hcd *xhci,
break;
if (xhci->quirks & XHCI_TRUST_TX_LENGTH)
trb_comp_code = COMP_SHORT_TX;
+#ifndef __UBOOT__
else
xhci_warn_ratelimited(xhci,
"WARN Successful completion on short TX: needs XHCI_TRUST_TX_LENGTH quirk?\n");
+#else
+ else
+ printf("WARN Successful completion on short TX: needs XHCI_TRUST_TX_LENGTH quirk?\n");
+#endif
case COMP_SHORT_TX:
break;
case COMP_STOP:
@@ -2657,12 +2695,13 @@ static int xhci_handle_event(struct xhci_hcd *xhci)
xhci->error_bitmask |= 1 << 2;
return 0;
}
-
+#ifndef __UBOOT__
/*
* Barrier between reading the TRB_CYCLE (valid) flag above and any
* speculative reads of the event's flags/data below.
*/
rmb();
+#endif
/* FIXME: Handle more event types. */
switch ((le32_to_cpu(event->event_cmd.flags) & TRB_TYPE_BITMASK)) {
case TRB_TYPE(TRB_COMPLETION):
@@ -2977,6 +3016,7 @@ static unsigned int count_sg_trbs_needed(struct xhci_hcd *xhci, struct urb *urb)
temp = urb->transfer_buffer_length;

num_trbs = 0;
+ /* sg_next is not defined yet need to define it */
for_each_sg(urb->sg, sg, num_sgs, i) {
unsigned int len = sg_dma_len(sg);

@@ -3056,7 +3096,9 @@ int xhci_queue_intr_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
* to set the polling interval (once the API is added).
*/
if (xhci_interval != ep_interval) {
+#ifndef __UBOOT__
if (printk_ratelimit())
+#endif
dev_dbg(&urb->dev->dev, "Driver uses different interval"
" (%d microframe%s) than xHCI "
"(%d microframe%s)\n",
@@ -3258,9 +3300,12 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
--num_sgs;
if (num_sgs == 0)
break;
+#ifndef __UBOOT__
+ /* TODO fix the scatterlist code here */
sg = sg_next(sg);
addr = (u64) sg_dma_address(sg);
this_sg_len = sg_dma_len(sg);
+#endif
} else {
addr += trb_buff_len;
}
@@ -3757,11 +3802,12 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
goto cleanup;
}
}
-
+#ifndef __UBOOT__
if (xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs == 0) {
if (xhci->quirks & XHCI_AMD_PLL_FIX)
usb_amd_quirk_pll_disable();
}
+#endif
xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs++;

giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id,
@@ -3845,7 +3891,9 @@ int xhci_queue_isoc_tx_prepare(struct xhci_hcd *xhci, gfp_t mem_flags,
* to set the polling interval (once the API is added).
*/
if (xhci_interval != ep_interval) {
+#ifndef __UBOOT__
if (printk_ratelimit())
+#endif
dev_dbg(&urb->dev->dev, "Driver uses different interval"
" (%d microframe%s) than xHCI "
"(%d microframe%s)\n",
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index b4aa79d..14dcf69 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -20,6 +20,8 @@
* Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

+#define __UBOOT__
+#ifndef __UBOOT__
#include <linux/pci.h>
#include <linux/irq.h>
#include <linux/log2.h>
@@ -27,6 +29,16 @@
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/dmi.h>
+#else
+
+#include <common.h>
+#include <linux/err.h>
+#include <linux/usb/linux-compat.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/usb-compat.h>
+#include <usb/lin_gadget_compat.h>
+
+#endif

#include "xhci.h"

@@ -428,10 +440,12 @@ static void compliance_mode_recovery(unsigned long arg)
usb_hcd_poll_rh_status(hcd);
}
}
-
+#ifndef __UBOOT__
+/* TODO needs implemenation */
if (xhci->port_status_u0 != ((1 << xhci->num_usb3_ports)-1))
mod_timer(&xhci->comp_mode_recovery_timer,
jiffies + msecs_to_jiffies(COMP_MODE_RCVRY_MSECS));
+#endif
}

/*
@@ -447,6 +461,8 @@ static void compliance_mode_recovery(unsigned long arg)
static void compliance_mode_recovery_timer_init(struct xhci_hcd *xhci)
{
xhci->port_status_u0 = 0;
+#ifndef __UBOOT__
+/* TODO needs timer implemenation */
init_timer(&xhci->comp_mode_recovery_timer);

xhci->comp_mode_recovery_timer.data = (unsigned long) xhci;
@@ -457,6 +473,7 @@ static void compliance_mode_recovery_timer_init(struct xhci_hcd *xhci)
set_timer_slack(&xhci->comp_mode_recovery_timer,
msecs_to_jiffies(COMP_MODE_RCVRY_MSECS));
add_timer(&xhci->comp_mode_recovery_timer);
+#endif
xhci_dbg(xhci, "Compliance mode recovery timer initialized\n");
}

@@ -468,6 +485,7 @@ static void compliance_mode_recovery_timer_init(struct xhci_hcd *xhci)
*/
static bool compliance_mode_recovery_timer_quirk_check(void)
{
+#ifndef __UBOOT__
const char *dmi_product_name, *dmi_sys_vendor;

dmi_product_name = dmi_get_system_info(DMI_PRODUCT_NAME);
@@ -483,7 +501,7 @@ static bool compliance_mode_recovery_timer_quirk_check(void)
strstr(dmi_product_name, "Z820") ||
strstr(dmi_product_name, "Z1 Workstation"))
return true;
-
+#endif
return false;
}

@@ -738,10 +756,10 @@ void xhci_stop(struct usb_hcd *hcd)
xhci_dbg(xhci, "%s: compliance mode recovery timer deleted\n",
__func__);
}
-
+#ifndef __UBOOT__
if (xhci->quirks & XHCI_AMD_PLL_FIX)
usb_amd_dev_put();
-
+#endif
xhci_dbg(xhci, "// Disabling event ring interrupts\n");
temp = xhci_readl(xhci, &xhci->op_regs->status);
xhci_writel(xhci, temp & ~STS_EINT, &xhci->op_regs->status);
@@ -768,10 +786,10 @@ void xhci_stop(struct usb_hcd *hcd)
void xhci_shutdown(struct usb_hcd *hcd)
{
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-
+#ifndef __UBOOT__
if (xhci->quirks & XHCI_SPURIOUS_REBOOT)
usb_disable_xhci_ports(to_pci_dev(hcd->self.controller));
-
+#endif
spin_lock_irq(&xhci->lock);
xhci_halt(xhci);
spin_unlock_irq(&xhci->lock);
@@ -1269,8 +1287,10 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
ep_index = xhci_get_endpoint_index(&urb->ep->desc);

if (!HCD_HW_ACCESSIBLE(hcd)) {
+#ifndef __UBOOT__
if (!in_interrupt())
xhci_dbg(xhci, "urb submitted during PCI suspend\n");
+#endif
ret = -ESHUTDOWN;
goto exit;
}
@@ -1531,9 +1551,11 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
if (!(ep->ep_state & EP_HALT_PENDING)) {
ep->ep_state |= EP_HALT_PENDING;
ep->stop_cmds_pending++;
+#ifndef __UBOOT__
ep->stop_cmd_timer.expires = jiffies +
XHCI_STOP_EP_CMD_TIMEOUT * HZ;
add_timer(&ep->stop_cmd_timer);
+#endif
xhci_queue_stop_endpoint(xhci, urb->dev->slot_id, ep_index, 0);
xhci_ring_cmd_db(xhci);
}
@@ -2541,10 +2563,14 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci,
bool ctx_change, bool must_succeed)
{
int ret;
+#ifndef __UBOOT__
int timeleft;
+#endif
unsigned long flags;
struct xhci_container_ctx *in_ctx;
+#ifndef __UBOOT__
struct completion *cmd_completion;
+#endif
u32 *cmd_status;
struct xhci_virt_device *virt_dev;
union xhci_trb *cmd_trb;
@@ -2573,7 +2599,7 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci,
xhci_warn(xhci, "Not enough bandwidth\n");
return -ENOMEM;
}
-
+#ifndef __UBOOT__
if (command) {
cmd_completion = command->completion;
cmd_status = &command->status;
@@ -2593,6 +2619,11 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci,
}
init_completion(cmd_completion);

+#endif
+#ifndef __UBOOT__
+ init_completion(cmd_completion);
+#endif
+
cmd_trb = xhci->cmd_ring->dequeue;
if (!ctx_change)
ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma,
@@ -2611,7 +2642,7 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci,
}
xhci_ring_cmd_db(xhci);
spin_unlock_irqrestore(&xhci->lock, flags);
-
+#ifndef __UBOOT__
/* Wait for the configure endpoint command to complete */
timeleft = wait_for_completion_interruptible_timeout(
cmd_completion,
@@ -2628,7 +2659,7 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci,
return ret;
return -ETIME;
}
-
+#endif
if (!ctx_change)
ret = xhci_configure_endpoint_result(xhci, udev, cmd_status);
else
@@ -2936,9 +2967,11 @@ static void xhci_calculate_streams_entries(struct xhci_hcd *xhci,
unsigned int *num_streams, unsigned int *num_stream_ctxs)
{
unsigned int max_streams;
-
- /* The stream context array size must be a power of two */
+#ifndef __UBOOT__
+/* TODO redefine this
+ The stream context array size must be a power of two */
*num_stream_ctxs = roundup_pow_of_two(*num_streams);
+#endif
/*
* Find out how many primary stream array entries the host controller
* supports. Later we may use secondary stream arrays (similar to 2nd
@@ -3321,7 +3354,9 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev)
unsigned int slot_id;
struct xhci_virt_device *virt_dev;
struct xhci_command *reset_device_cmd;
+#ifndef __UBOOT__
int timeleft;
+#endif
int last_freed_endpoint;
struct xhci_slot_ctx *slot_ctx;
int old_active_eps = 0;
@@ -3397,7 +3432,8 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev)
}
xhci_ring_cmd_db(xhci);
spin_unlock_irqrestore(&xhci->lock, flags);
-
+#ifndef __UBOOT__
+/* TODO */
/* Wait for the Reset Device command to finish */
timeleft = wait_for_completion_interruptible_timeout(
reset_device_cmd->completion,
@@ -3415,7 +3451,7 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev)
ret = -ETIME;
goto command_cleanup;
}
-
+#endif
/* The Reset Device command can't fail, according to the 0.95/0.96 spec,
* unless we tried to reset a slot ID that wasn't enabled,
* or the device wasn't in the addressed or configured state.
@@ -3572,7 +3608,9 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
{
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
unsigned long flags;
+#ifndef __UBOOT__
int timeleft;
+#endif
int ret;
union xhci_trb *cmd_trb;

@@ -3586,7 +3624,7 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
}
xhci_ring_cmd_db(xhci);
spin_unlock_irqrestore(&xhci->lock, flags);
-
+#ifndef __UBOOT__
/* XXX: how much time for xHC slot assignment? */
timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev,
XHCI_CMD_DEFAULT_TIMEOUT);
@@ -3596,7 +3634,7 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
/* cancel the enable slot request */
return xhci_cancel_cmd(xhci, NULL, cmd_trb);
}
-
+#endif
if (!xhci->slot_id) {
xhci_err(xhci, "Error while assigning device slot ID\n");
return 0;
@@ -3648,7 +3686,10 @@ disable_slot:
int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
{
unsigned long flags;
+#ifndef __UBOOT__
int timeleft;
+
+#endif
struct xhci_virt_device *virt_dev;
int ret = 0;
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
@@ -3663,8 +3704,11 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
}

virt_dev = xhci->devs[udev->slot_id];
-
+#ifndef __UBOOT__
if (WARN_ON(!virt_dev)) {
+#else
+ if (!virt_dev) {
+#endif
/*
* In plug/unplug torture test with an NEC controller,
* a zero-dereference was observed once due to virt_dev = 0.
@@ -3704,7 +3748,7 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
}
xhci_ring_cmd_db(xhci);
spin_unlock_irqrestore(&xhci->lock, flags);
-
+#ifndef __UBOOT__
/* ctrl tx can take up to 5 sec; XXX: need more time for xHC? */
timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev,
XHCI_CMD_DEFAULT_TIMEOUT);
@@ -3721,7 +3765,7 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
return ret;
return -ETIME;
}
-
+#endif
switch (virt_dev->cmd_status) {
case COMP_CTX_STATE:
case COMP_EBADSLT:
@@ -4723,6 +4767,7 @@ MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_LICENSE("GPL");

+#ifndef __UBOOT__
static int __init xhci_hcd_init(void)
{
int retval;
@@ -4767,3 +4812,4 @@ static void __exit xhci_hcd_cleanup(void)
xhci_unregister_plat();
}
module_exit(xhci_hcd_cleanup);
+#endif
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 29c978e..330562a 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -23,14 +23,26 @@
#ifndef __LINUX_XHCI_HCD_H
#define __LINUX_XHCI_HCD_H

+#define __UBOOT__
+#ifndef __UBOOT__
#include <linux/usb.h>
#include <linux/timer.h>
#include <linux/kernel.h>
#include <linux/usb/hcd.h>
+#else
+
+#include <asm/io.h>
+#include <usb.h>
+#include <linux/usb/hcd.h>
+
+#endif

/* Code sharing between pci-quirks and xhci hcd */
-#include "xhci-ext-caps.h"
+#include "xhci-ext-caps.h"
+
+#ifndef __UBOOT__
#include "pci-quirks.h"
+#endif

/* xHCI PCI Configuration Registers */
#define XHCI_SBRN_OFFSET (0x60)
@@ -749,8 +761,10 @@ struct xhci_stream_info {
struct xhci_stream_ctx *stream_ctx_array;
unsigned int num_stream_ctxs;
dma_addr_t ctx_array_dma;
+#ifndef __UBOOT__
/* For mapping physical TRB addresses to segments in stream rings */
struct radix_tree_root trb_address_map;
+#endif
struct xhci_command *free_streams_command;
};

@@ -913,6 +927,7 @@ struct xhci_virt_device {
#define XHCI_MAX_RINGS_CACHED 31
struct xhci_virt_ep eps[31];
struct completion cmd_completion;
+
/* Status of the last command issued for this device */
u32 cmd_status;
struct list_head cmd_list;
@@ -1447,9 +1462,10 @@ struct xhci_hcd {
struct xhci_scratchpad *scratchpad;
/* Store LPM test failed devices' information */
struct list_head lpm_failed_devs;
-
+#ifndef __UBOOT__
/* slot enabling and address device helpers */
struct completion addr_dev;
+#endif
int slot_id;
/* For USB 3.0 LPM enable/disable. */
struct xhci_command *lpm_command;
diff --git a/include/asm-generic/scatterlist.h b/include/asm-generic/scatterlist.h
new file mode 100644
index 0000000..5de0735
--- /dev/null
+++ b/include/asm-generic/scatterlist.h
@@ -0,0 +1,34 @@
+#ifndef __ASM_GENERIC_SCATTERLIST_H
+#define __ASM_GENERIC_SCATTERLIST_H
+
+#include <linux/types.h>
+
+struct scatterlist {
+#ifdef CONFIG_DEBUG_SG
+ unsigned long sg_magic;
+#endif
+ unsigned long page_link;
+ unsigned int offset;
+ unsigned int length;
+ dma_addr_t dma_address;
+#ifdef CONFIG_NEED_SG_DMA_LENGTH
+ unsigned int dma_length;
+#endif
+};
+
+/*
+ * These macros should be used after a dma_map_sg call has been done
+ * to get bus addresses of each of the SG entries and their lengths.
+ * You should only work with the number of sg entries pci_map_sg
+ * returns, or alternatively stop on the first sg_dma_len(sg) which
+ * is 0.
+ */
+#define sg_dma_address(sg) ((sg)->dma_address)
+
+#ifdef CONFIG_NEED_SG_DMA_LENGTH
+#define sg_dma_len(sg) ((sg)->dma_length)
+#else
+#define sg_dma_len(sg) ((sg)->length)
+#endif
+
+#endif /* __ASM_GENERIC_SCATTERLIST_H */
diff --git a/include/configs/omap5_common.h b/include/configs/omap5_common.h
index 1df553e..b7c3e9f 100644
--- a/include/configs/omap5_common.h
+++ b/include/configs/omap5_common.h
@@ -104,6 +104,7 @@
#define CONFIG_USB_DWC3_DUAL_ROLE
#define CONFIG_USB_DWC3_OMAP
#define CONFIG_USB_DWC3_HOST
+#define CONFIG_USB_XHCI

/* Flash */
#define CONFIG_SYS_NO_FLASH
diff --git a/include/linux/usb/ch11.h b/include/linux/usb/ch11.h
index 7692dc6..2eac74c 100644
--- a/include/linux/usb/ch11.h
+++ b/include/linux/usb/ch11.h
@@ -11,6 +11,11 @@

#include <linux/types.h> /* __u8 etc */

+#define __UBOOT__
+#ifdef __UBOOT__
+#include <linux/usb/usb-compat.h>
+#endif
+
/*
* Hub request types
*/
@@ -240,6 +245,14 @@ struct usb_hub_descriptor {
__le16 DeviceRemovable;
} __attribute__ ((packed)) ss;
} u;
+#ifdef __UBOOT__
+ /* For uBoot backwards compatibility */
+ unsigned char bLength;
+ unsigned char DeviceRemovable[(USB_MAXCHILDREN+1+7)/8];
+ unsigned char PortPowerCtrlMask[(USB_MAXCHILDREN+1+7)/8];
+ /* DeviceRemovable and PortPwrCtrlMask want to be variable-length
+ bitmaps that hold max 255 entries. (bit0 is ignored) */
+#endif
} __attribute__ ((packed));

/* port indicator status selectors, tables 11-7 and 11-25 */
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index f5f5c7d..df68955 100644
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
@@ -19,9 +19,14 @@
#ifndef __USB_CORE_HCD_H
#define __USB_CORE_HCD_H

+#define __UBOOT__
#ifdef __KERNEL__

+#ifndef __UBOOT__
#include <linux/rwsem.h>
+#else
+#include <usb.h>
+#endif

#define MAX_TOPO_LEVEL 6

@@ -73,8 +78,9 @@ struct usb_hcd {
* housekeeping
*/
struct usb_bus self; /* hcd is-a bus */
+#ifndef __UBOOT__
struct kref kref; /* reference counter */
-
+#endif
const char *product_desc; /* product/vendor string */
int speed; /* Speed for this roothub.
* May be different from
@@ -135,8 +141,10 @@ struct usb_hcd {

unsigned int irq; /* irq allocated */
void __iomem *regs; /* device memory/io */
+#ifndef __UBOOT__
resource_size_t rsrc_start; /* memory/io resource start */
resource_size_t rsrc_len; /* memory/io resource length */
+#endif
unsigned power_budget; /* in mA, 0 = no limit */

/* bandwidth_mutex should be taken before adding or removing
diff --git a/include/linux/usb/linux-compat.h b/include/linux/usb/linux-compat.h
index 9850f44..81a099b 100644
--- a/include/linux/usb/linux-compat.h
+++ b/include/linux/usb/linux-compat.h
@@ -27,6 +27,8 @@
#include <linux/list.h>
#include <linux/compat.h>
#include <asm-generic/errno.h>
+#include <asm-generic/scatterlist.h>
+

#define __init
#define __devinit
@@ -44,6 +46,7 @@ struct work_struct {};

struct timer_list {};
struct notifier_block {};
+typedef int wait_queue_head_t;

typedef unsigned long dmaaddr_t;
#define BUS_ID_SIZE 20
@@ -59,6 +62,24 @@ struct device {
};

/**
+ * clamp_val - return a value clamped to a given range using val's type
+ * @val: current value
+ * @min: minimum allowable value
+ * @max: maximum allowable value
+ *
+ * This macro does no typechecking and uses temporary variables of whatever
+ * type the input argument 'val' is. This is useful when val is an unsigned
+ * type and min and max are literals that will otherwise be assigned a signed
+ * integer type.
+ */
+#define clamp_val(val, min, max) ({ \
+ typeof(val) __val = (val); \
+ typeof(val) __min = (min); \
+ typeof(val) __max = (max); \
+ __val = __val < __min ? __min: __val; \
+ __val > __max ? __max: __val; })
+
+/**
* struct device_driver - The basic device driver structure
* @name: Name of the device driver.
* @bus: The bus which the device of this driver belongs to.
@@ -79,6 +100,26 @@ struct device_driver {

};

+
+/*
+ * struct completion - structure used to maintain state for a "completion"
+ *
+ * This is the opaque structure used to maintain the state for a "completion".
+ * Completions currently use a FIFO to queue threads that have to wait for
+ * the "completion" event.
+ *
+ * See also: complete(), wait_for_completion() (and friends _timeout,
+ * _interruptible, _interruptible_timeout, and _killable), init_completion(),
+ * and macros DECLARE_COMPLETION(), DECLARE_COMPLETION_ONSTACK(), and
+ * INIT_COMPLETION().
+ */
+struct completion {
+ unsigned int done;
+#ifndef __UBOOT__
+ wait_queue_head_t wait;
+#endif
+};
+
/*
* Loop over each sg element, following the pointer to a new list if necessary
*/
@@ -103,6 +144,8 @@ struct device_driver {
printf(fmt, ##args)
#define dev_err(dev, fmt, args...) \
printf(fmt, ##args)
+#define dev_warn(dev, fmt, args...) \
+ printf(fmt, ##args)
#define printk printf

#define WARN(condition, fmt, args...) ({ \
@@ -123,6 +166,8 @@ struct device_driver {
/* common */
#define spin_lock_init(...)
#define spin_lock(...)
+#define spin_lock_irq(...)
+#define spin_unlock_irq(...)
#define spin_lock_irqsave(lock, flags) do { debug("%lu\n", flags); } while (0)
#define spin_unlock(...)
#define spin_unlock_irqrestore(lock, flags) do {flags = 0; } while (0)
@@ -134,6 +179,8 @@ struct device_driver {
#define mutex_unlock(...)

#define GFP_KERNEL 0
+#define GFP_ATOMIC 0x20u
+#define GFP_NOIO 0x10u

#define IRQ_HANDLED 1

diff --git a/include/linux/usb/usb-compat.h b/include/linux/usb/usb-compat.h
index a46d1e6..e99f83b 100644
--- a/include/linux/usb/usb-compat.h
+++ b/include/linux/usb/usb-compat.h
@@ -1529,9 +1529,9 @@ struct urb {
unsigned int transfer_flags; /* (in) URB_SHORT_NOT_OK | ...*/
void *transfer_buffer; /* (in) associated data buffer */
dma_addr_t transfer_dma; /* (in) dma addr for transfer_buffer */
-#ifndef __UBOOT__
+
struct scatterlist *sg; /* (in) scatter gather buffer list */
-#endif
+
int num_mapped_sgs; /* (internal) mapped sg entries */
int num_sgs; /* (in) number of entries in the sg list */
u32 transfer_buffer_length; /* (in) data buffer length */
diff --git a/include/usb.h b/include/usb.h
index 0598972..6a64c5a 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -28,6 +28,7 @@

#include <usb_defs.h>
#include <linux/usb/ch9.h>
+#include <linux/usb/ch11.h>
#include <linux/usb/usb-compat.h>

/*
@@ -214,15 +215,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate);
default_pipe(dev) | \
USB_DIR_IN)

-/* The D0/D1 toggle bits */
-#define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> ep) & 1)
-#define usb_dotoggle(dev, ep, out) ((dev)->toggle[out] ^= (1 << ep))
-#define usb_settoggle(dev, ep, out, bit) ((dev)->toggle[out] = \
- ((dev)->toggle[out] & \
- ~(1 << ep)) | ((bit) << ep))
-
/* Endpoint halt control/status */
-#define usb_endpoint_out(ep_dir) (((ep_dir >> 7) & 1) ^ 1)
#define usb_endpoint_halt(dev, ep, out) ((dev)->halted[out] |= (1 << (ep)))
#define usb_endpoint_running(dev, ep, out) ((dev)->halted[out] &= ~(1 << (ep)))
#define usb_endpoint_halted(dev, ep, out) ((dev)->halted[out] & (1 << (ep)))
@@ -244,31 +237,6 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate);
/*************************************************************************
* Hub Stuff
*/
-struct usb_port_status {
- unsigned short wPortStatus;
- unsigned short wPortChange;
-} __attribute__ ((packed));
-
-struct usb_hub_status {
- unsigned short wHubStatus;
- unsigned short wHubChange;
-} __attribute__ ((packed));
-
-
-/* Hub descriptor */
-struct usb_hub_descriptor {
- unsigned char bLength;
- unsigned char bDescriptorType;
- unsigned char bNbrPorts;
- unsigned short wHubCharacteristics;
- unsigned char bPwrOn2PwrGood;
- unsigned char bHubContrCurrent;
- unsigned char DeviceRemovable[(USB_MAXCHILDREN+1+7)/8];
- unsigned char PortPowerCtrlMask[(USB_MAXCHILDREN+1+7)/8];
- /* DeviceRemovable and PortPwrCtrlMask want to be variable-length
- bitmaps that hold max 255 entries. (bit0 is ignored) */
-} __attribute__ ((packed));
-

struct usb_hub_device {
struct usb_device *pusb_dev;
--
1.7.9.5