patch "USB: EHCI: Do not return -EPIPE when hub is disconnected" added to usb-linus
Subsystems (3)
This is a note to let you know that I've just added the patch titled
USB: EHCI: Do not return -EPIPE when hub is disconnected
to my usb git tree which can be found at
git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git
in the usb-linus branch.
The patch will show up in the next release of the linux-next tree (usually sometime within the next 24 hours during the week.)
The patch will hopefully also be merged in Linus's tree for the next -rc kernel release.
If you have any questions about this process, please let me know.
From 64cc3f12d1c7dd054a215bc1ff9cc2abcfe35832 Mon Sep 17 00:00:00 2001
From: Erkka Talvitie <[email protected]>
Date: Wed, 11 Dec 2019 10:08:39 +0200
Subject: USB: EHCI: Do not return -EPIPE when hub is disconnected
When disconnecting a USB hub that has some child device(s) connected to it (such as a USB mouse), then the stack tries to clear halt and reset device(s) which are _already_ physically disconnected.
The issue has been reproduced with:
CPU: IMX6D5EYM10AD or MCIMX6D5EYM10AE.
SW: U-Boot 2019.07 and kernel 4.19.40.
CPU: HP Proliant Microserver Gen8.
SW: Linux version 4.2.3-300.fc23.x86_64
In this situation there will be error bit for MMF active yet the CERR equals EHCI_TUNE_CERR + halt. Existing implementation interprets this as a stall [1] (chapter 8.4.5).
The possible conditions when the MMF will be active + halt can be found from [2] (Table 4-13).
Fix for the issue is to check whether MMF is active and PID Code is IN before checking for the stall. If these conditions are true then it is not a stall.
What happens after the fix is that when disconnecting a hub with attached device(s) the situation is not interpret as a stall.
[1] [https://www.usb.org/document-library/usb-20-specification, usb_20.pdf]
[2] [https://www.intel.com/content/dam/www/public/us/en/documents/
technical-specifications/ehci-specification-for-usb.pdf]
--- drivers/usb/host/ehci-q.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
drivers/usb/host/ehci-q.c +12 -1
@@ -27,6 +27,10 @@/*-------------------------------------------------------------------------*/ +/* PID Codes that are used here, from EHCI specification, Table 3-16. */ +#define PID_CODE_IN 1 +#define PID_CODE_SETUP 2 +/* fill a qtd, returning how much of the buffer we were able to queue up */ static int
@@ -190,7 +194,7 @@ static int qtd_copy_status (int status = -EINPROGRESS ;/* count IN/OUT bytes, not SETUP (even short packets) */ -if (likely (QTD_PID (token) !=2 )) +if (likely (QTD_PID (token) !=PID_CODE_SETUP )) urb->actual_length += length -QTD_LENGTH (token);/* don't modify error codes */
@@ -206,6 +210,13 @@ static int qtd_copy_status (if (token &QTD_STS_BABBLE ) {/* FIXME "must" disable babbling device's port too */ status = -EOVERFLOW ; +/* +* When MMF is active and PID Code is IN, queue is halted. +* EHCI Specification, Table 4-13. +*/ + }else if ((token &QTD_STS_MMF ) && + (QTD_PID (token) ==PID_CODE_IN )) { + status = -EPROTO ;/* CERR nonzero + halt --> stall */ }else if (QTD_CERR (token)) { status = -EPIPE ;
Signature · 1 line
2.24.1