summaryrefslogtreecommitdiff
path: root/drivers/usb/core/hcd.h
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@linux.intel.com>2009-12-03 09:44:36 -0800
committerGreg Kroah-Hartman <gregkh@suse.de>2009-12-11 11:55:27 -0800
commit3f0479e00a3fca9590ae8d9edc4e9c47b7fa0610 (patch)
tree495cee9f35ed0315367a10af86bbb107f05eeb75 /drivers/usb/core/hcd.h
parent91017f9cf5fcfb601b8d583c896ac7de7d200c57 (diff)
USB: Check bandwidth when switching alt settings.
Make the USB core check the bandwidth when switching from one interface alternate setting to another. Also check the bandwidth when resetting a configuration (so that alt setting 0 is used). If this check fails, the device's state is unchanged. If the device refuses the new alt setting, re-instate the old alt setting in the host controller hardware. If a USB device doesn't have an alternate interface setting 0, install the first alt setting in its descriptors when a new configuration is requested, or the device is reset. Add a mutex per root hub to protect bandwidth operations: adding/reseting/changing configurations, and changing alternate interface settings. We want to ensure that the xHCI host controller and the USB device are set up for the same configurations and alternate settings. There are two (possibly three) steps to do this: 1. The host controller needs to check that bandwidth is available for a different setting, by issuing and waiting for a configure endpoint command. 2. Once that returns successfully, a control message is sent to the device. 3. If that fails, the host controller must be notified through another configure endpoint command. The mutex is used to make these three operations seem atomic, to prevent another driver from using more bandwidth for a different device while we're in the middle of these operations. While we're touching the bandwidth code, rename usb_hcd_check_bandwidth() to usb_hcd_alloc_bandwidth(). This function does more than just check that the bandwidth change won't exceed the bus bandwidth; it actually changes the bandwidth configuration in the xHCI host controller. Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/core/hcd.h')
-rw-r--r--drivers/usb/core/hcd.h19
1 files changed, 17 insertions, 2 deletions
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
index 79782a1c43f6..d8b43aee581e 100644
--- a/drivers/usb/core/hcd.h
+++ b/drivers/usb/core/hcd.h
@@ -111,6 +111,20 @@ struct usb_hcd {
u64 rsrc_len; /* memory/io resource length */
unsigned power_budget; /* in mA, 0 = no limit */
+ /* bandwidth_mutex should be taken before adding or removing
+ * any new bus bandwidth constraints:
+ * 1. Before adding a configuration for a new device.
+ * 2. Before removing the configuration to put the device into
+ * the addressed state.
+ * 3. Before selecting a different configuration.
+ * 4. Before selecting an alternate interface setting.
+ *
+ * bandwidth_mutex should be dropped after a successful control message
+ * to the device, or resetting the bandwidth after a failed attempt.
+ */
+ struct mutex bandwidth_mutex;
+
+
#define HCD_BUFFER_POOLS 4
struct dma_pool *pool [HCD_BUFFER_POOLS];
@@ -290,9 +304,10 @@ extern void usb_hcd_disable_endpoint(struct usb_device *udev,
extern void usb_hcd_reset_endpoint(struct usb_device *udev,
struct usb_host_endpoint *ep);
extern void usb_hcd_synchronize_unlinks(struct usb_device *udev);
-extern int usb_hcd_check_bandwidth(struct usb_device *udev,
+extern int usb_hcd_alloc_bandwidth(struct usb_device *udev,
struct usb_host_config *new_config,
- struct usb_interface *new_intf);
+ struct usb_host_interface *old_alt,
+ struct usb_host_interface *new_alt);
extern int usb_hcd_get_frame_number(struct usb_device *udev);
extern struct usb_hcd *usb_create_hcd(const struct hc_driver *driver,