Re: [PATCH] usb: chipidea: udc: Disable auto ZLP generation on ep0

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

 



On Sun, Jul 06, 2014 at 09:26:02PM +0500, Abbas Raza wrote:
> From: Abbas Raza <Abbas_Raza@xxxxxxxxxx>
> 
> There are 2 methods for ZLP (zero-length packet) generation:
> 1) In software
> 2) Automatic generation by device controller
> 
> 1) is implemented in UDC driver and it attaches ZLP to IN packet if
>    descriptor->size < wLength
> 2) can be enabled/disabled by setting ZLT bit in the QH
> 
> When gadget ffs is connected to ubuntu host, the host sends
> get descriptor request and wLength in setup packet is 255 while the
> size of descriptor which will be sent by gadget in IN packet is
> 64 byte. So the composite driver sets req->zero = 1.
> In UDC driver following code will be executed then
> 
>         if (hwreq->req.zero && hwreq->req.length
>             && (hwreq->req.length % hwep->ep.maxpacket == 0))
>                 add_td_to_list(hwep, hwreq, 0);
> 
> Case-A:
> So in case of ubuntu host, UDC driver will attach a ZLP to the IN packet.
> ubuntu host will request 255 byte in IN request, gadget will send 64 byte
> with ZLP and host will come to know that there is no more data.
> But hold on, by default ZLT=0 for endpoint 0 so hardware also tries to
> automatically generate the ZLP which blocks enumeration for ~6 seconds due
> to endpoint 0 STALL, NAKs are sent to host for any requests (OUT/PING)
> 
> Case-B:
> In case when gadget ffs is connected to Apple device, Apple device sends
> setup packet with wLength=64. So descriptor->size = 64 and wLength=64
> therefore req->zero = 0 and UDC driver will not attach any ZLP to the
> IN packet. Apple device requests 64 bytes, gets 64 bytes and doesn't
> further request for IN data. But ZLT=0 by default for endpoint 0 so
> hardware tries to automatically generate the ZLP which blocks enumeration
> for ~6 seconds due to endpoint 0 STALL, NAKs are sent to host for any
> requests (OUT/PING)
> 
> According to USB2.0 specs:
> 
>     8.5.3.2 Variable-length Data Stage
>     A control pipe may have a variable-length data phase in which the
>     host requests more data than is contained in the specified data
>     structure. When all of the data structure is returned to the host,
>     the function should indicate that the Data stage is ended by
>     returning a packet that is shorter than the MaxPacketSize for the
>     pipe. If the data structure is an exact multiple of wMaxPacketSize
>     for the pipe, the function will return a zero-length packet to indicate
>     the end of the Data stage.
> 
> In Case-A mentioned above:
> If we disable software ZLP generation & ZLT=0 for endpoint 0 OR if software
> ZLP generation is not disabled but we set ZLT=1 for endpoint 0 then
> enumeration doesn't block for 6 seconds.
> 
> In Case-B mentioned above:
> If we disable software ZLP generation & ZLT=0 for endpoint then enumeration
> still blocks due to ZLP automatically generated by hardware and host not needing
> it. But if we keep software ZLP generation enabled but we set ZLT=1 for
> endpoint 0 then enumeration doesn't block for 6 seconds.
> 
> So the proper solution for this issue seems to disable automatic ZLP generation
> by hardware (i.e by setting ZLT=1 for endpoint 0) and let software (UDC driver)
> handle the ZLP generation based on req->zero field.
> 
> Signed-off-by: Abbas Raza <Abbas_Raza@xxxxxxxxxx>
> ---
>  drivers/usb/chipidea/udc.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
> index 7a12d13..2857dff 100644
> --- a/drivers/usb/chipidea/udc.c
> +++ b/drivers/usb/chipidea/udc.c
> @@ -1169,8 +1169,8 @@ static int ep_enable(struct usb_ep *ep,
>  
>  	if (hwep->type == USB_ENDPOINT_XFER_CONTROL)
>  		cap |= QH_IOS;
> -	if (hwep->num)
> -		cap |= QH_ZLT;
> +
> +	cap |= QH_ZLT;
>  	cap |= (hwep->ep.maxpacket << __ffs(QH_MAX_PKT)) & QH_MAX_PKT;
>  	/*
>  	 * For ISO-TX, we set mult at QH as the largest value, and use
> -- 
> 1.8.3.2
> 

Good fix, I will apply it after testing, thanks.

-- 

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