diff options
Diffstat (limited to 'drivers/usb/gadget/fsl_qe_udc.c')
-rw-r--r-- | drivers/usb/gadget/fsl_qe_udc.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index aee7e3c53c38..36613b37c504 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c | |||
@@ -1148,6 +1148,12 @@ static int qe_ep_tx(struct qe_ep *ep, struct qe_frame *frame) | |||
1148 | static int txcomplete(struct qe_ep *ep, unsigned char restart) | 1148 | static int txcomplete(struct qe_ep *ep, unsigned char restart) |
1149 | { | 1149 | { |
1150 | if (ep->tx_req != NULL) { | 1150 | if (ep->tx_req != NULL) { |
1151 | struct qe_req *req = ep->tx_req; | ||
1152 | unsigned zlp = 0, last_len = 0; | ||
1153 | |||
1154 | last_len = min_t(unsigned, req->req.length - ep->sent, | ||
1155 | ep->ep.maxpacket); | ||
1156 | |||
1151 | if (!restart) { | 1157 | if (!restart) { |
1152 | int asent = ep->last; | 1158 | int asent = ep->last; |
1153 | ep->sent += asent; | 1159 | ep->sent += asent; |
@@ -1156,9 +1162,18 @@ static int txcomplete(struct qe_ep *ep, unsigned char restart) | |||
1156 | ep->last = 0; | 1162 | ep->last = 0; |
1157 | } | 1163 | } |
1158 | 1164 | ||
1165 | /* zlp needed when req->re.zero is set */ | ||
1166 | if (req->req.zero) { | ||
1167 | if (last_len == 0 || | ||
1168 | (req->req.length % ep->ep.maxpacket) != 0) | ||
1169 | zlp = 0; | ||
1170 | else | ||
1171 | zlp = 1; | ||
1172 | } else | ||
1173 | zlp = 0; | ||
1174 | |||
1159 | /* a request already were transmitted completely */ | 1175 | /* a request already were transmitted completely */ |
1160 | if ((ep->tx_req->req.length - ep->sent) <= 0) { | 1176 | if (((ep->tx_req->req.length - ep->sent) <= 0) && !zlp) { |
1161 | ep->tx_req->req.actual = (unsigned int)ep->sent; | ||
1162 | done(ep, ep->tx_req, 0); | 1177 | done(ep, ep->tx_req, 0); |
1163 | ep->tx_req = NULL; | 1178 | ep->tx_req = NULL; |
1164 | ep->last = 0; | 1179 | ep->last = 0; |
@@ -1191,6 +1206,7 @@ static int qe_usb_senddata(struct qe_ep *ep, struct qe_frame *frame) | |||
1191 | buf = (u8 *)ep->tx_req->req.buf + ep->sent; | 1206 | buf = (u8 *)ep->tx_req->req.buf + ep->sent; |
1192 | if (buf && size) { | 1207 | if (buf && size) { |
1193 | ep->last = size; | 1208 | ep->last = size; |
1209 | ep->tx_req->req.actual += size; | ||
1194 | frame_set_data(frame, buf); | 1210 | frame_set_data(frame, buf); |
1195 | frame_set_length(frame, size); | 1211 | frame_set_length(frame, size); |
1196 | frame_set_status(frame, FRAME_OK); | 1212 | frame_set_status(frame, FRAME_OK); |