Re: [RFC 10/22] usb: Make core allocate resources per PCI-device.

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

 



On Mon, 3 Jan 2011, Sarah Sharp wrote:

> > I'm not sure this "shared_hcd" pointer is needed.  Does it ever get 
> > used in a non-trivial way?
> 
> I'm not sure what you mean by "non-trivial".  The USB core needs it, for
> instance, to make sure that both buses are suspended before suspending
> the PCI device:
> 
>         if (hcd->driver->pci_suspend) {
>                 /* Optimization: Don't suspend if a root-hub wakeup is
>                  * pending and it would cause the HCD to wake up anyway.
>                  */
>                 if (do_wakeup && HCD_WAKEUP_PENDING(hcd))
>                         return -EBUSY;
>                 if (do_wakeup && hcd->shared_hcd &&
>                                 HCD_WAKEUP_PENDING(hcd->shared_hcd))
>                         return -EBUSY;
>                 retval = hcd->driver->pci_suspend(hcd, do_wakeup);

We shouldn't have to change this.  It's not necessary to check that the
root hubs are suspended; the PM core is now smart enough never to
suspend a controller if the root hubs aren't already suspended.  It
isn't even really necessary to avoid races between suspending the
controller and remote wakeup of the root hubs; the code you see above
is merely an optimization.  It could be removed (all but the first and 
last lines).

Regardless, I'm pretty sure that having a "shared_hcd" pointer isn't
the way to go.  Originally we assumed that one controller = one bus.  
xHCI has broken that assumption; it seems awfully foolish now to make
the assumption that one controller = one or two buses.

One possibility would be to allow each hcd to have a list of buses.  
But I think this just adds unnecessary complexity.  In addition, the
dividing line between a controller and a bus isn't clear.  For example,
xHCI uses a single IRQ line to report events on either of the buses,
but it's easy to imagine a controller using a different IRQ for each
bus.

> Since there's only one usb_hcd stored in the PCI device pointer, there
> needs to be a way to access the second usb_hcd.  Other functions also
> need to use shared_hcd to set various flags that are part of the usb_hcd
> state.  Do you have a different suggestion as to how to do that?

What other functions?  My suggestion is that we figure out a way to 
change them so that they don't need to look at the secondary hcd or to 
remove them entirely.

> I have thought about your suggestion to make the xHCI driver call
> usb_create_shared_hcd() instead of having the USB PCI layer do the
> allocation and registering of the second roothub.  However, I wanted to
> ensure that the shared_hcd pointer was set before the first usb_hcd was
> registered, and I don't think I can do that if I push the call into the
> xHCI driver.

You don't have to worry about it if there is no shared_hcd pointer.  
:-)

> I need to set the shared_hcd pointer before the first usb_hcd is
> registered so that, for example, the PCI device wouldn't get suspended
> until the initialization process completed for both roothubs and both
> buses are suspended.

That can't happen; devices are never suspended while being probed.

>  Things like flags also need to get set for both
> host controllers, and I want to make sure the shared_hcd pointer is set
> before the bus is used by the USB core at all.

Be more specific.  Why exactly do you think you need this?

> I could potentially allocate the shared HCD in one of the xHCI
> initialization routines, before usb_add_hcd() has a chance to call
> register_root_hub().  But I'm not sure how the USB core will react to
> being called recursively, i.e. usb_register_bus() calls xhci_run() which
> calls usb_alloc_shared_hcd() and usb_register_bus().  And what if
> someone decides to add a new lock to the USB core functions later?  If
> they don't have an xHCI device to test with, then they may not notice
> some obscure code in the xHCI driver that calls the functions
> recursively.
> 
> I agree that it's code that's not likely to be used by any other host
> controller, but I think this code needs to be visible in the USB core.

I still think you should be able to call usb_hcd_pci_probe for the 
primary hcd, let it be registered and started, and then call 
usb_add_shared_hcd for the other one.

> > > +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.
> 
> I do use it in the xHCI driver initialization code, to ensure I'm only
> starting the host controller when the second (i.e. non-primary) host
> controller is registered.  I would have to see if I can just test for
> NULL instead, but I feel that it's more symmetrical somehow to set
> primary_hcd for both HCDs.

It's not a big deal.  Doing it this way just means you have to make two
tests instead of only one.

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


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

  Powered by Linux