aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/brcm2708/patches-3.10/0060-dwc_otg-fix-NAK-holdoff-and-allow-on-split-transacti.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/brcm2708/patches-3.10/0060-dwc_otg-fix-NAK-holdoff-and-allow-on-split-transacti.patch')
-rw-r--r--target/linux/brcm2708/patches-3.10/0060-dwc_otg-fix-NAK-holdoff-and-allow-on-split-transacti.patch67
1 files changed, 67 insertions, 0 deletions
diff --git a/target/linux/brcm2708/patches-3.10/0060-dwc_otg-fix-NAK-holdoff-and-allow-on-split-transacti.patch b/target/linux/brcm2708/patches-3.10/0060-dwc_otg-fix-NAK-holdoff-and-allow-on-split-transacti.patch
new file mode 100644
index 0000000000..ae5bfe9b26
--- /dev/null
+++ b/target/linux/brcm2708/patches-3.10/0060-dwc_otg-fix-NAK-holdoff-and-allow-on-split-transacti.patch
@@ -0,0 +1,67 @@
+From 370cbdb4a5ec521d9312b02bbaf269ed520b1451 Mon Sep 17 00:00:00 2001
+From: P33M <P33M@github.com>
+Date: Mon, 22 Apr 2013 00:08:36 +0100
+Subject: [PATCH 060/174] dwc_otg: fix NAK holdoff and allow on split
+ transactions only
+
+This corrects a bug where if a single active non-periodic endpoint
+had at least one transaction in its qh, on frnum == MAX_FRNUM the qh
+would get skipped and never get queued again. This would result in
+a silent device until error detection (automatic or otherwise) would
+either reset the device or flush and requeue the URBs.
+
+Additionally the NAK holdoff was enabled for all transactions - this
+would potentially stall a HS endpoint for 1ms if a previous error state
+enabled this interrupt and the next response was a NAK. Fix so that
+only split transactions get held off.
+---
+ drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 28 ++++++++++++++++++----------
+ 1 file changed, 18 insertions(+), 10 deletions(-)
+
+--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
+@@ -46,7 +46,7 @@
+ #include "dwc_otg_hcd.h"
+ #include "dwc_otg_regs.h"
+
+-extern bool microframe_schedule;
++extern bool microframe_schedule, nak_holdoff_enable;
+
+ //#define DEBUG_HOST_CHANNELS
+ #ifdef DEBUG_HOST_CHANNELS
+@@ -1349,18 +1349,26 @@ dwc_otg_transaction_type_e dwc_otg_hcd_s
+
+ /*
+ * Check to see if this is a NAK'd retransmit, in which case ignore for retransmission
+- * we hold off on bulk retransmissions to reduce NAK interrupt overhead for
++ * we hold off on bulk retransmissions to reduce NAK interrupt overhead for full-speed
+ * cheeky devices that just hold off using NAKs
+ */
+- if (dwc_full_frame_num(qh->nak_frame) == dwc_full_frame_num(dwc_otg_hcd_get_frame_number(hcd))) {
+- // Make fiq interrupt run on next frame (i.e. 8 uframes)
+- g_next_sched_frame = ((qh->nak_frame + 8) & ~7) & DWC_HFNUM_MAX_FRNUM;
+- qh_ptr = DWC_LIST_NEXT(qh_ptr);
+- continue;
++ if (nak_holdoff_enable && qh->do_split) {
++ if (qh->nak_frame != 0xffff &&
++ dwc_full_frame_num(qh->nak_frame) ==
++ dwc_full_frame_num(dwc_otg_hcd_get_frame_number(hcd))) {
++ /*
++ * Revisit: Need to avoid trampling on periodic scheduling.
++ * Currently we are safe because g_np_count != g_np_sent whenever we hit this,
++ * but if this behaviour is changed then periodic endpoints will get a slower
++ * polling rate.
++ */
++ g_next_sched_frame = ((qh->nak_frame + 8) & ~7) & DWC_HFNUM_MAX_FRNUM;
++ qh_ptr = DWC_LIST_NEXT(qh_ptr);
++ continue;
++ } else {
++ qh->nak_frame = 0xffff;
++ }
+ }
+- else
+- qh->nak_frame = 0xffff;
+-
+ if (microframe_schedule) {
+ DWC_SPINLOCK_IRQSAVE(channel_lock, &flags);
+ if (hcd->available_host_channels < 1) {