summaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2005-11-29 12:08:15 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2006-01-04 13:51:40 -0800
commit3cf0a22e8b1b3f44288db773d315e72e89d51c4c (patch)
treeb2b9e6d717b317a6439d9e5c1cf2333148759af0 /drivers/usb
parenta21d4fed4b00eaf7e7c3b2e2b25de24f540bfa66 (diff)
downloadblackbird-op-linux-3cf0a22e8b1b3f44288db773d315e72e89d51c4c.tar.gz
blackbird-op-linux-3cf0a22e8b1b3f44288db773d315e72e89d51c4c.zip
[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>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/gadget/dummy_hcd.c43
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;
}
OpenPOWER on IntegriCloud