diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2005-11-29 12:08:15 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-01-04 13:51:40 -0800 |
commit | 3cf0a22e8b1b3f44288db773d315e72e89d51c4c (patch) | |
tree | b2b9e6d717b317a6439d9e5c1cf2333148759af0 | |
parent | a21d4fed4b00eaf7e7c3b2e2b25de24f540bfa66 (diff) |
[PATCH] USB Gadget: dummy_hcd: updates to hcd->state
This patch (as613) moves the updates to hcd->state in the dummy_hcd
driver to where they now belong. It also uses the new
HC_FLAG_HW_ACCESSIBLE flag in a way that simulates a real PCI
controller, and it adds checks for attempts to resume the bus while the
controller is suspended or to suspend the controller while the bus is
active.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/usb/gadget/dummy_hcd.c | 43 |
1 files changed, 31 insertions, 12 deletions
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 4932b07b316d..ce0d4b412dfe 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -1576,7 +1576,7 @@ static int dummy_hub_status (struct usb_hcd *hcd, char *buf) dum = hcd_to_dummy (hcd); spin_lock_irqsave (&dum->lock, flags); - if (hcd->state != HC_STATE_RUNNING) + if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) goto done; if (dum->resuming && time_after_eq (jiffies, dum->re_timeout)) { @@ -1623,7 +1623,7 @@ static int dummy_hub_control ( int retval = 0; unsigned long flags; - if (hcd->state != HC_STATE_RUNNING) + if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) return -ETIMEDOUT; dum = hcd_to_dummy (hcd); @@ -1756,9 +1756,12 @@ static int dummy_bus_suspend (struct usb_hcd *hcd) { struct dummy *dum = hcd_to_dummy (hcd); + dev_dbg (&hcd->self.root_hub->dev, "%s\n", __FUNCTION__); + spin_lock_irq (&dum->lock); dum->rh_state = DUMMY_RH_SUSPENDED; set_link_state (dum); + hcd->state = HC_STATE_SUSPENDED; spin_unlock_irq (&dum->lock); return 0; } @@ -1766,14 +1769,23 @@ static int dummy_bus_suspend (struct usb_hcd *hcd) static int dummy_bus_resume (struct usb_hcd *hcd) { struct dummy *dum = hcd_to_dummy (hcd); + int rc = 0; + + dev_dbg (&hcd->self.root_hub->dev, "%s\n", __FUNCTION__); spin_lock_irq (&dum->lock); - dum->rh_state = DUMMY_RH_RUNNING; - set_link_state (dum); - if (!list_empty(&dum->urbp_list)) - mod_timer (&dum->timer, jiffies); + if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) { + dev_warn (&hcd->self.root_hub->dev, "HC isn't running!\n"); + rc = -ENODEV; + } else { + dum->rh_state = DUMMY_RH_RUNNING; + set_link_state (dum); + if (!list_empty(&dum->urbp_list)) + mod_timer (&dum->timer, jiffies); + hcd->state = HC_STATE_RUNNING; + } spin_unlock_irq (&dum->lock); - return 0; + return rc; } /*-------------------------------------------------------------------------*/ @@ -1933,12 +1945,19 @@ static int dummy_hcd_remove (struct platform_device *pdev) static int dummy_hcd_suspend (struct platform_device *pdev, pm_message_t state) { struct usb_hcd *hcd; + struct dummy *dum; + int rc = 0; dev_dbg (&pdev->dev, "%s\n", __FUNCTION__); - hcd = platform_get_drvdata (pdev); - hcd->state = HC_STATE_SUSPENDED; - return 0; + hcd = platform_get_drvdata (pdev); + dum = hcd_to_dummy (hcd); + if (dum->rh_state == DUMMY_RH_RUNNING) { + dev_warn(&pdev->dev, "Root hub isn't suspended!\n"); + rc = -EBUSY; + } else + clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + return rc; } static int dummy_hcd_resume (struct platform_device *pdev) @@ -1946,9 +1965,9 @@ static int dummy_hcd_resume (struct platform_device *pdev) struct usb_hcd *hcd; dev_dbg (&pdev->dev, "%s\n", __FUNCTION__); - hcd = platform_get_drvdata (pdev); - hcd->state = HC_STATE_RUNNING; + hcd = platform_get_drvdata (pdev); + set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); usb_hcd_poll_rh_status (hcd); return 0; } |