[RFC 05/15] xhci: Change hcd_priv be a pointer.

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

 



Instead of allocating space for the whole xhci_hcd structure at the end of
usb_hcd, make the USB core allocate enough space for a pointer to the
xhci_hcd structure.  This will make it easy to share the xhci_hcd
structure across the two roothubs (the USB 3.0 usb_hcd and the USB 2.0
usb_hcd).  This method of sharing the xhci_hcd pointer is better than
modifying all xhci_functions to check whether the passed in usb_hcd
contains the real xhci_hcd.

Signed-off-by: Sarah Sharp <sarah.a.sharp@xxxxxxxxxxxxxxx>
---
 drivers/usb/host/xhci-pci.c |   22 +++++++++++++++++-----
 drivers/usb/host/xhci.c     |    2 ++
 drivers/usb/host/xhci.h     |    5 +++--
 3 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index bb668a8..b3ed661 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -57,6 +57,12 @@ static int xhci_pci_setup(struct usb_hcd *hcd)
 
 	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;
+
 	xhci->cap_regs = hcd->regs;
 	xhci->op_regs = hcd->regs +
 		HC_LENGTH(xhci_readl(xhci, &xhci->cap_regs->hc_capbase));
@@ -85,13 +91,13 @@ static int xhci_pci_setup(struct usb_hcd *hcd)
 	/* Make sure the HC is halted. */
 	retval = xhci_halt(xhci);
 	if (retval)
-		return retval;
+		goto error;
 
 	xhci_dbg(xhci, "Resetting HCD\n");
 	/* Reset the internal HC memory state and registers. */
 	retval = xhci_reset(xhci);
 	if (retval)
-		return retval;
+		goto error;
 	xhci_dbg(xhci, "Reset complete\n");
 
 	temp = xhci_readl(xhci, &xhci->cap_regs->hcc_params);
@@ -106,14 +112,20 @@ static int xhci_pci_setup(struct usb_hcd *hcd)
 	/* Initialize HCD and host controller data structures. */
 	retval = xhci_init(hcd);
 	if (retval)
-		return retval;
+		goto error;
 	xhci_dbg(xhci, "Called HCD init\n");
 
 	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 */
-	return xhci_pci_reinit(xhci, pdev);
+	retval = xhci_pci_reinit(xhci, pdev);
+	if (!retval)
+		return retval;
+
+error:
+	kfree(xhci);
+	return retval;
 }
 
 #ifdef CONFIG_PM
@@ -143,7 +155,7 @@ static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated)
 static const struct hc_driver xhci_pci_hc_driver = {
 	.description =		hcd_name,
 	.product_desc =		"xHCI Host Controller",
-	.hcd_priv_size =	sizeof(struct xhci_hcd),
+	.hcd_priv_size =	sizeof(struct xhci_hcd *),
 
 	/*
 	 * generic hardware linkage
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index ff65ea6..7577876 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -519,6 +519,8 @@ void xhci_stop(struct usb_hcd *hcd)
 	xhci_mem_cleanup(xhci);
 	xhci_dbg(xhci, "xhci_stop completed - status = %x\n",
 		    xhci_readl(xhci, &xhci->op_regs->status));
+	kfree(xhci);
+	*((struct xhci_hcd **) hcd->hcd_priv) = NULL;
 }
 
 /*
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 3658564..29747a1 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1144,6 +1144,7 @@ struct s3_save {
 
 /* There is one ehci_hci structure per controller */
 struct xhci_hcd {
+	struct usb_hcd *main_hcd;
 	/* glue to PCI and HCD framework */
 	struct xhci_cap_regs __iomem *cap_regs;
 	struct xhci_op_regs __iomem *op_regs;
@@ -1238,12 +1239,12 @@ struct xhci_hcd {
 /* convert between an HCD pointer and the corresponding EHCI_HCD */
 static inline struct xhci_hcd *hcd_to_xhci(struct usb_hcd *hcd)
 {
-	return (struct xhci_hcd *) (hcd->hcd_priv);
+	return *((struct xhci_hcd **) (hcd->hcd_priv));
 }
 
 static inline struct usb_hcd *xhci_to_hcd(struct xhci_hcd *xhci)
 {
-	return container_of((void *) xhci, struct usb_hcd, hcd_priv);
+	return xhci->main_hcd;
 }
 
 #ifdef CONFIG_USB_XHCI_HCD_DEBUGGING
-- 
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