Re: [PATCHv3 2/4] usb: gadget: replace "is_dualspeed" with"max_speed"

From: Felipe Balbi
Date: Wed Aug 24 2011 - 19:04:27 EST


Hi,

On Wed, Aug 24, 2011 at 05:25:11PM +0200, Michal Nazarewicz wrote:
> On Wed, 24 Aug 2011 17:15:29 +0200, Alan Stern
> <stern@xxxxxxxxxxxxxxxxxxx> wrote:
>
> >On Wed, 24 Aug 2011, Michal Nazarewicz wrote:
> >
> >>I've found where my reasoning was faulty. The usb_gadget_driver's
> >>max_speed is set before all the functions get added so composite.c has
> >>no way to figure those things in advance. That's why we need to relay
> >>on usb_composite_driver's max_speed be set to a proper value.
> >
> >This is what Felipe was complaining about earlier. We shouldn't set
> >max_speed or allow the UDC to connect to the host until all the
> >functions have been added.
>
> We're not doing the latter. The functions are added in bind callback so
> (hopefully) UDC will first run the bind callback and then try connecting
> to host.
>
> And the former would be fixed if we allowed gadget driver to set max_speed
> in bind callback rather then prior to calling usb_gadget_probe_driver().

there's one catch. As of today, we always start UDCs with data pullups
connected, which means that we could connect to a host even before a
gadget driver is loaded. My point in moving to udc_start/udc_stop is
that the above would be take care of. See udc-core.c:

int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
int (*bind)(struct usb_gadget *))
{
....

if (udc_is_newstyle(udc)) {
ret = bind(udc->gadget);
if (ret)
goto err1;
ret = usb_gadget_udc_start(udc->gadget, driver);
if (ret) {
driver->unbind(udc->gadget);
goto err1;
}
usb_gadget_connect(udc->gadget);
} else {
ret = usb_gadget_start(udc->gadget, driver, bind);
if (ret)
goto err1;

}

...
}

If all UDCs are converted to udc_start()/udc_stop() we get the guarantee
that they will only conect to host after gadget driver is fully loaded
for free. We can also, finally, properly use the
usb_function_deactivate/usb_function_activate properly. So for each
registered function, composite.c calls usb_function_deactivate() and
function is _required_ to call usb_function_activate when it's ready
(for f_obex.c that would be when userland OBEX stack has opened
/dev/ttyGS*, for g_mass_storage that would be on function bind(), and so
on).

Then, when on gadget driver's bind() we can take this kind of spee
decision and pass that on to UDC driver.

--
balbi

Attachment: signature.asc
Description: Digital signature