aboutsummaryrefslogtreecommitdiffstats
path: root/usb/usb-s3c-hsotg-fix-out-packet-request-retry.patch
diff options
authorGreg Kroah-Hartman <gregkh@suse.de>2010-07-22 16:57:38 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2010-07-22 16:57:38 -0700
commit6bbbb136e761db39158852c9b42619c2438e9d45 (patch)
tree4b48eba7be3ba0e7ffbddc0fee4988d26623099a /usb/usb-s3c-hsotg-fix-out-packet-request-retry.patch
parent5caca10b163e38f1671c4be83c480581da4d90d6 (diff)
downloadpatches-6bbbb136e761db39158852c9b42619c2438e9d45.tar.gz
lots of patches
Diffstat (limited to 'usb/usb-s3c-hsotg-fix-out-packet-request-retry.patch')
-rw-r--r--usb/usb-s3c-hsotg-fix-out-packet-request-retry.patch89
1 files changed, 89 insertions, 0 deletions
diff --git a/usb/usb-s3c-hsotg-fix-out-packet-request-retry.patch b/usb/usb-s3c-hsotg-fix-out-packet-request-retry.patch
new file mode 100644
index 00000000000000..396ff6c8f161fd
--- /dev/null
+++ b/usb/usb-s3c-hsotg-fix-out-packet-request-retry.patch
@@ -0,0 +1,89 @@
+From ben@ben-laptop.fluff.org Thu Jul 22 16:50:21 2010
+From: Ben Dooks <ben-linux@fluff.org>
+To: linux-samsung-soc@vger.kernel.org, linux-usb@vger.kernel.org
+Cc: gregkh@suse.de, Ben Dooks <ben-linux@fluff.org>
+Subject: USB: s3c-hsotg: Fix OUT packet request retry
+Date: Mon, 19 Jul 2010 09:40:49 +0100
+Message-Id: <1279528850-28245-11-git-send-email-ben-linux@fluff.org>
+
+If there is more data in the request than we could fit into a single
+hardware request, then check when the OutDone event is received if
+we have more data, and if so, schedule the new data instead of trying
+to complete the request (and in the case of EP0, sending a 0 packet
+in the middle of a transfer).
+
+Also, move the debug message about the current transfer state before
+the warning about a bad transfer.
+
+Signed-off-by: Ben Dooks <ben-linux@fluff.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/s3c-hsotg.c | 18 +++++++++++-------
+ 1 file changed, 11 insertions(+), 7 deletions(-)
+
+--- a/drivers/usb/gadget/s3c-hsotg.c
++++ b/drivers/usb/gadget/s3c-hsotg.c
+@@ -1383,6 +1383,9 @@ static void s3c_hsotg_rx_data(struct s3c
+ read_ptr = hs_req->req.actual;
+ max_req = hs_req->req.length - read_ptr;
+
++ dev_dbg(hsotg->dev, "%s: read %d/%d, done %d/%d\n",
++ __func__, to_read, max_req, read_ptr, hs_req->req.length);
++
+ if (to_read > max_req) {
+ /* more data appeared than we where willing
+ * to deal with in this request.
+@@ -1392,9 +1395,6 @@ static void s3c_hsotg_rx_data(struct s3c
+ WARN_ON_ONCE(1);
+ }
+
+- dev_dbg(hsotg->dev, "%s: read %d/%d, done %d/%d\n",
+- __func__, to_read, max_req, read_ptr, hs_req->req.length);
+-
+ hs_ep->total_data += to_read;
+ hs_req->req.actual += to_read;
+ to_read = DIV_ROUND_UP(to_read, 4);
+@@ -1463,9 +1463,11 @@ static void s3c_hsotg_send_zlp(struct s3
+ static void s3c_hsotg_handle_outdone(struct s3c_hsotg *hsotg,
+ int epnum, bool was_setup)
+ {
++ u32 epsize = readl(hsotg->regs + S3C_DOEPTSIZ(epnum));
+ struct s3c_hsotg_ep *hs_ep = &hsotg->eps[epnum];
+ struct s3c_hsotg_req *hs_req = hs_ep->req;
+ struct usb_request *req = &hs_req->req;
++ unsigned size_left = S3C_DxEPTSIZ_XferSize_GET(epsize);
+ int result = 0;
+
+ if (!hs_req) {
+@@ -1474,9 +1476,7 @@ static void s3c_hsotg_handle_outdone(str
+ }
+
+ if (using_dma(hsotg)) {
+- u32 epsize = readl(hsotg->regs + S3C_DOEPTSIZ(epnum));
+ unsigned size_done;
+- unsigned size_left;
+
+ /* Calculate the size of the transfer by checking how much
+ * is left in the endpoint size register and then working it
+@@ -1486,14 +1486,18 @@ static void s3c_hsotg_handle_outdone(str
+ * so may overshoot/undershoot the transfer.
+ */
+
+- size_left = S3C_DxEPTSIZ_XferSize_GET(epsize);
+-
+ size_done = hs_ep->size_loaded - size_left;
+ size_done += hs_ep->last_load;
+
+ req->actual = size_done;
+ }
+
++ /* if there is more request to do, schedule new transfer */
++ if (req->actual < req->length && size_left == 0) {
++ s3c_hsotg_start_req(hsotg, hs_ep, hs_req, true);
++ return;
++ }
++
+ if (req->actual < req->length && req->short_not_ok) {
+ dev_dbg(hsotg->dev, "%s: got %d/%d (short not ok) => error\n",
+ __func__, req->actual, req->length);