Re: [RFT 2/2] USB: Free bandwidth when usb_disable_device is called.

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

 



On Mon, 6 Jun 2011, Sarah Sharp wrote:

> Tanya ran into an issue when trying to switch a UAS device from the BOT
> configuration to the UAS configuration via the bConfigurationValue sysfs
> file.  Before installing the UAS configuration, set_bConfigurationValue()
> calls usb_disable_device().  That function is supposed to remove all host
> controller resources associated with that device, but it leaves some state
> in the xHCI host controller.
> 
> usb_disable_device() goes through all the motions of unbinding the drivers
> attached to active interfaces and removing the USB core structures
> associated with those interfaces, but it doesn't actually remove the
> endpoints from the internal xHCI host controller bandwidth structures.
> 
> When usb_disable_device() calls usb_disable_endpoint() with reset_hardware
> set to true, the entries in udev->ep_out and udev->ep_in will be set to
> NULL.  Usually, when the USB core installs a new configuration,
> usb_hcd_alloc_bandwidth() will drop all non-NULL endpoints in udev->ep_out
> and udev->ep_in before adding any new endpoints.  However, when the new
> UAS configuration was added, all those entries were null, so none of the
> old endpoints in the BOT configuration were dropped.
> 
> The xHCI driver blindly added the UAS configuration endpoints, and some of
> the endpoint addresses overlapped with the old BOT configuration
> endpoints.  This caused the xHCI host to reject the Configure Endpoint
> command.  Now that the xHCI driver code is cleaned up to reject a
> double-add of active endpoints, we need to fix the USB core to properly
> drop old endpoints in usb_disable_device().
> 
> If the host controller driver needs bandwidth checking support, make
> usb_disable_device() call usb_disable_endpoint() with
> reset_hardware set to false, drop the endpoints from the xHCI host
> controller, and then call usb_disable_endpoint() again with
> reset_hardware set to true.
> 
> The first call to usb_disable_endpoint() will cancel any pending URBs and
> wait on them to be freed in usb_hcd_disable_endpoint(), but will keep the
> pointers in udev->ep_out and udev->ep in intact.  Then
> usb_hcd_alloc_bandwidth() will use those pointers to know which endpoints
> to drop.
> 
> The final call to usb_disable_endpoint() will do two things:
> 
> 1. It will call usb_hcd_disable_endpoint() again, which should be harmless
> since the ep->urb_list should be empty after the first call to
> usb_disable_endpoint() returns.
> 
> 2. It will set the entries in udev->ep_out and udev->ep in to NULL, and call
> usb_hcd_disable_endpoint().  That call will have no effect, since the xHCI
> driver doesn't set the endpoint_disable function pointer.
> 
> Signed-off-by: Sarah Sharp <sarah.a.sharp@xxxxxxxxxxxxxxx>
> Reported-by: Tanya Brokhman <tlinder@xxxxxxxxxxxxxx>
> Cc: ablay@xxxxxxxxxxxxxx
> Cc: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx>
> ---
> 
> Alan,
> 
> Does this patch look correct?  I was struggling a bit to make sure the
> USB core behavior remained the same, while still correctly dropping the
> old configuration's endpoints from the xHCI driver.

How about just unconditionally calling usb_hcd_alloc_bandwidth() before 
looping through the endpoint arrays?  Alternatively, how about making 
xhci-hcd's endpoint_disable method responsible for releasing the 
endpoint's bandwidth reservation?

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