summaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-mem.c
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@linux.intel.com>2009-04-27 19:53:42 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2009-06-15 21:44:48 -0700
commita74588f94655263b96dacbbf14aac0958d8b7409 (patch)
tree0c4a53d0e6aa00fe9226c9c915f22da9171043ad /drivers/usb/host/xhci-mem.c
parent0ebbab37422315a5d0cb29792271085bafdf38c0 (diff)
USB: xhci: Device context array allocation.
Instead of keeping a "frame list" like older host controllers, the xHCI host controller keeps internal representations of the USB devices, with a transfer ring per endpoint. The host controller queues Transfer Request Blocks (TRBs) to the endpoint ring, and then "rings the doorbell" for that device. The host controller processes the transfer, places a transfer completion event on the event ring, and interrupts the system. The device context base address array must be allocated by the xHCI host controller driver, along with the device contexts it points to. Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/xhci-mem.c')
-rw-r--r--drivers/usb/host/xhci-mem.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 7cf15ca854b..be5a05b2021 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -220,6 +220,12 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
dma_pool_destroy(xhci->segment_pool);
xhci->segment_pool = NULL;
xhci_dbg(xhci, "Freed segment pool\n");
+ xhci_writel(xhci, 0, &xhci->op_regs->dcbaa_ptr[1]);
+ xhci_writel(xhci, 0, &xhci->op_regs->dcbaa_ptr[0]);
+ if (xhci->dcbaa)
+ pci_free_consistent(pdev, sizeof(*xhci->dcbaa),
+ xhci->dcbaa, xhci->dcbaa->dma);
+ xhci->dcbaa = NULL;
xhci->page_size = 0;
xhci->page_shift = 0;
}
@@ -263,6 +269,21 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
xhci_writel(xhci, val, &xhci->op_regs->config_reg);
/*
+ * Section 5.4.8 - doorbell array must be
+ * "physically contiguous and 64-byte (cache line) aligned".
+ */
+ xhci->dcbaa = pci_alloc_consistent(to_pci_dev(dev),
+ sizeof(*xhci->dcbaa), &dma);
+ if (!xhci->dcbaa)
+ goto fail;
+ memset(xhci->dcbaa, 0, sizeof *(xhci->dcbaa));
+ xhci->dcbaa->dma = dma;
+ xhci_dbg(xhci, "// Setting device context base array address to 0x%x\n",
+ xhci->dcbaa->dma);
+ xhci_writel(xhci, (u32) 0, &xhci->op_regs->dcbaa_ptr[1]);
+ xhci_writel(xhci, dma, &xhci->op_regs->dcbaa_ptr[0]);
+
+ /*
* Initialize the ring segment pool. The ring must be a contiguous
* structure comprised of TRBs. The TRBs must be 16 byte aligned,
* however, the command ring segment needs 64-byte aligned segments,