linux/drivers/usb/core/hcd.c

2457 lines
71 KiB

usb hub: fix root hub code so it takes more than 15 devices per root hub Wireless USB Host Controllers accept a large number of devices per host, which shows up as a large number of ports in its root hub. When the number of ports in a hub device goes over 16, the activation of the hub fails with the cryptic message in klogd. hub 2-0:1.0: activate --> -22 Following this further, it was seen that: hub_probe() hub_configure() generates pipe number pseudo allocates buffer 'maxp' bytes in size using usb_maxpacket() The endpoint descriptor for a root hub interrupt endpoint is declared in drivers/usb/core/hcd.c:hs_rh_config_descriptor and declares it to be size two (supporting 15 devices max). hub_activate() usb_hcd_submit_urb() rh_urb_enqueue() urb->pipe is neither int nor ctl, so it errors out rh_queue_status() Returns -EINVAL because the buffer length is smaller than the minimum needed to report all the hub port bits as in accordance with USB2.0[11.12.3]. There has to be trunc((PORTS + 1 + 7) / 8) bytes of space at least. Alan Stern confirmed that the reason for reading maxpktsize and not the right amount is because some hubs are known to return more data and thus cause overflow. So this patch simply changes the code to make the interrupt endpoint's max packet size be at least the minimum required by USB_MAXCHILDREN (instead of a fixed magic number) and add documentation for that. This way we are always ahead of the limit. Signed-off-by: Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2006-10-11 20:05:59 -07:00
USB: don't stop root-hub status polls too soon This patch (as1390) fixes a problem that crops up when a UHCI host controller is unbound from uhci-hcd while there are still some active URBs. The URBs have to be unlinked when the root hub is unregistered, and uhci-hcd relies upon root-hub status polls as part of its unlinking procedure. But usb_hcd_poll_rh_status() won't make those status calls if hcd->rh_registered is clear, and the flag is cleared _before_ the unregistration takes place. Since hcd->rh_registered is used for other things and needs to be cleared early, the solution is to add a new flag (rh_pollable) and use it instead. It gets cleared _after_ the root hub is unregistered. Now that the status polls don't end too soon, we have to make sure they also don't occur too late -- after the root hub's usb_device structure or the HCD's private structures are deallocated. Therefore the patch adds usb_get_device() and usb_put_device() calls to protect the root hub structure, and it adds an extra del_timer_sync() to prevent the root-hub timer from causing an unexpected status poll. This additional complexity would not be needed if the HCD framework had provided separate stop() and release() callbacks instead of just stop(). This lack could be fixed at some future time (although it would require changes to every host controller driver); when that happens this patch won't be needed any more. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2010-06-09 17:34:17 -04:00
2010-04-02 13:27:28 -04:00
2010-04-02 13:27:28 -04:00
USB: Push scatter gather lists down to host controller drivers. This is the original patch I created before David Vrabel posted a better patch (http://marc.info/?l=linux-usb&m=123377477209109&w=2) that does basically the same thing. This patch will get replaced with his (modified) patch later. Allow USB device drivers that use usb_sg_init() and usb_sg_wait() to push bulk endpoint scatter gather lists down to the host controller drivers. This allows host controller drivers to more efficiently enqueue these transfers, and allows the xHCI host controller to better take advantage of USB 3.0 "bursts" for bulk endpoints. This patch currently only enables scatter gather lists for bulk endpoints. Other endpoint types that use the usb_sg_* functions will not have their scatter gather lists pushed down to the host controller. For periodic endpoints, we want each scatterlist entry to be a separate transfer. Eventually, HCDs could parse these scatter-gather lists for periodic endpoints also. For now, we use the old code and call usb_submit_urb() for each scatterlist entry. The caller of usb_sg_init() can request that all bytes in the scatter gather list be transferred by passing in a length of zero. Handle that request for a bulk endpoint under xHCI by walking the scatter gather list and calculating the length. We could let the HCD handle a zero length in this case, but I'm not sure if the core layers in between will get confused by this. Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2009-04-27 19:59:01 -07:00
2010-04-02 13:27:28 -04:00
2010-04-02 13:27:28 -04:00
2010-04-02 13:27:28 -04:00
2010-04-02 13:27:28 -04:00
2010-04-02 13:27:28 -04:00
2010-04-02 13:27:28 -04:00
2010-04-02 13:27:28 -04:00
2010-04-02 13:27:28 -04:00
2010-04-02 13:27:28 -04:00
2010-04-02 13:27:28 -04:00
2010-04-02 13:27:28 -04:00
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>
2009-12-03 09:44:36 -08:00
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>
2009-12-03 09:44:36 -08:00
USB: Support for bandwidth allocation. Originally, the USB core had no support for allocating bandwidth when a particular configuration or alternate setting for an interface was selected. Instead, the device driver's URB submission would fail if there was not enough bandwidth for a periodic endpoint. Drivers could work around this, by using the scatter-gather list API to guarantee bandwidth. This patch adds host controller API to allow the USB core to allocate or deallocate bandwidth for an endpoint. Endpoints are added to or dropped from a copy of the current schedule by calling add_endpoint() or drop_endpoint(), and then the schedule is atomically evaluated with a call to check_bandwidth(). This allows all the endpoints for a new configuration or alternate setting to be added at the same time that the endpoints from the old configuration or alt setting are dropped. Endpoints must be added to the schedule before any URBs are submitted to them. The HCD must be allowed to reject a new configuration or alt setting before the control transfer is sent to the device requesting the change. It may reject the change because there is not enough bandwidth, not enough internal resources (such as memory on an embedded host controller), or perhaps even for security reasons in a virtualized environment. If the call to check_bandwidth() fails, the USB core must call reset_bandwidth(). This causes the schedule to be reverted back to the state it was in just after the last successful check_bandwidth() call. If the call succeeds, the host controller driver (and hardware) will have changed its internal state to match the new configuration or alternate setting. The USB core can then issue a control transfer to the device to change the configuration or alt setting. This allows the core to test new configurations or alternate settings before unbinding drivers bound to interfaces in the old configuration. WIP: The USB core must add endpoints from all interfaces in a configuration to the schedule, because a driver may claim that interface at any time. A slight optimization might be to add the endpoints to the schedule once a driver claims that interface. FIXME This patch does not cover changing alternate settings, but it does handle a configuration change or de-configuration. FIXME The code for managing the schedule is currently HCD specific. A generic scheduling algorithm could be added for host controllers without built-in scheduling support. For now, if a host controller does not define the check_bandwidth() function, the call to usb_hcd_check_bandwidth() will always succeed. Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2009-04-27 19:58:26 -07:00
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>
2009-12-03 09:44:36 -08:00
USB: Support for bandwidth allocation. Originally, the USB core had no support for allocating bandwidth when a particular configuration or alternate setting for an interface was selected. Instead, the device driver's URB submission would fail if there was not enough bandwidth for a periodic endpoint. Drivers could work around this, by using the scatter-gather list API to guarantee bandwidth. This patch adds host controller API to allow the USB core to allocate or deallocate bandwidth for an endpoint. Endpoints are added to or dropped from a copy of the current schedule by calling add_endpoint() or drop_endpoint(), and then the schedule is atomically evaluated with a call to check_bandwidth(). This allows all the endpoints for a new configuration or alternate setting to be added at the same time that the endpoints from the old configuration or alt setting are dropped. Endpoints must be added to the schedule before any URBs are submitted to them. The HCD must be allowed to reject a new configuration or alt setting before the control transfer is sent to the device requesting the change. It may reject the change because there is not enough bandwidth, not enough internal resources (such as memory on an embedded host controller), or perhaps even for security reasons in a virtualized environment. If the call to check_bandwidth() fails, the USB core must call reset_bandwidth(). This causes the schedule to be reverted back to the state it was in just after the last successful check_bandwidth() call. If the call succeeds, the host controller driver (and hardware) will have changed its internal state to match the new configuration or alternate setting. The USB core can then issue a control transfer to the device to change the configuration or alt setting. This allows the core to test new configurations or alternate settings before unbinding drivers bound to interfaces in the old configuration. WIP: The USB core must add endpoints from all interfaces in a configuration to the schedule, because a driver may claim that interface at any time. A slight optimization might be to add the endpoints to the schedule once a driver claims that interface. FIXME This patch does not cover changing alternate settings, but it does handle a configuration change or de-configuration. FIXME The code for managing the schedule is currently HCD specific. A generic scheduling algorithm could be added for host controllers without built-in scheduling support. For now, if a host controller does not define the check_bandwidth() function, the call to usb_hcd_check_bandwidth() will always succeed. Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2009-04-27 19:58:26 -07:00
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>
2009-12-03 09:44:36 -08:00
USB: Support for bandwidth allocation. Originally, the USB core had no support for allocating bandwidth when a particular configuration or alternate setting for an interface was selected. Instead, the device driver's URB submission would fail if there was not enough bandwidth for a periodic endpoint. Drivers could work around this, by using the scatter-gather list API to guarantee bandwidth. This patch adds host controller API to allow the USB core to allocate or deallocate bandwidth for an endpoint. Endpoints are added to or dropped from a copy of the current schedule by calling add_endpoint() or drop_endpoint(), and then the schedule is atomically evaluated with a call to check_bandwidth(). This allows all the endpoints for a new configuration or alternate setting to be added at the same time that the endpoints from the old configuration or alt setting are dropped. Endpoints must be added to the schedule before any URBs are submitted to them. The HCD must be allowed to reject a new configuration or alt setting before the control transfer is sent to the device requesting the change. It may reject the change because there is not enough bandwidth, not enough internal resources (such as memory on an embedded host controller), or perhaps even for security reasons in a virtualized environment. If the call to check_bandwidth() fails, the USB core must call reset_bandwidth(). This causes the schedule to be reverted back to the state it was in just after the last successful check_bandwidth() call. If the call succeeds, the host controller driver (and hardware) will have changed its internal state to match the new configuration or alternate setting. The USB core can then issue a control transfer to the device to change the configuration or alt setting. This allows the core to test new configurations or alternate settings before unbinding drivers bound to interfaces in the old configuration. WIP: The USB core must add endpoints from all interfaces in a configuration to the schedule, because a driver may claim that interface at any time. A slight optimization might be to add the endpoints to the schedule once a driver claims that interface. FIXME This patch does not cover changing alternate settings, but it does handle a configuration change or de-configuration. FIXME The code for managing the schedule is currently HCD specific. A generic scheduling algorithm could be added for host controllers without built-in scheduling support. For now, if a host controller does not define the check_bandwidth() function, the call to usb_hcd_check_bandwidth() will always succeed. Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2009-04-27 19:58:26 -07:00
USB: Support for bandwidth allocation. Originally, the USB core had no support for allocating bandwidth when a particular configuration or alternate setting for an interface was selected. Instead, the device driver's URB submission would fail if there was not enough bandwidth for a periodic endpoint. Drivers could work around this, by using the scatter-gather list API to guarantee bandwidth. This patch adds host controller API to allow the USB core to allocate or deallocate bandwidth for an endpoint. Endpoints are added to or dropped from a copy of the current schedule by calling add_endpoint() or drop_endpoint(), and then the schedule is atomically evaluated with a call to check_bandwidth(). This allows all the endpoints for a new configuration or alternate setting to be added at the same time that the endpoints from the old configuration or alt setting are dropped. Endpoints must be added to the schedule before any URBs are submitted to them. The HCD must be allowed to reject a new configuration or alt setting before the control transfer is sent to the device requesting the change. It may reject the change because there is not enough bandwidth, not enough internal resources (such as memory on an embedded host controller), or perhaps even for security reasons in a virtualized environment. If the call to check_bandwidth() fails, the USB core must call reset_bandwidth(). This causes the schedule to be reverted back to the state it was in just after the last successful check_bandwidth() call. If the call succeeds, the host controller driver (and hardware) will have changed its internal state to match the new configuration or alternate setting. The USB core can then issue a control transfer to the device to change the configuration or alt setting. This allows the core to test new configurations or alternate settings before unbinding drivers bound to interfaces in the old configuration. WIP: The USB core must add endpoints from all interfaces in a configuration to the schedule, because a driver may claim that interface at any time. A slight optimization might be to add the endpoints to the schedule once a driver claims that interface. FIXME This patch does not cover changing alternate settings, but it does handle a configuration change or de-configuration. FIXME The code for managing the schedule is currently HCD specific. A generic scheduling algorithm could be added for host controllers without built-in scheduling support. For now, if a host controller does not define the check_bandwidth() function, the call to usb_hcd_check_bandwidth() will always succeed. Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2009-04-27 19:58:26 -07:00
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>
2009-12-03 09:44:36 -08:00
USB: Support for bandwidth allocation. Originally, the USB core had no support for allocating bandwidth when a particular configuration or alternate setting for an interface was selected. Instead, the device driver's URB submission would fail if there was not enough bandwidth for a periodic endpoint. Drivers could work around this, by using the scatter-gather list API to guarantee bandwidth. This patch adds host controller API to allow the USB core to allocate or deallocate bandwidth for an endpoint. Endpoints are added to or dropped from a copy of the current schedule by calling add_endpoint() or drop_endpoint(), and then the schedule is atomically evaluated with a call to check_bandwidth(). This allows all the endpoints for a new configuration or alternate setting to be added at the same time that the endpoints from the old configuration or alt setting are dropped. Endpoints must be added to the schedule before any URBs are submitted to them. The HCD must be allowed to reject a new configuration or alt setting before the control transfer is sent to the device requesting the change. It may reject the change because there is not enough bandwidth, not enough internal resources (such as memory on an embedded host controller), or perhaps even for security reasons in a virtualized environment. If the call to check_bandwidth() fails, the USB core must call reset_bandwidth(). This causes the schedule to be reverted back to the state it was in just after the last successful check_bandwidth() call. If the call succeeds, the host controller driver (and hardware) will have changed its internal state to match the new configuration or alternate setting. The USB core can then issue a control transfer to the device to change the configuration or alt setting. This allows the core to test new configurations or alternate settings before unbinding drivers bound to interfaces in the old configuration. WIP: The USB core must add endpoints from all interfaces in a configuration to the schedule, because a driver may claim that interface at any time. A slight optimization might be to add the endpoints to the schedule once a driver claims that interface. FIXME This patch does not cover changing alternate settings, but it does handle a configuration change or de-configuration. FIXME The code for managing the schedule is currently HCD specific. A generic scheduling algorithm could be added for host controllers without built-in scheduling support. For now, if a host controller does not define the check_bandwidth() function, the call to usb_hcd_check_bandwidth() will always succeed. Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2009-04-27 19:58:26 -07:00
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>
2009-12-03 09:44:36 -08:00
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>
2009-12-03 09:44:36 -08:00
USB: Support for bandwidth allocation. Originally, the USB core had no support for allocating bandwidth when a particular configuration or alternate setting for an interface was selected. Instead, the device driver's URB submission would fail if there was not enough bandwidth for a periodic endpoint. Drivers could work around this, by using the scatter-gather list API to guarantee bandwidth. This patch adds host controller API to allow the USB core to allocate or deallocate bandwidth for an endpoint. Endpoints are added to or dropped from a copy of the current schedule by calling add_endpoint() or drop_endpoint(), and then the schedule is atomically evaluated with a call to check_bandwidth(). This allows all the endpoints for a new configuration or alternate setting to be added at the same time that the endpoints from the old configuration or alt setting are dropped. Endpoints must be added to the schedule before any URBs are submitted to them. The HCD must be allowed to reject a new configuration or alt setting before the control transfer is sent to the device requesting the change. It may reject the change because there is not enough bandwidth, not enough internal resources (such as memory on an embedded host controller), or perhaps even for security reasons in a virtualized environment. If the call to check_bandwidth() fails, the USB core must call reset_bandwidth(). This causes the schedule to be reverted back to the state it was in just after the last successful check_bandwidth() call. If the call succeeds, the host controller driver (and hardware) will have changed its internal state to match the new configuration or alternate setting. The USB core can then issue a control transfer to the device to change the configuration or alt setting. This allows the core to test new configurations or alternate settings before unbinding drivers bound to interfaces in the old configuration. WIP: The USB core must add endpoints from all interfaces in a configuration to the schedule, because a driver may claim that interface at any time. A slight optimization might be to add the endpoints to the schedule once a driver claims that interface. FIXME This patch does not cover changing alternate settings, but it does handle a configuration change or de-configuration. FIXME The code for managing the schedule is currently HCD specific. A generic scheduling algorithm could be added for host controllers without built-in scheduling support. For now, if a host controller does not define the check_bandwidth() function, the call to usb_hcd_check_bandwidth() will always succeed. Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2009-04-27 19:58:26 -07:00
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>
2009-12-03 09:44:36 -08:00
USB: Fix duplicate sysfs problem after device reset. Borislav Petkov reports issues with duplicate sysfs endpoint files after a resume from a hibernate. It turns out that the code to support alternate settings under xHCI has issues when a device with a non-default alternate setting is reset during the hibernate: [ 427.681810] Restarting tasks ... [ 427.681995] hub 1-0:1.0: state 7 ports 6 chg 0004 evt 0000 [ 427.682019] usb usb3: usb resume [ 427.682030] ohci_hcd 0000:00:12.0: wakeup root hub [ 427.682191] hub 1-0:1.0: port 2, status 0501, change 0000, 480 Mb/s [ 427.682205] usb 1-2: usb wakeup-resume [ 427.682226] usb 1-2: finish reset-resume [ 427.682886] done. [ 427.734658] ehci_hcd 0000:00:12.2: port 2 high speed [ 427.734663] ehci_hcd 0000:00:12.2: GetStatus port 2 status 001005 POWER sig=se0 PE CONNECT [ 427.746682] hub 3-0:1.0: hub_reset_resume [ 427.746693] hub 3-0:1.0: trying to enable port power on non-switchable hub [ 427.786715] usb 1-2: reset high speed USB device using ehci_hcd and address 2 [ 427.839653] ehci_hcd 0000:00:12.2: port 2 high speed [ 427.839666] ehci_hcd 0000:00:12.2: GetStatus port 2 status 001005 POWER sig=se0 PE CONNECT [ 427.847717] ohci_hcd 0000:00:12.0: GetStatus roothub.portstatus [1] = 0x00010100 CSC PPS [ 427.915497] hub 1-2:1.0: remove_intf_ep_devs: if: ffff88022f9e8800 ->ep_devs_created: 1 [ 427.915774] hub 1-2:1.0: remove_intf_ep_devs: bNumEndpoints: 1 [ 427.915934] hub 1-2:1.0: if: ffff88022f9e8800: endpoint devs removed. [ 427.916158] hub 1-2:1.0: create_intf_ep_devs: if: ffff88022f9e8800 ->ep_devs_created: 0, ->unregistering: 0 [ 427.916434] hub 1-2:1.0: create_intf_ep_devs: bNumEndpoints: 1 [ 427.916609] ep_81: create, parent hub [ 427.916632] ------------[ cut here ]------------ [ 427.916644] WARNING: at fs/sysfs/dir.c:477 sysfs_add_one+0x82/0x96() [ 427.916649] Hardware name: System Product Name [ 427.916653] sysfs: cannot create duplicate filename '/devices/pci0000:00/0000:00:12.2/usb1/1-2/1-2:1.0/ep_81' [ 427.916658] Modules linked in: binfmt_misc kvm_amd kvm powernow_k8 cpufreq_ondemand cpufreq_powersave cpufreq_userspace freq_table cpufreq_conservative ipv6 vfat fat +8250_pnp 8250 pcspkr ohci_hcd serial_core k10temp edac_core [ 427.916694] Pid: 278, comm: khubd Not tainted 2.6.33-rc2-00187-g08d869a-dirty #13 [ 427.916699] Call Trace: The problem is caused by a mismatch between the USB core's view of the device state and the USB device and xHCI host's view of the device state. After the device reset and re-configuration, the device and the xHCI host think they are using alternate setting 0 of all interfaces. However, the USB core keeps track of the old state, which may include non-zero alternate settings. It uses intf->cur_altsetting to keep the endpoint sysfs files for the old state across the reset. The bandwidth allocation functions need to know what the xHCI host thinks the current alternate settings are, so original patch set intf->cur_altsetting to the alternate setting 0. This caused duplicate endpoint files to be created. The solution is to not set intf->cur_altsetting before calling usb_set_interface() in usb_reset_and_verify_device(). Instead, we add a new flag to struct usb_interface to tell usb_hcd_alloc_bandwidth() to use alternate setting 0 as the currently installed alternate setting. Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Tested-by: Borislav Petkov <petkovbb@googlemail.com> Cc: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2010-01-06 10:16:51 -08:00
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>
2009-12-03 09:44:36 -08:00
USB: Support for bandwidth allocation. Originally, the USB core had no support for allocating bandwidth when a particular configuration or alternate setting for an interface was selected. Instead, the device driver's URB submission would fail if there was not enough bandwidth for a periodic endpoint. Drivers could work around this, by using the scatter-gather list API to guarantee bandwidth. This patch adds host controller API to allow the USB core to allocate or deallocate bandwidth for an endpoint. Endpoints are added to or dropped from a copy of the current schedule by calling add_endpoint() or drop_endpoint(), and then the schedule is atomically evaluated with a call to check_bandwidth(). This allows all the endpoints for a new configuration or alternate setting to be added at the same time that the endpoints from the old configuration or alt setting are dropped. Endpoints must be added to the schedule before any URBs are submitted to them. The HCD must be allowed to reject a new configuration or alt setting before the control transfer is sent to the device requesting the change. It may reject the change because there is not enough bandwidth, not enough internal resources (such as memory on an embedded host controller), or perhaps even for security reasons in a virtualized environment. If the call to check_bandwidth() fails, the USB core must call reset_bandwidth(). This causes the schedule to be reverted back to the state it was in just after the last successful check_bandwidth() call. If the call succeeds, the host controller driver (and hardware) will have changed its internal state to match the new configuration or alternate setting. The USB core can then issue a control transfer to the device to change the configuration or alt setting. This allows the core to test new configurations or alternate settings before unbinding drivers bound to interfaces in the old configuration. WIP: The USB core must add endpoints from all interfaces in a configuration to the schedule, because a driver may claim that interface at any time. A slight optimization might be to add the endpoints to the schedule once a driver claims that interface. FIXME This patch does not cover changing alternate settings, but it does handle a configuration change or de-configuration. FIXME The code for managing the schedule is currently HCD specific. A generic scheduling algorithm could be added for host controllers without built-in scheduling support. For now, if a host controller does not define the check_bandwidth() function, the call to usb_hcd_check_bandwidth() will always succeed. Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2009-04-27 19:58:26 -07:00
IRQ: Maintain regs pointer globally rather than passing to IRQ handlers Maintain a per-CPU global "struct pt_regs *" variable which can be used instead of passing regs around manually through all ~1800 interrupt handlers in the Linux kernel. The regs pointer is used in few places, but it potentially costs both stack space and code to pass it around. On the FRV arch, removing the regs parameter from all the genirq function results in a 20% speed up of the IRQ exit path (ie: from leaving timer_interrupt() to leaving do_IRQ()). Where appropriate, an arch may override the generic storage facility and do something different with the variable. On FRV, for instance, the address is maintained in GR28 at all times inside the kernel as part of general exception handling. Having looked over the code, it appears that the parameter may be handed down through up to twenty or so layers of functions. Consider a USB character device attached to a USB hub, attached to a USB controller that posts its interrupts through a cascaded auxiliary interrupt controller. A character device driver may want to pass regs to the sysrq handler through the input layer which adds another few layers of parameter passing. I've build this code with allyesconfig for x86_64 and i386. I've runtested the main part of the code on FRV and i386, though I can't test most of the drivers. I've also done partial conversion for powerpc and MIPS - these at least compile with minimal configurations. This will affect all archs. Mostly the changes should be relatively easy. Take do_IRQ(), store the regs pointer at the beginning, saving the old one: struct pt_regs *old_regs = set_irq_regs(regs); And put the old one back at the end: set_irq_regs(old_regs); Don't pass regs through to generic_handle_irq() or __do_IRQ(). In timer_interrupt(), this sort of change will be necessary: - update_process_times(user_mode(regs)); - profile_tick(CPU_PROFILING, regs); + update_process_times(user_mode(get_irq_regs())); + profile_tick(CPU_PROFILING); I'd like to move update_process_times()'s use of get_irq_regs() into itself, except that i386, alone of the archs, uses something other than user_mode(). Some notes on the interrupt handling in the drivers: (*) input_dev() is now gone entirely. The regs pointer is no longer stored in the input_dev struct. (*) finish_unlinks() in drivers/usb/host/ohci-q.c needs checking. It does something different depending on whether it's been supplied with a regs pointer or not. (*) Various IRQ handler function pointers have been moved to type irq_handler_t. Signed-Off-By: David Howells <dhowells@redhat.com> (cherry picked from 1b16e7ac850969f38b375e511e3fa2f474a33867 commit)
2006-10-05 14:55:46 +01:00
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>
2009-12-03 09:44:36 -08:00
USB: don't stop root-hub status polls too soon This patch (as1390) fixes a problem that crops up when a UHCI host controller is unbound from uhci-hcd while there are still some active URBs. The URBs have to be unlinked when the root hub is unregistered, and uhci-hcd relies upon root-hub status polls as part of its unlinking procedure. But usb_hcd_poll_rh_status() won't make those status calls if hcd->rh_registered is clear, and the flag is cleared _before_ the unregistration takes place. Since hcd->rh_registered is used for other things and needs to be cleared early, the solution is to add a new flag (rh_pollable) and use it instead. It gets cleared _after_ the root hub is unregistered. Now that the status polls don't end too soon, we have to make sure they also don't occur too late -- after the root hub's usb_device structure or the HCD's private structures are deallocated. Therefore the patch adds usb_get_device() and usb_put_device() calls to protect the root hub structure, and it adds an extra del_timer_sync() to prevent the root-hub timer from causing an unexpected status poll. This additional complexity would not be needed if the HCD framework had provided separate stop() and release() callbacks instead of just stop(). This lack could be fixed at some future time (although it would require changes to every host controller driver); when that happens this patch won't be needed any more. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2010-06-09 17:34:17 -04:00
USB: don't stop root-hub status polls too soon This patch (as1390) fixes a problem that crops up when a UHCI host controller is unbound from uhci-hcd while there are still some active URBs. The URBs have to be unlinked when the root hub is unregistered, and uhci-hcd relies upon root-hub status polls as part of its unlinking procedure. But usb_hcd_poll_rh_status() won't make those status calls if hcd->rh_registered is clear, and the flag is cleared _before_ the unregistration takes place. Since hcd->rh_registered is used for other things and needs to be cleared early, the solution is to add a new flag (rh_pollable) and use it instead. It gets cleared _after_ the root hub is unregistered. Now that the status polls don't end too soon, we have to make sure they also don't occur too late -- after the root hub's usb_device structure or the HCD's private structures are deallocated. Therefore the patch adds usb_get_device() and usb_put_device() calls to protect the root hub structure, and it adds an extra del_timer_sync() to prevent the root-hub timer from causing an unexpected status poll. This additional complexity would not be needed if the HCD framework had provided separate stop() and release() callbacks instead of just stop(). This lack could be fixed at some future time (although it would require changes to every host controller driver); when that happens this patch won't be needed any more. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2010-06-09 17:34:17 -04:00
[PATCH] USB: Consider power budget when choosing configuration This patch (as609) changes the way we keep track of power budgeting for USB hubs and devices, and it updates the choose_configuration routine to take this information into account. (This is something we should have been doing all along.) A new field in struct usb_device holds the amount of bus current available from the upstream port, and the usb_hub structure keeps track of the current available for each downstream port. Two new rules for configuration selection are added: Don't select a self-powered configuration when only bus power is available. Don't select a configuration requiring more bus power than is available. However the first rule is #if-ed out, because I found that the internal hub in my HP USB keyboard claims that its only configuration is self-powered. The rule would prevent the configuration from being chosen, leaving the hub & keyboard unconfigured. Since similar descriptor errors may turn out to be fairly common, it seemed wise not to include a rule that would break automatic configuration unnecessarily for such devices. The second rule may also trigger unnecessarily, although this should be less common. More likely it will annoy people by sometimes failing to accept configurations that should never have been chosen in the first place. The patch also changes usbcore's reaction when no configuration is suitable. Instead of raising an error and rejecting the device, now the core will simply leave the device unconfigured. People can always work around such problems by installing configurations manually through sysfs. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2005-11-23 12:03:12 -05:00
USB: don't stop root-hub status polls too soon This patch (as1390) fixes a problem that crops up when a UHCI host controller is unbound from uhci-hcd while there are still some active URBs. The URBs have to be unlinked when the root hub is unregistered, and uhci-hcd relies upon root-hub status polls as part of its unlinking procedure. But usb_hcd_poll_rh_status() won't make those status calls if hcd->rh_registered is clear, and the flag is cleared _before_ the unregistration takes place. Since hcd->rh_registered is used for other things and needs to be cleared early, the solution is to add a new flag (rh_pollable) and use it instead. It gets cleared _after_ the root hub is unregistered. Now that the status polls don't end too soon, we have to make sure they also don't occur too late -- after the root hub's usb_device structure or the HCD's private structures are deallocated. Therefore the patch adds usb_get_device() and usb_put_device() calls to protect the root hub structure, and it adds an extra del_timer_sync() to prevent the root-hub timer from causing an unexpected status poll. This additional complexity would not be needed if the HCD framework had provided separate stop() and release() callbacks instead of just stop(). This lack could be fixed at some future time (although it would require changes to every host controller driver); when that happens this patch won't be needed any more. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2010-06-09 17:34:17 -04:00
USB: don't stop root-hub status polls too soon This patch (as1390) fixes a problem that crops up when a UHCI host controller is unbound from uhci-hcd while there are still some active URBs. The URBs have to be unlinked when the root hub is unregistered, and uhci-hcd relies upon root-hub status polls as part of its unlinking procedure. But usb_hcd_poll_rh_status() won't make those status calls if hcd->rh_registered is clear, and the flag is cleared _before_ the unregistration takes place. Since hcd->rh_registered is used for other things and needs to be cleared early, the solution is to add a new flag (rh_pollable) and use it instead. It gets cleared _after_ the root hub is unregistered. Now that the status polls don't end too soon, we have to make sure they also don't occur too late -- after the root hub's usb_device structure or the HCD's private structures are deallocated. Therefore the patch adds usb_get_device() and usb_put_device() calls to protect the root hub structure, and it adds an extra del_timer_sync() to prevent the root-hub timer from causing an unexpected status poll. This additional complexity would not be needed if the HCD framework had provided separate stop() and release() callbacks instead of just stop(). This lack could be fixed at some future time (although it would require changes to every host controller driver); when that happens this patch won't be needed any more. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2010-06-09 17:34:17 -04:00
USB: don't stop root-hub status polls too soon This patch (as1390) fixes a problem that crops up when a UHCI host controller is unbound from uhci-hcd while there are still some active URBs. The URBs have to be unlinked when the root hub is unregistered, and uhci-hcd relies upon root-hub status polls as part of its unlinking procedure. But usb_hcd_poll_rh_status() won't make those status calls if hcd->rh_registered is clear, and the flag is cleared _before_ the unregistration takes place. Since hcd->rh_registered is used for other things and needs to be cleared early, the solution is to add a new flag (rh_pollable) and use it instead. It gets cleared _after_ the root hub is unregistered. Now that the status polls don't end too soon, we have to make sure they also don't occur too late -- after the root hub's usb_device structure or the HCD's private structures are deallocated. Therefore the patch adds usb_get_device() and usb_put_device() calls to protect the root hub structure, and it adds an extra del_timer_sync() to prevent the root-hub timer from causing an unexpected status poll. This additional complexity would not be needed if the HCD framework had provided separate stop() and release() callbacks instead of just stop(). This lack could be fixed at some future time (although it would require changes to every host controller driver); when that happens this patch won't be needed any more. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2010-06-09 17:34:17 -04:00
USB: don't stop root-hub status polls too soon This patch (as1390) fixes a problem that crops up when a UHCI host controller is unbound from uhci-hcd while there are still some active URBs. The URBs have to be unlinked when the root hub is unregistered, and uhci-hcd relies upon root-hub status polls as part of its unlinking procedure. But usb_hcd_poll_rh_status() won't make those status calls if hcd->rh_registered is clear, and the flag is cleared _before_ the unregistration takes place. Since hcd->rh_registered is used for other things and needs to be cleared early, the solution is to add a new flag (rh_pollable) and use it instead. It gets cleared _after_ the root hub is unregistered. Now that the status polls don't end too soon, we have to make sure they also don't occur too late -- after the root hub's usb_device structure or the HCD's private structures are deallocated. Therefore the patch adds usb_get_device() and usb_put_device() calls to protect the root hub structure, and it adds an extra del_timer_sync() to prevent the root-hub timer from causing an unexpected status poll. This additional complexity would not be needed if the HCD framework had provided separate stop() and release() callbacks instead of just stop(). This lack could be fixed at some future time (although it would require changes to every host controller driver); when that happens this patch won't be needed any more. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2010-06-09 17:34:17 -04:00
USB: don't stop root-hub status polls too soon This patch (as1390) fixes a problem that crops up when a UHCI host controller is unbound from uhci-hcd while there are still some active URBs. The URBs have to be unlinked when the root hub is unregistered, and uhci-hcd relies upon root-hub status polls as part of its unlinking procedure. But usb_hcd_poll_rh_status() won't make those status calls if hcd->rh_registered is clear, and the flag is cleared _before_ the unregistration takes place. Since hcd->rh_registered is used for other things and needs to be cleared early, the solution is to add a new flag (rh_pollable) and use it instead. It gets cleared _after_ the root hub is unregistered. Now that the status polls don't end too soon, we have to make sure they also don't occur too late -- after the root hub's usb_device structure or the HCD's private structures are deallocated. Therefore the patch adds usb_get_device() and usb_put_device() calls to protect the root hub structure, and it adds an extra del_timer_sync() to prevent the root-hub timer from causing an unexpected status poll. This additional complexity would not be needed if the HCD framework had provided separate stop() and release() callbacks instead of just stop(). This lack could be fixed at some future time (although it would require changes to every host controller driver); when that happens this patch won't be needed any more. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2010-06-09 17:34:17 -04:00
USB: don't stop root-hub status polls too soon This patch (as1390) fixes a problem that crops up when a UHCI host controller is unbound from uhci-hcd while there are still some active URBs. The URBs have to be unlinked when the root hub is unregistered, and uhci-hcd relies upon root-hub status polls as part of its unlinking procedure. But usb_hcd_poll_rh_status() won't make those status calls if hcd->rh_registered is clear, and the flag is cleared _before_ the unregistration takes place. Since hcd->rh_registered is used for other things and needs to be cleared early, the solution is to add a new flag (rh_pollable) and use it instead. It gets cleared _after_ the root hub is unregistered. Now that the status polls don't end too soon, we have to make sure they also don't occur too late -- after the root hub's usb_device structure or the HCD's private structures are deallocated. Therefore the patch adds usb_get_device() and usb_put_device() calls to protect the root hub structure, and it adds an extra del_timer_sync() to prevent the root-hub timer from causing an unexpected status poll. This additional complexity would not be needed if the HCD framework had provided separate stop() and release() callbacks instead of just stop(). This lack could be fixed at some future time (although it would require changes to every host controller driver); when that happens this patch won't be needed any more. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2010-06-09 17:34:17 -04:00
USB: don't stop root-hub status polls too soon This patch (as1390) fixes a problem that crops up when a UHCI host controller is unbound from uhci-hcd while there are still some active URBs. The URBs have to be unlinked when the root hub is unregistered, and uhci-hcd relies upon root-hub status polls as part of its unlinking procedure. But usb_hcd_poll_rh_status() won't make those status calls if hcd->rh_registered is clear, and the flag is cleared _before_ the unregistration takes place. Since hcd->rh_registered is used for other things and needs to be cleared early, the solution is to add a new flag (rh_pollable) and use it instead. It gets cleared _after_ the root hub is unregistered. Now that the status polls don't end too soon, we have to make sure they also don't occur too late -- after the root hub's usb_device structure or the HCD's private structures are deallocated. Therefore the patch adds usb_get_device() and usb_put_device() calls to protect the root hub structure, and it adds an extra del_timer_sync() to prevent the root-hub timer from causing an unexpected status poll. This additional complexity would not be needed if the HCD framework had provided separate stop() and release() callbacks instead of just stop(). This lack could be fixed at some future time (although it would require changes to every host controller driver); when that happens this patch won't be needed any more. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2010-06-09 17:34:17 -04:00
USB: don't stop root-hub status polls too soon This patch (as1390) fixes a problem that crops up when a UHCI host controller is unbound from uhci-hcd while there are still some active URBs. The URBs have to be unlinked when the root hub is unregistered, and uhci-hcd relies upon root-hub status polls as part of its unlinking procedure. But usb_hcd_poll_rh_status() won't make those status calls if hcd->rh_registered is clear, and the flag is cleared _before_ the unregistration takes place. Since hcd->rh_registered is used for other things and needs to be cleared early, the solution is to add a new flag (rh_pollable) and use it instead. It gets cleared _after_ the root hub is unregistered. Now that the status polls don't end too soon, we have to make sure they also don't occur too late -- after the root hub's usb_device structure or the HCD's private structures are deallocated. Therefore the patch adds usb_get_device() and usb_put_device() calls to protect the root hub structure, and it adds an extra del_timer_sync() to prevent the root-hub timer from causing an unexpected status poll. This additional complexity would not be needed if the HCD framework had provided separate stop() and release() callbacks instead of just stop(). This lack could be fixed at some future time (although it would require changes to every host controller driver); when that happens this patch won't be needed any more. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2010-06-09 17:34:17 -04:00
USB: don't stop root-hub status polls too soon This patch (as1390) fixes a problem that crops up when a UHCI host controller is unbound from uhci-hcd while there are still some active URBs. The URBs have to be unlinked when the root hub is unregistered, and uhci-hcd relies upon root-hub status polls as part of its unlinking procedure. But usb_hcd_poll_rh_status() won't make those status calls if hcd->rh_registered is clear, and the flag is cleared _before_ the unregistration takes place. Since hcd->rh_registered is used for other things and needs to be cleared early, the solution is to add a new flag (rh_pollable) and use it instead. It gets cleared _after_ the root hub is unregistered. Now that the status polls don't end too soon, we have to make sure they also don't occur too late -- after the root hub's usb_device structure or the HCD's private structures are deallocated. Therefore the patch adds usb_get_device() and usb_put_device() calls to protect the root hub structure, and it adds an extra del_timer_sync() to prevent the root-hub timer from causing an unexpected status poll. This additional complexity would not be needed if the HCD framework had provided separate stop() and release() callbacks instead of just stop(). This lack could be fixed at some future time (although it would require changes to every host controller driver); when that happens this patch won't be needed any more. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2010-06-09 17:34:17 -04:00
USB: don't stop root-hub status polls too soon This patch (as1390) fixes a problem that crops up when a UHCI host controller is unbound from uhci-hcd while there are still some active URBs. The URBs have to be unlinked when the root hub is unregistered, and uhci-hcd relies upon root-hub status polls as part of its unlinking procedure. But usb_hcd_poll_rh_status() won't make those status calls if hcd->rh_registered is clear, and the flag is cleared _before_ the unregistration takes place. Since hcd->rh_registered is used for other things and needs to be cleared early, the solution is to add a new flag (rh_pollable) and use it instead. It gets cleared _after_ the root hub is unregistered. Now that the status polls don't end too soon, we have to make sure they also don't occur too late -- after the root hub's usb_device structure or the HCD's private structures are deallocated. Therefore the patch adds usb_get_device() and usb_put_device() calls to protect the root hub structure, and it adds an extra del_timer_sync() to prevent the root-hub timer from causing an unexpected status poll. This additional complexity would not be needed if the HCD framework had provided separate stop() and release() callbacks instead of just stop(). This lack could be fixed at some future time (although it would require changes to every host controller driver); when that happens this patch won't be needed any more. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2010-06-09 17:34:17 -04:00
USB: don't stop root-hub status polls too soon This patch (as1390) fixes a problem that crops up when a UHCI host controller is unbound from uhci-hcd while there are still some active URBs. The URBs have to be unlinked when the root hub is unregistered, and uhci-hcd relies upon root-hub status polls as part of its unlinking procedure. But usb_hcd_poll_rh_status() won't make those status calls if hcd->rh_registered is clear, and the flag is cleared _before_ the unregistration takes place. Since hcd->rh_registered is used for other things and needs to be cleared early, the solution is to add a new flag (rh_pollable) and use it instead. It gets cleared _after_ the root hub is unregistered. Now that the status polls don't end too soon, we have to make sure they also don't occur too late -- after the root hub's usb_device structure or the HCD's private structures are deallocated. Therefore the patch adds usb_get_device() and usb_put_device() calls to protect the root hub structure, and it adds an extra del_timer_sync() to prevent the root-hub timer from causing an unexpected status poll. This additional complexity would not be needed if the HCD framework had provided separate stop() and release() callbacks instead of just stop(). This lack could be fixed at some future time (although it would require changes to every host controller driver); when that happens this patch won't be needed any more. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2010-06-09 17:34:17 -04:00