Skip to content

Commit

Permalink
USB: fsl_qe_udc: send ZLP when zero flag and length % maxpacket == 0
Browse files Browse the repository at this point in the history
The driver did not take the zero flag in the USB request. If the
request length is the same as the endpoint's maxpacket, an additional
ZLP with no data has to be transmitted.

The method used here is inspired to what is done in fsl_udc_core.c
(and pxa27x_udc.c and at91_udc.c) where this is supported.

There already was a discussion about this topic with people from
Keymile, and I propose here a better implementation:

http://thread.gmane.org/gmane.linux.usb.general/38951

Signed-off-by: Valentin Longchamp <valentin.longchamp@keymile.com>
Acked-by: Li Yang <leoli@freescale.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Valentin Longchamp authored and Greg Kroah-Hartman committed Apr 13, 2011
1 parent cb62d65 commit d834508
Showing 1 changed file with 18 additions and 2 deletions.
20 changes: 18 additions & 2 deletions drivers/usb/gadget/fsl_qe_udc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1148,6 +1148,12 @@ static int qe_ep_tx(struct qe_ep *ep, struct qe_frame *frame)
static int txcomplete(struct qe_ep *ep, unsigned char restart)
{
if (ep->tx_req != NULL) {
struct qe_req *req = ep->tx_req;
unsigned zlp = 0, last_len = 0;

last_len = min_t(unsigned, req->req.length - ep->sent,
ep->ep.maxpacket);

if (!restart) {
int asent = ep->last;
ep->sent += asent;
Expand All @@ -1156,9 +1162,18 @@ static int txcomplete(struct qe_ep *ep, unsigned char restart)
ep->last = 0;
}

/* zlp needed when req->re.zero is set */
if (req->req.zero) {
if (last_len == 0 ||
(req->req.length % ep->ep.maxpacket) != 0)
zlp = 0;
else
zlp = 1;
} else
zlp = 0;

/* a request already were transmitted completely */
if ((ep->tx_req->req.length - ep->sent) <= 0) {
ep->tx_req->req.actual = (unsigned int)ep->sent;
if (((ep->tx_req->req.length - ep->sent) <= 0) && !zlp) {
done(ep, ep->tx_req, 0);
ep->tx_req = NULL;
ep->last = 0;
Expand Down Expand Up @@ -1191,6 +1206,7 @@ static int qe_usb_senddata(struct qe_ep *ep, struct qe_frame *frame)
buf = (u8 *)ep->tx_req->req.buf + ep->sent;
if (buf && size) {
ep->last = size;
ep->tx_req->req.actual += size;
frame_set_data(frame, buf);
frame_set_length(frame, size);
frame_set_status(frame, FRAME_OK);
Expand Down

0 comments on commit d834508

Please sign in to comment.