disable IMQ on 2.6.28 as well -- people should use IFB..
[openwrt.git] / target / linux / s3c24xx / patches / 0022-s3c2410_udc-2440_dual_packet-workaround.patch.patch
1 From 5207363cc9d50f99a2ad490eff5efa913b1c10ba Mon Sep 17 00:00:00 2001
2 From: mokopatches <mokopatches@openmoko.org>
3 Date: Wed, 16 Jul 2008 14:44:50 +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 6b1ef48..c1a4379 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.3
61