summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2005-05-02 19:25:17 +0400
committerGreg Kroah-Hartman <gregkh@suse.de>2005-06-28 01:43:51 +0400
commit5742b0c95026c817d9c266174ca39a909e8d38ca (patch)
tree4f94fd2d99c134e9d600983b834014b933fca7c6 /drivers
parent65111084c63d7674dc37833e8eb59cfdaa4d0bda (diff)
downloadlinux-5742b0c95026c817d9c266174ca39a909e8d38ca.tar.xz
[PATCH] USB dummy_hcd: Partial OTG emulation
Partial OTG support for dummy_hcd, mostly as a framework for further work. It emulates the new OTG flags in the host and peripheral frameworks, if that option is configured. But it's incomplete: - Resetting the peripheral needs to clear the OTG state bits; a second enumeration won't work correctly. - This stops modeling HNP right when roles should switch the first time. It should probably disconnect, then set the usb_bus.is_b_host and usb_gadget.is_a_peripheral flags; then it'd enumerate almost normally, except for the role reversal. Roles could then switch a second time, back to "normal" (with those flags cleared). - SRP should be modeled as "resume from port-unpowered", which is a state that usbcore doesn't yet use. HNP can be triggered by enabling the OTG whitelist and configuring a gadget driver that's not in that list; or by configuring Gadget Zero to identify itself as the HNP test device. Sent-by: David Brownell <david-b@pacbell.net> Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/gadget/dummy_hcd.c30
1 files changed, 28 insertions, 2 deletions
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index 1918d10f7569..e9b95df5b23d 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -601,8 +601,10 @@ static int dummy_wakeup (struct usb_gadget *_gadget)
struct dummy *dum;
dum = gadget_to_dummy (_gadget);
- if ((dum->devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) == 0
- || !(dum->port_status & (1 << USB_PORT_FEAT_SUSPEND)))
+ if (!(dum->port_status & (1 << USB_PORT_FEAT_SUSPEND))
+ || !(dum->devstatus &
+ ( (1 << USB_DEVICE_B_HNP_ENABLE)
+ | (1 << USB_DEVICE_REMOTE_WAKEUP))))
return -EINVAL;
/* hub notices our request, issues downstream resume, etc */
@@ -713,6 +715,9 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver)
dum->gadget.ops = &dummy_ops;
dum->gadget.is_dualspeed = 1;
+ /* maybe claim OTG support, though we won't complete HNP */
+ dum->gadget.is_otg = (dummy_to_hcd(dum)->self.otg_port != 0);
+
dum->devstatus = 0;
dum->resuming = 0;
@@ -1215,6 +1220,16 @@ restart:
switch (setup.wValue) {
case USB_DEVICE_REMOTE_WAKEUP:
break;
+ case USB_DEVICE_B_HNP_ENABLE:
+ dum->gadget.b_hnp_enable = 1;
+ break;
+ case USB_DEVICE_A_HNP_SUPPORT:
+ dum->gadget.a_hnp_support = 1;
+ break;
+ case USB_DEVICE_A_ALT_HNP_SUPPORT:
+ dum->gadget.a_alt_hnp_support
+ = 1;
+ break;
default:
value = -EOPNOTSUPP;
}
@@ -1533,6 +1548,13 @@ static int dummy_hub_control (
spin_unlock (&dum->lock);
dum->driver->suspend (&dum->gadget);
spin_lock (&dum->lock);
+ /* HNP would happen here; for now we
+ * assume b_bus_req is always true.
+ */
+ if (((1 << USB_DEVICE_B_HNP_ENABLE)
+ & dum->devstatus) != 0)
+ dev_dbg (dummy_dev(dum),
+ "no HNP yet!\n");
}
}
break;
@@ -1648,6 +1670,10 @@ static int dummy_start (struct usb_hcd *hcd)
hcd->power_budget = 8;
hcd->state = HC_STATE_RUNNING;
+#ifdef CONFIG_USB_OTG
+ hcd->self.otg_port = 1;
+#endif
+
/* FIXME 'urbs' should be a per-device thing, maybe in usbcore */
device_create_file (dummy_dev(dum), &dev_attr_urbs);
return 0;