[brcm63xx] resync kernel configuration
[openwrt.git] / target / linux / s3c24xx / patches-2.6.24 / 1027-s3c2410_udc-2440_dual_packet-workaround.patch.patch
1 From d8310bb7e4ee4a9f3433a9a1e0e87567337299cb Mon Sep 17 00:00:00 2001
2 From: mokopatches <mokopatches@openmoko.org>
3 Date: Fri, 4 Apr 2008 11:33:55 +0100
4 Subject: [PATCH] s3c2410_udc-2440_dual_packet-workaround.patch
5 This is a patch that seems to make the USB hangs on the S3C2440 go away. At
6 least a good amount of ping torture didn't make them come back so far.
7
8 The issue is that, if there are several back-to-back packets,
9 sometimes no interrupt is generated for one of them. This
10 seems to be caused by the mysterious dual packet mode, which
11 the USB hardware enters automatically if the endpoint size is
12 half that of the FIFO. (On the 2440, this is the normal
13 situation for bulk data endpoints.)
14
15 There is also a timing factor in this. I think what happens is
16 that the USB hardware automatically sends an acknowledgement
17 if there is only one packet in the FIFO (the FIFO has space
18 for two). If another packet arrives before the host has
19 retrieved and acknowledged the previous one, no interrupt is
20 generated for that second one.
21
22 However, there may be an indication. There is one undocumented
23 bit (none of the 244x manuals document it), OUT_CRS1_REG[1],
24 that seems to be set suspiciously often when this condition
25 occurs. There is also CLR_DATA_TOGGLE, OUT_CRS1_REG[7], which
26 may have a function related to this. (The Samsung manual is
27 rather terse on that, as usual.)
28
29 This needs to be examined further. For now, the patch seems to do the
30 trick.
31
32 Note that this is not a clean solution by any means, because we
33 might potentially get stuck in that interrupt for quite a while.
34 ---
35 drivers/usb/gadget/s3c2410_udc.c | 3 +++
36 1 files changed, 3 insertions(+), 0 deletions(-)
37
38 diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c
39 index 4ce050c..d4a17af 100644
40 --- a/drivers/usb/gadget/s3c2410_udc.c
41 +++ b/drivers/usb/gadget/s3c2410_udc.c
42 @@ -845,6 +845,7 @@ static void s3c2410_udc_handle_ep(struct s3c2410_ep *ep)
43 u32 ep_csr1;
44 u32 idx;
45
46 +handle_ep_again:
47 if (likely (!list_empty(&ep->queue)))
48 req = list_entry(ep->queue.next,
49 struct s3c2410_request, queue);
50 @@ -884,6 +885,8 @@ static void s3c2410_udc_handle_ep(struct s3c2410_ep *ep)
51
52 if ((ep_csr1 & S3C2410_UDC_OCSR1_PKTRDY) && req) {
53 s3c2410_udc_read_fifo(ep,req);
54 + if (s3c2410_udc_fifo_count_out())
55 + goto handle_ep_again;
56 }
57 }
58 }
59 --
60 1.5.6.5
61
This page took 0.043026 seconds and 5 git commands to generate.