summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClemens Gruber <clemens.gruber@pqgruber.com>2016-09-05 19:29:58 +0200
committerSasha Levin <alexander.levin@verizon.com>2016-10-02 20:32:17 -0400
commit32eb86c0cc4b3d19916981f2c3df9b7df6267d65 (patch)
tree231f4e65790271a979df8a0f3d3d5617a4a9d170
parent4bfeb58805bd708c1d1831df6bc30b3cb8f42516 (diff)
usb: chipidea: udc: fix NULL ptr dereference in isr_setup_status_phase
[ Upstream commit 6f3c4fb6d05e63c9c6d8968302491c3a5457be61 ] Problems with the signal integrity of the high speed USB data lines or noise on reference ground lines can cause the i.MX6 USB controller to violate USB specs and exhibit unexpected behavior. It was observed that USBi_UI interrupts were triggered first and when isr_setup_status_phase was called, ci->status was NULL, which lead to a NULL pointer dereference kernel panic. This patch fixes the kernel panic, emits a warning once and returns -EPIPE to halt the device and let the host get stalled. It also adds a comment to point people, who are experiencing this issue, to their USB hardware design. Cc: <stable@vger.kernel.org> #4.1+ Signed-off-by: Clemens Gruber <clemens.gruber@pqgruber.com> Signed-off-by: Peter Chen <peter.chen@nxp.com> Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
-rw-r--r--drivers/usb/chipidea/udc.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index d93e43cfb6f8..ebcf40c2f12b 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -939,6 +939,15 @@ static int isr_setup_status_phase(struct ci_hdrc *ci)
int retval;
struct ci_hw_ep *hwep;
+ /*
+ * Unexpected USB controller behavior, caused by bad signal integrity
+ * or ground reference problems, can lead to isr_setup_status_phase
+ * being called with ci->status equal to NULL.
+ * If this situation occurs, you should review your USB hardware design.
+ */
+ if (WARN_ON_ONCE(!ci->status))
+ return -EPIPE;
+
hwep = (ci->ep0_dir == TX) ? ci->ep0out : ci->ep0in;
ci->status->context = ci;
ci->status->complete = isr_setup_status_complete;