Commit 5742b0c9 authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman

[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: default avatarDavid Brownell <david-b@pacbell.net>
Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 65111084
...@@ -601,8 +601,10 @@ static int dummy_wakeup (struct usb_gadget *_gadget) ...@@ -601,8 +601,10 @@ static int dummy_wakeup (struct usb_gadget *_gadget)
struct dummy *dum; struct dummy *dum;
dum = gadget_to_dummy (_gadget); dum = gadget_to_dummy (_gadget);
if ((dum->devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) == 0 if (!(dum->port_status & (1 << USB_PORT_FEAT_SUSPEND))
|| !(dum->port_status & (1 << USB_PORT_FEAT_SUSPEND))) || !(dum->devstatus &
( (1 << USB_DEVICE_B_HNP_ENABLE)
| (1 << USB_DEVICE_REMOTE_WAKEUP))))
return -EINVAL; return -EINVAL;
/* hub notices our request, issues downstream resume, etc */ /* hub notices our request, issues downstream resume, etc */
...@@ -713,6 +715,9 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver) ...@@ -713,6 +715,9 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver)
dum->gadget.ops = &dummy_ops; dum->gadget.ops = &dummy_ops;
dum->gadget.is_dualspeed = 1; 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->devstatus = 0;
dum->resuming = 0; dum->resuming = 0;
...@@ -1215,6 +1220,16 @@ static void dummy_timer (unsigned long _dum) ...@@ -1215,6 +1220,16 @@ static void dummy_timer (unsigned long _dum)
switch (setup.wValue) { switch (setup.wValue) {
case USB_DEVICE_REMOTE_WAKEUP: case USB_DEVICE_REMOTE_WAKEUP:
break; 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: default:
value = -EOPNOTSUPP; value = -EOPNOTSUPP;
} }
...@@ -1533,6 +1548,13 @@ static int dummy_hub_control ( ...@@ -1533,6 +1548,13 @@ static int dummy_hub_control (
spin_unlock (&dum->lock); spin_unlock (&dum->lock);
dum->driver->suspend (&dum->gadget); dum->driver->suspend (&dum->gadget);
spin_lock (&dum->lock); 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; break;
...@@ -1648,6 +1670,10 @@ static int dummy_start (struct usb_hcd *hcd) ...@@ -1648,6 +1670,10 @@ static int dummy_start (struct usb_hcd *hcd)
hcd->power_budget = 8; hcd->power_budget = 8;
hcd->state = HC_STATE_RUNNING; 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 */ /* FIXME 'urbs' should be a per-device thing, maybe in usbcore */
device_create_file (dummy_dev(dum), &dev_attr_urbs); device_create_file (dummy_dev(dum), &dev_attr_urbs);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment