diff options
Diffstat (limited to 'drivers/usb/gadget/s3c-hsotg.c')
-rw-r--r-- | drivers/usb/gadget/s3c-hsotg.c | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index 7b46af3e014..0a74a067749 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__); |