Commit 2b33fdb4 authored by David Brownell's avatar David Brownell Committed by Greg Kroah-Hartman

[PATCH] USB OTG: add usb_bus_start_enum() (1/5)

Define a new usb_bus_start_enum() routine that's available with OTG.
It starts immediate enumeration (port reset) and makes khubd wake up
later.  Non-OTG code could start to use this, given some attention to
HC-specific reset timing issues.
Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: default avatarGreg Kroah-Hartman <greg@kroah.com>
parent 820156fa
...@@ -1404,6 +1404,45 @@ static int hcd_hub_resume (struct usb_bus *bus) ...@@ -1404,6 +1404,45 @@ static int hcd_hub_resume (struct usb_bus *bus)
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
#ifdef CONFIG_USB_OTG
/**
* usb_bus_start_enum - start immediate enumeration (for OTG)
* @bus: the bus (must use hcd framework)
* @port: 1-based number of port; usually bus->otg_port
* Context: in_interrupt()
*
* Starts enumeration, with an immediate reset followed later by
* khubd identifying and possibly configuring the device.
* This is needed by OTG controller drivers, where it helps meet
* HNP protocol timing requirements for starting a port reset.
*/
int usb_bus_start_enum(struct usb_bus *bus, unsigned port_num)
{
struct usb_hcd *hcd;
int status = -EOPNOTSUPP;
/* NOTE: since HNP can't start by grabbing the bus's address0_sem,
* boards with root hubs hooked up to internal devices (instead of
* just the OTG port) may need more attention to resetting...
*/
hcd = container_of (bus, struct usb_hcd, self);
if (port_num && hcd->driver->start_port_reset)
status = hcd->driver->start_port_reset(hcd, port_num);
/* run khubd shortly after (first) root port reset finishes;
* it may issue others, until at least 50 msecs have passed.
*/
if (status == 0)
mod_timer(&hcd->rh_timer, jiffies + msecs_to_jiffies(10));
return status;
}
EXPORT_SYMBOL (usb_bus_start_enum);
#endif
/*-------------------------------------------------------------------------*/
/* called by khubd, rmmod, apmd, or other thread for hcd-private cleanup. /* called by khubd, rmmod, apmd, or other thread for hcd-private cleanup.
* we're guaranteed that the device is fully quiesced. also, that each * we're guaranteed that the device is fully quiesced. also, that each
* endpoint has been hcd_endpoint_disabled. * endpoint has been hcd_endpoint_disabled.
......
...@@ -212,6 +212,7 @@ struct hc_driver { ...@@ -212,6 +212,7 @@ struct hc_driver {
char *buf, u16 wLength); char *buf, u16 wLength);
int (*hub_suspend)(struct usb_hcd *); int (*hub_suspend)(struct usb_hcd *);
int (*hub_resume)(struct usb_hcd *); int (*hub_resume)(struct usb_hcd *);
int (*start_port_reset)(struct usb_hcd *, unsigned port_num);
}; };
extern void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb, struct pt_regs *regs); extern void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb, struct pt_regs *regs);
......
...@@ -114,3 +114,5 @@ otg_start_srp(struct otg_transceiver *otg) ...@@ -114,3 +114,5 @@ otg_start_srp(struct otg_transceiver *otg)
} }
/* for OTG controller drivers (and maybe other stuff) */
extern int usb_bus_start_enum(struct usb_bus *bus, unsigned port_num);
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