Make sure that the xhci_hcd pointer is shared across the two usb_hcd structures. The xhci_hcd structure should only be deallocated when xhci_stop() is called with the USB 3.0 roothub. Set the xhci_hcd pointer in the USB 2.0 roothub to null when xhci_stop() is called with that. Make sure to set the sg_tablesize and DMA mask for both usb_hcd structures. Signed-off-by: Sarah Sharp <sarah.a.sharp@xxxxxxxxxxxxxxx> --- drivers/usb/host/xhci-pci.c | 26 ++++++++++++++++++++------ drivers/usb/host/xhci.c | 5 +++++ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index b3ed661..f0ea271 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -50,18 +50,32 @@ static int xhci_pci_reinit(struct xhci_hcd *xhci, struct pci_dev *pdev) /* called during probe() after chip reset completes */ static int xhci_pci_setup(struct usb_hcd *hcd) { - struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct xhci_hcd *xhci; struct pci_dev *pdev = to_pci_dev(hcd->self.controller); int retval; u32 temp; hcd->self.sg_tablesize = TRBS_PER_SEGMENT - 2; - xhci = kzalloc(sizeof(struct xhci_hcd), GFP_KERNEL); - if (!xhci) - return -ENOMEM; - *((struct xhci_hcd **) hcd->hcd_priv) = xhci; - xhci->main_hcd = hcd; + if (usb_hcd_is_main_hcd(hcd)) { + xhci = kzalloc(sizeof(struct xhci_hcd), GFP_KERNEL); + if (!xhci) + return -ENOMEM; + *((struct xhci_hcd **) hcd->hcd_priv) = xhci; + xhci->main_hcd = hcd; + } else { + xhci = hcd_to_xhci(hcd->shared_hcd); + *((struct xhci_hcd **) hcd->hcd_priv) = xhci; + + temp = xhci_readl(xhci, &xhci->cap_regs->hcc_params); + if (HCC_64BIT_ADDR(temp)) { + xhci_dbg(xhci, "Enabling 64-bit DMA addresses.\n"); + dma_set_mask(hcd->self.controller, DMA_BIT_MASK(64)); + } else { + dma_set_mask(hcd->self.controller, DMA_BIT_MASK(32)); + } + return 0; + } xhci->cap_regs = hcd->regs; xhci->op_regs = hcd->regs + diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 7577876..cb4caf6 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -495,6 +495,11 @@ void xhci_stop(struct usb_hcd *hcd) u32 temp; struct xhci_hcd *xhci = hcd_to_xhci(hcd); + if (!usb_hcd_is_main_hcd(hcd)) { + *((struct xhci_hcd **) hcd->hcd_priv) = NULL; + return; + } + spin_lock_irq(&xhci->lock); xhci_halt(xhci); xhci_reset(xhci); -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html