diff options
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.patch | 67 |
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) { |