brcm2708: update against latest rpi-3.10.y branch
[openwrt.git] / target / linux / brcm2708 / patches-3.10 / 0060-dwc_otg-fix-NAK-holdoff-and-allow-on-split-transacti.patch
1 From 370cbdb4a5ec521d9312b02bbaf269ed520b1451 Mon Sep 17 00:00:00 2001
2 From: P33M <P33M@github.com>
3 Date: Mon, 22 Apr 2013 00:08:36 +0100
4 Subject: [PATCH 060/174] dwc_otg: fix NAK holdoff and allow on split
5  transactions only
6
7 This corrects a bug where if a single active non-periodic endpoint
8 had at least one transaction in its qh, on frnum == MAX_FRNUM the qh
9 would get skipped and never get queued again. This would result in
10 a silent device until error detection (automatic or otherwise) would
11 either reset the device or flush and requeue the URBs.
12
13 Additionally the NAK holdoff was enabled for all transactions - this
14 would potentially stall a HS endpoint for 1ms if a previous error state
15 enabled this interrupt and the next response was a NAK. Fix so that
16 only split transactions get held off.
17 ---
18  drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 28 ++++++++++++++++++----------
19  1 file changed, 18 insertions(+), 10 deletions(-)
20
21 --- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
22 +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
23 @@ -46,7 +46,7 @@
24  #include "dwc_otg_hcd.h"
25  #include "dwc_otg_regs.h"
26  
27 -extern bool microframe_schedule;
28 +extern bool microframe_schedule, nak_holdoff_enable;
29  
30  //#define DEBUG_HOST_CHANNELS
31  #ifdef DEBUG_HOST_CHANNELS
32 @@ -1349,18 +1349,26 @@ dwc_otg_transaction_type_e dwc_otg_hcd_s
33  
34                 /*
35                  * Check to see if this is a NAK'd retransmit, in which case ignore for retransmission
36 -                * we hold off on bulk retransmissions to reduce NAK interrupt overhead for
37 +                * we hold off on bulk retransmissions to reduce NAK interrupt overhead for full-speed
38                  * cheeky devices that just hold off using NAKs
39                  */
40 -               if (dwc_full_frame_num(qh->nak_frame) == dwc_full_frame_num(dwc_otg_hcd_get_frame_number(hcd))) {
41 -                       // Make fiq interrupt run on next frame (i.e. 8 uframes)
42 -                       g_next_sched_frame = ((qh->nak_frame + 8) & ~7) & DWC_HFNUM_MAX_FRNUM;
43 -                       qh_ptr = DWC_LIST_NEXT(qh_ptr);
44 -                       continue;
45 +               if (nak_holdoff_enable && qh->do_split) {
46 +                       if (qh->nak_frame != 0xffff &&
47 +                               dwc_full_frame_num(qh->nak_frame) ==
48 +                               dwc_full_frame_num(dwc_otg_hcd_get_frame_number(hcd))) {
49 +                               /*
50 +                                * Revisit: Need to avoid trampling on periodic scheduling.
51 +                                * Currently we are safe because g_np_count != g_np_sent whenever we hit this,
52 +                                * but if this behaviour is changed then periodic endpoints will get a slower
53 +                                * polling rate.
54 +                                */
55 +                               g_next_sched_frame = ((qh->nak_frame + 8) & ~7) & DWC_HFNUM_MAX_FRNUM;
56 +                               qh_ptr = DWC_LIST_NEXT(qh_ptr);
57 +                               continue;
58 +                       } else {
59 +                               qh->nak_frame = 0xffff;
60 +                       }
61                 }
62 -               else
63 -                       qh->nak_frame = 0xffff;
64 -
65                 if (microframe_schedule) {
66                                 DWC_SPINLOCK_IRQSAVE(channel_lock, &flags);
67                                 if (hcd->available_host_channels < 1) {