|
@@ -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;
|
|
@@ -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;
|
|
@@ -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);
|