[RFC 11/15] xhci: Prepare driver for multiple usb_hcds.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux