Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 207943
b: refs/heads/master
c: 6d88e67
h: refs/heads/master
i:
  207941: d3fb6a2
  207939: 653fbaf
  207935: 1dfc50f
v: v3
  • Loading branch information
Alan Stern authored and Greg Kroah-Hartman committed Aug 10, 2010
1 parent 80097be commit 77be838
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 8 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 96e077ae347912dfce0e93f5958efc3ed6f311f4
refs/heads/master: 6d88e6792574497bfac9a81403cc47712040636f
32 changes: 25 additions & 7 deletions trunk/drivers/usb/core/hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -667,7 +667,7 @@ void usb_hcd_poll_rh_status(struct usb_hcd *hcd)
unsigned long flags;
char buffer[6]; /* Any root hubs with > 31 ports? */

if (unlikely(!hcd->rh_registered))
if (unlikely(!hcd->rh_pollable))
return;
if (!hcd->uses_new_polling && !hcd->status_urb)
return;
Expand Down Expand Up @@ -2217,6 +2217,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
retval = -ENOMEM;
goto err_allocate_root_hub;
}
hcd->self.root_hub = rhdev;

switch (hcd->driver->flags & HCD_MASK) {
case HCD_USB11:
Expand All @@ -2231,7 +2232,6 @@ int usb_add_hcd(struct usb_hcd *hcd,
default:
goto err_set_rh_speed;
}
hcd->self.root_hub = rhdev;

/* wakeup flag init defaults to "everything works" for root hubs,
* but drivers can override it in reset() if needed, along with
Expand All @@ -2246,6 +2246,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
dev_err(hcd->self.controller, "can't setup\n");
goto err_hcd_driver_setup;
}
hcd->rh_pollable = 1;

/* NOTE: root hub and controller capabilities may not be the same */
if (device_can_wakeup(hcd->self.controller)
Expand Down Expand Up @@ -2315,9 +2316,12 @@ int usb_add_hcd(struct usb_hcd *hcd,
cancel_work_sync(&hcd->wakeup_work);
#endif
mutex_lock(&usb_bus_list_lock);
usb_disconnect(&hcd->self.root_hub);
usb_disconnect(&rhdev); /* Sets rhdev to NULL */
mutex_unlock(&usb_bus_list_lock);
err_register_root_hub:
hcd->rh_pollable = 0;
hcd->poll_rh = 0;
del_timer_sync(&hcd->rh_timer);
hcd->driver->stop(hcd);
hcd->state = HC_STATE_HALT;
hcd->poll_rh = 0;
Expand All @@ -2328,8 +2332,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
err_request_irq:
err_hcd_driver_setup:
err_set_rh_speed:
hcd->self.root_hub = NULL;
usb_put_dev(rhdev);
usb_put_dev(hcd->self.root_hub);
err_allocate_root_hub:
usb_deregister_bus(&hcd->self);
err_register_bus:
Expand All @@ -2348,9 +2351,12 @@ EXPORT_SYMBOL_GPL(usb_add_hcd);
*/
void usb_remove_hcd(struct usb_hcd *hcd)
{
struct usb_device *rhdev = hcd->self.root_hub;

dev_info(hcd->self.controller, "remove, state %x\n", hcd->state);

sysfs_remove_group(&hcd->self.root_hub->dev.kobj, &usb_bus_attr_group);
usb_get_dev(rhdev);
sysfs_remove_group(&rhdev->dev.kobj, &usb_bus_attr_group);

if (HC_IS_RUNNING (hcd->state))
hcd->state = HC_STATE_QUIESCING;
Expand All @@ -2365,17 +2371,29 @@ void usb_remove_hcd(struct usb_hcd *hcd)
#endif

mutex_lock(&usb_bus_list_lock);
usb_disconnect(&hcd->self.root_hub);
usb_disconnect(&rhdev); /* Sets rhdev to NULL */
mutex_unlock(&usb_bus_list_lock);

/* Prevent any more root-hub status calls from the timer.
* The HCD might still restart the timer (if a port status change
* interrupt occurs), but usb_hcd_poll_rh_status() won't invoke
* the hub_status_data() callback.
*/
hcd->rh_pollable = 0;
hcd->poll_rh = 0;
del_timer_sync(&hcd->rh_timer);

hcd->driver->stop(hcd);
hcd->state = HC_STATE_HALT;

/* In case the HCD restarted the timer, stop it again. */
hcd->poll_rh = 0;
del_timer_sync(&hcd->rh_timer);

if (hcd->irq >= 0)
free_irq(hcd->irq, hcd);

usb_put_dev(hcd->self.root_hub);
usb_deregister_bus(&hcd->self);
hcd_buffer_destroy(hcd);
}
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/usb/hcd.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ struct usb_hcd {
#define HCD_FLAG_SAW_IRQ 0x00000002

unsigned rh_registered:1;/* is root hub registered? */
unsigned rh_pollable:1; /* may we poll the root hub? */

/* The next flag is a stopgap, to be removed when all the HCDs
* support the new root-hub polling mechanism. */
Expand Down

0 comments on commit 77be838

Please sign in to comment.