On Thu, 30 Dec 2010, Sarah Sharp wrote: > Introduce the notion of a PCI device that may be associated with more than > one USB host controller driver (struct usb_hcd). This patch is the start > of the work to separate the xHCI host controller into two roothubs: a USB > 3.0 roothub with SuperSpeed-only ports, and a USB 2.0 roothub with > HS/FS/LS ports. > > One usb_hcd structure is designated to be the "primary HCD", and a pointer > is added to the usb_hcd structure to keep track of that. A new function > call, usb_hcd_is_primary_hcd() is added to check whether the USB hcd is > marked as the primary HCD (or if it is not part of a roothub pair). To > allow the USB core and xHCI driver to access either roothub in a pair, a > "shared_hcd" pointer is added to the usb_hcd structure. I'm not sure this "shared_hcd" pointer is needed. Does it ever get used in a non-trivial way? > Add a new function, usb_create_shared_hcd(), that does roothub allocation > for paired roothubs. It will act just like usb_create_hcd() did if the > primary_hcd pointer argument is NULL. If it is passed a non-NULL > primary_hcd pointer, it sets usb_hcd->shared_hcd and usb_hcd->primary_hcd > fields. It will also skip the bandwidth_mutex allocation, and set the > secondary hcd's bandwidth_mutex pointer to the primary HCD's mutex. > > IRQs are only allocated once for the primary roothub. > > Introduce a new usb_hcd driver flag that indicates the host controller > driver wants to create two roothubs. If the HCD_SHARED flag is set, then > the USB core PCI probe methods will allocate a second roothub, and make > sure that second roothub gets freed during rmmod and in initialization > error paths. This doesn't seem like the right approach. The creation of a secondary usb_hcd should be handled by the driver that needs it; it isn't such a common activity that we need to implement it in the USB core. In particular, hcd-pci.c shouldn't be changed. > If the driver that wants to create two roothubs is an xHCI driver, the > roothub that is allocated last is marked as the USB 2.0 roothub. Didn't we agree earlier that xhci-hcd needs to register its USB-2 root hub first? > diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c > index 79bad2c..a061c31 100644 > --- a/drivers/usb/core/hcd.c > +++ b/drivers/usb/core/hcd.c > @@ -2184,13 +2195,49 @@ struct usb_hcd *usb_create_hcd (const struct hc_driver *driver, > "USB Host Controller"; > return hcd; > } > +EXPORT_SYMBOL_GPL(usb_create_shared_hcd); > + > +/** > + * usb_create_hcd - create and initialize an HCD structure > + * @driver: HC driver that will use this hcd > + * @dev: device for this HC, stored in hcd->self.controller > + * @bus_name: value to store in hcd->self.bus_name > + * @shared_hcd: a pointer to the usb_hcd structure that is sharing the > + * PCI device. Used for allocating two usb_hcd structures > + * under one xHCI host controller PCI device (a USB 2.0 bus > + * and a USB 3.0 bus). This last argument doesn't really exist, as you can see below. > + * Context: !in_interrupt() > + * > + * Allocate a struct usb_hcd, with extra space at the end for the > + * HC driver's private data. Initialize the generic members of the > + * hcd structure. > + * > + * If memory is unavailable, returns NULL. > + */ > +struct usb_hcd *usb_create_hcd(const struct hc_driver *driver, > + struct device *dev, const char *bus_name) > +{ > + return usb_create_shared_hcd(driver, dev, bus_name, NULL); > +} > EXPORT_SYMBOL_GPL(usb_create_hcd); > @@ -2209,6 +2256,14 @@ void usb_put_hcd (struct usb_hcd *hcd) > } > EXPORT_SYMBOL_GPL(usb_put_hcd); > > +inline int usb_hcd_is_primary_hcd(struct usb_hcd *hcd) > +{ > + if (!hcd->primary_hcd) > + return 1; > + return hcd == hcd->primary_hcd; Do you really need to set hcd->primary_hcd to point to hcd itself? My inclination would be to leave it unset. Alan Stern -- 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