]> rtime.felk.cvut.cz Git - zynq/linux.git/commitdiff
usb: xilinxps_udc: Fixed zero length packet issue with control endpoint.
authorNaveen Mamindlapalli <naveen.mamindlapalli@xilinx.com>
Mon, 25 Mar 2013 11:35:19 +0000 (17:05 +0530)
committerMichal Simek <michal.simek@xilinx.com>
Mon, 25 Mar 2013 15:58:33 +0000 (16:58 +0100)
Fixed sending a separate zero length packet for control IN endpoint. The
ZLT bit in dQH takes care of it. Configured control OUT endpoint not to
wait for zero length packet from the host controller. See USB 2.0 section
5.5.3 for more details.

Signed-off-by: Naveen Mamindlapalli <naveenm@xilinx.com>
drivers/usb/gadget/xilinx_usbps_udc.c

index 38cd054ffdd0d9031fc725a8d665ba9a000272e5..f127fbb87a24cad8362d99ace090b40e93f8ac57 100644 (file)
@@ -806,8 +806,12 @@ static void ep0_setup(struct xusbps_udc *udc)
 {
        /* the intialization of an ep includes: fields in QH, Regs,
         * xusbps_ep struct */
+       /*
+        * For control OUT endpoint, don't need to wait for zlp from host
+        * (see usb 2.0 spec, section 5.5.3)
+        */
        struct_ep_qh_setup(udc, 0, USB_RECV, USB_ENDPOINT_XFER_CONTROL,
-                       USB_MAX_CTRL_PAYLOAD, 0, 0);
+                       USB_MAX_CTRL_PAYLOAD, 1, 0);
        struct_ep_qh_setup(udc, 0, USB_SEND, USB_ENDPOINT_XFER_CONTROL,
                        USB_MAX_CTRL_PAYLOAD, 0, 0);
        dr_ep_setup(0, USB_RECV, USB_ENDPOINT_XFER_CONTROL);
@@ -1099,7 +1103,15 @@ static struct ep_td_struct *xusbps_build_dtd(struct xusbps_req *req, unsigned
 
        /* zlp is needed if req->req.zero is set */
        if (req->req.zero) {
-               if (*length == 0 || (*length % req->ep->ep.maxpacket) != 0)
+               /*
+                * There is no need for a separate zlp dtd for control IN
+                * endpoint. The ZLT bit in dQH takes care.
+                */
+               if ((ep_index(req->ep) == 0) &&
+                               (req->req.length == req->req.actual) &&
+                               !(req->req.length % req->ep->ep.maxpacket))
+                       *is_last = 1;
+               else if (*length == 0 || (*length % req->ep->ep.maxpacket) != 0)
                        *is_last = 1;
                else
                        *is_last = 0;