|
@@ -1555,6 +1555,10 @@ static void s3c_hsotg_handle_outdone(struct s3c_hsotg *hsotg,
|
|
|
}
|
|
|
|
|
|
if (epnum == 0) {
|
|
|
+ /*
|
|
|
+ * Condition req->complete != s3c_hsotg_complete_setup says:
|
|
|
+ * send ZLP when we have an asynchronous request from gadget
|
|
|
+ */
|
|
|
if (!was_setup && req->complete != s3c_hsotg_complete_setup)
|
|
|
s3c_hsotg_send_zlp(hsotg, hs_req);
|
|
|
}
|
|
@@ -1809,6 +1813,13 @@ static void s3c_hsotg_complete_in(struct s3c_hsotg *hsotg,
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ /* Finish ZLP handling for IN EP0 transactions */
|
|
|
+ if (hsotg->eps[0].sent_zlp) {
|
|
|
+ dev_dbg(hsotg->dev, "zlp packet received\n");
|
|
|
+ s3c_hsotg_complete_request_lock(hsotg, hs_ep, hs_req, 0);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
/* Calculate the size of the transfer by checking how much is left
|
|
|
* in the endpoint size register and then working it out from
|
|
|
* the amount we loaded for the transfer.
|
|
@@ -1828,9 +1839,28 @@ static void s3c_hsotg_complete_in(struct s3c_hsotg *hsotg,
|
|
|
__func__, hs_req->req.actual, size_done);
|
|
|
|
|
|
hs_req->req.actual = size_done;
|
|
|
+ dev_dbg(hsotg->dev, "req->length:%d req->actual:%d req->zero:%d\n",
|
|
|
+ hs_req->req.length, hs_req->req.actual, hs_req->req.zero);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check if dealing with Maximum Packet Size(MPS) IN transfer at EP0
|
|
|
+ * When sent data is a multiple MPS size (e.g. 64B ,128B ,192B
|
|
|
+ * ,256B ... ), after last MPS sized packet send IN ZLP packet to
|
|
|
+ * inform the host that no more data is available.
|
|
|
+ * The state of req.zero member is checked to be sure that the value to
|
|
|
+ * send is smaller than wValue expected from host.
|
|
|
+ * Check req.length to NOT send another ZLP when the current one is
|
|
|
+ * under completion (the one for which this completion has been called).
|
|
|
+ */
|
|
|
+ if (hs_req->req.length && hs_ep->index == 0 && hs_req->req.zero &&
|
|
|
+ hs_req->req.length == hs_req->req.actual &&
|
|
|
+ !(hs_req->req.length % hs_ep->ep.maxpacket)) {
|
|
|
+
|
|
|
+ dev_dbg(hsotg->dev, "ep0 zlp IN packet sent\n");
|
|
|
+ s3c_hsotg_send_zlp(hsotg, hs_req);
|
|
|
|
|
|
- /* if we did all of the transfer, and there is more data left
|
|
|
- * around, then try restarting the rest of the request */
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
if (!size_left && hs_req->req.actual < hs_req->req.length) {
|
|
|
dev_dbg(hsotg->dev, "%s trying more for req...\n", __func__);
|