[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>
This commit is contained in:
parent
65111084c6
commit
5742b0c950
|
@ -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)
|
||||||
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 @@ restart:
|
||||||
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 (
|
||||||
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)
|
||||||
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;
|
||||||
|
|
Loading…
Reference in a new issue