Re: [PATCH v2 4/7] usb: chipidea: create the gadget at ci_hdrc_probe even at host role

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Nov 20, 2012 at 10:12:30PM +0800, Peter Chen wrote:
> On Tue, Nov 20, 2012 at 02:08:18PM +0200, Alexander Shishkin wrote:
> > Peter Chen <peter.chen@xxxxxxxxxxxxx> writes:
> > 
> > > Since we can't load/unload gadget module on the fly, we can't
> > > de-init gadget structure during the otg switch.
> > > We have to create gadget at the probe function no matter current
> > > role is the host or device, of cource, the gadget will not
> > > be created for host-only port.
> > 
> > No, this is much worse than the previous version.
> > 
> > >
> > > Signed-off-by: Peter Chen <peter.chen@xxxxxxxxxxxxx>
> > > ---
> > >  drivers/usb/chipidea/ci.h   |   10 +++++++---
> > >  drivers/usb/chipidea/core.c |    7 ++++++-
> > >  2 files changed, 13 insertions(+), 4 deletions(-)
> > >
> > > diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
> > > index d32f932..c704aa7 100644
> > > --- a/drivers/usb/chipidea/ci.h
> > > +++ b/drivers/usb/chipidea/ci.h
> > > @@ -188,9 +188,13 @@ static inline int ci_role_start(struct ci13xxx *ci, enum ci_role role)
> > >  	if (!ci->roles[role])
> > >  		return -ENXIO;
> > >  
> > > -	ret = ci->roles[role]->start(ci);
> > > -	if (!ret)
> > > -		ci->role = role;
> > > +	/* Only host role is supported at this function*/
> > > +	if (role == CI_ROLE_HOST) {
> > > +		ret = ci->roles[role]->start(ci);
> > > +		if (!ret)
> > > +			ci->role = role;
> > > +	}
> > > +
> > >  	return ret;
> > >  }
> > 
> > This is bad in a number of ways. What we need is add a "destroy" method
> > to the role and not add
> > 
> >   if (ci->role == CI_ROLE_HOST)
> >     hackity_hackity();
> > 
> > to ten different places in the driver. This is really bad, even worse
> > than the fact that with this patch you're returning an uninitialized
> > 'ret' in case of non-host, which (correct me if I'm wrong) should
> > explode straight away, which in turn makes me wonder how is this
> > patchset fully tested as it claims to be.
> 
> Oh, my fault, maybe this uninitialized value is just 0 at my test.
> I will consider this problem more.

How about this:

/* prepare for switch to device */
static int udc_id_switch_for_device(struct ci13xxx *ci)
{
	usb_gadget_vbus_disconnect(&ci->gadget);
	/* host doesn't care B_SESSION_VALID event */
	hw_write(ci, OP_OTGSC, OTGSC_BSVIE, ~OTGSC_BSVIE);
	hw_write(ci, OP_OTGSC, OTGSC_BSVIS, OTGSC_BSVIS);		
	ci->role = CI_ROLE_END;
}

/* prepare for switch to host */
static int udc_id_switch_for_host(struct ci13xxx *ci)
{
	ci->role = role;
	hw_write(ci, OP_OTGSC, OTGSC_BSVIS, OTGSC_BSVIS);
	hw_write(ci, OP_OTGSC, OTGSC_BSVIE, OTGSC_BSVIE);
}

struct ci_role_driver device {
	.init = udc_start;
	.start = udc_id_switch_for_device;
	.stop = udc_id_switch_for_host;
	.destroy = udc_stop;
};

struct ci_role_driver host {
	.init = host_start;
	.start = host_start;
	.stop = host_stop;
	.destroy = stop_stop;

};

At probe call role .init. At remove, call role .destroy
During id_switch, just call ci_role_stop/ci_role_start.

For host mode at otg port during init case, I still think we
should call device .init, as the modprobe gadget will
fail if device .init isn't called, like the "modprobe g_ether"
will fail at user's init.rc.

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux