aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/s3c-hsotg.c
diff options
context:
space:
mode:
authorLukasz Majewski <l.majewski@samsung.com>2012-05-04 08:17:04 -0400
committerFelipe Balbi <balbi@ti.com>2012-05-04 08:53:12 -0400
commitd3ca0259c56ee2dbc537d88a7496aba6b4712981 (patch)
treefa653e8b924ec9269f3b54c081df405f49fb7e15 /drivers/usb/gadget/s3c-hsotg.c
parent71225beeeba2bde80aac02fadb5c197389fa12e4 (diff)
usb:hsotg:samsung: Sending ZLP packet for IN EP0 transfers
This commit targets following scenarios for IN requests: 1. HOST requests e.g. 256B (which is a multiple of MPS = 64B). Then NO ZLP shall be sent, since host expects exact number of bytes. 2. HOST requested 4096B, but our data for sending is 256B. In this situation ZLP shall be send to tell HOST that no more data is available and it shall not wait for more data. This prevents HOST from hanging. Tested with: - DFU gadget (various size of the sent data - also packet = MPS) - Ethernet gadget (CDC and RNDIS) - Multi Function Gadget (g_multi) HW: - Samsung's C210 Universal rev.0 - Samsung's C110 GONI Signed-off-by: Lukasz Majewski <l.majewski@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/gadget/s3c-hsotg.c')
-rw-r--r--drivers/usb/gadget/s3c-hsotg.c34
1 files changed, 32 insertions, 2 deletions
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
index 7b46af3e014f..0a74a067749a 100644
--- a/drivers/usb/gadget/s3c-hsotg.c
+++ b/drivers/usb/gadget/s3c-hsotg.c
@@ -1555,6 +1555,10 @@ static void s3c_hsotg_handle_outdone(struct s3c_hsotg *hsotg,
1555 } 1555 }
1556 1556
1557 if (epnum == 0) { 1557 if (epnum == 0) {
1558 /*
1559 * Condition req->complete != s3c_hsotg_complete_setup says:
1560 * send ZLP when we have an asynchronous request from gadget
1561 */
1558 if (!was_setup && req->complete != s3c_hsotg_complete_setup) 1562 if (!was_setup && req->complete != s3c_hsotg_complete_setup)
1559 s3c_hsotg_send_zlp(hsotg, hs_req); 1563 s3c_hsotg_send_zlp(hsotg, hs_req);
1560 } 1564 }
@@ -1809,6 +1813,13 @@ static void s3c_hsotg_complete_in(struct s3c_hsotg *hsotg,
1809 return; 1813 return;
1810 } 1814 }
1811 1815
1816 /* Finish ZLP handling for IN EP0 transactions */
1817 if (hsotg->eps[0].sent_zlp) {
1818 dev_dbg(hsotg->dev, "zlp packet received\n");
1819 s3c_hsotg_complete_request_lock(hsotg, hs_ep, hs_req, 0);
1820 return;
1821 }
1822
1812 /* Calculate the size of the transfer by checking how much is left 1823 /* Calculate the size of the transfer by checking how much is left
1813 * in the endpoint size register and then working it out from 1824 * in the endpoint size register and then working it out from
1814 * the amount we loaded for the transfer. 1825 * the amount we loaded for the transfer.
@@ -1828,9 +1839,28 @@ static void s3c_hsotg_complete_in(struct s3c_hsotg *hsotg,
1828 __func__, hs_req->req.actual, size_done); 1839 __func__, hs_req->req.actual, size_done);
1829 1840
1830 hs_req->req.actual = size_done; 1841 hs_req->req.actual = size_done;
1842 dev_dbg(hsotg->dev, "req->length:%d req->actual:%d req->zero:%d\n",
1843 hs_req->req.length, hs_req->req.actual, hs_req->req.zero);
1844
1845 /*
1846 * Check if dealing with Maximum Packet Size(MPS) IN transfer at EP0
1847 * When sent data is a multiple MPS size (e.g. 64B ,128B ,192B
1848 * ,256B ... ), after last MPS sized packet send IN ZLP packet to
1849 * inform the host that no more data is available.
1850 * The state of req.zero member is checked to be sure that the value to
1851 * send is smaller than wValue expected from host.
1852 * Check req.length to NOT send another ZLP when the current one is
1853 * under completion (the one for which this completion has been called).
1854 */
1855 if (hs_req->req.length && hs_ep->index == 0 && hs_req->req.zero &&
1856 hs_req->req.length == hs_req->req.actual &&
1857 !(hs_req->req.length % hs_ep->ep.maxpacket)) {
1858
1859 dev_dbg(hsotg->dev, "ep0 zlp IN packet sent\n");
1860 s3c_hsotg_send_zlp(hsotg, hs_req);
1831 1861
1832 /* if we did all of the transfer, and there is more data left 1862 return;
1833 * around, then try restarting the rest of the request */ 1863 }
1834 1864
1835 if (!size_left && hs_req->req.actual < hs_req->req.length) { 1865 if (!size_left && hs_req->req.actual < hs_req->req.length) {
1836 dev_dbg(hsotg->dev, "%s trying more for req...\n", __func__); 1866 dev_dbg(hsotg->dev, "%s trying more for req...\n", __func__);