Re: hardware driver <-> gadget driver interaction

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

 



On Fri, 20 Jan 2012, Nikolai Zhubr wrote:

> Hello people,
> 
> continueing my fight with DWC OTG controller I'm now pretty sure I've 
> found a place exactly related to why g_file_storage DOES work whereas 
> g_serial does NOT. Sorry for my ignorance, but could someone please 
> explain the meaning of the lengthy confused comment in code fragment 
> listed below, and does the assumptions implied there even apply 
> nowadays? (The code was targeted for 2.6.22 and earlier, so it is quite 
> ancient and AFAIK it was not revised much since)
> 
> Thank you.
> Nikolai
> 
> /**
>   * This functions delegates the setup command to the gadget driver.
>   */
> static inline void do_gadget_setup(dwc_otg_pcd_t *pcd,
> 					struct usb_ctrlrequest * ctrl)
> {
> 	int ret = 0;
> 	if (pcd->driver && pcd->driver->setup) {
> 		SPIN_UNLOCK(&pcd->lock);
> 		ret = pcd->driver->setup(&pcd->gadget, ctrl);
> 		SPIN_LOCK(&pcd->lock);
> 		if (ret < 0) {
> 			ep0_do_stall(pcd, ret);
> 		}
> 
> 	/** @todo This is a g_file_storage gadget driver specific
> 	 * workaround: a DELAYED_STATUS result from the fsg_setup
> 	 * routine will result in the gadget queueing a EP0 IN status
> 	 * phase for a two-stage control transfer. Exactly the same as
> 	 * a SET_CONFIGURATION/SET_INTERFACE except that this is a class
> 	 * specific request.  Need a generic way to know when the gadget
> 	 * driver will queue the status phase.	Can we assume when we
> 	 * call the gadget driver setup() function that it will always
> 	 * queue and require the following flag?  Need to look into
> 	 * this.
> 	 */
> 
> 		if (ret == 256 + 999) {
> 			pcd->request_config = 1;
> 		}
> 	}
> }

The comment and the code are both out of date.  Instead of checking for 
256 + 999, it should now check for USB_GADGET_DELAYED_STATUS (defined 
in include/linux/usb/composite.h).

The idea is simple enough, although why it was implemented as shown 
above is a mystery.  Nowadays it should all be handled internally by 
composite.c.

A USB device isn't supposed to carry out the status stage of a control
transfer until after it has finished doing whatever operation the
transfer specifies.  (There's one exception -- the status stage for a
Set Address request must be done before the device changes its bus
address.)  Normally a gadget driver can do the required operation from
within its setup routine, in which case the setup routine will take
care of queuing the status stage of the transfer.

But some operations require more time, or cannot be carried out in 
interrupt context.  In these cases the setup routine cannot queue the 
status stage of the control transfer -- it delays the status stage 
until later.  USB_GADGET_DELAYED_STATUS is the value it returns to 
indicate this has happened.

Alan Stern

--
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