| From 6eb3a1a5206dfa2fc00402d2915ad0a4ed6973ac Mon Sep 17 00:00:00 2001 |
| From: Lu Baolu <baolu.lu@linux.intel.com> |
| Date: Thu, 5 Oct 2017 11:21:45 +0300 |
| Subject: [PATCH 0251/1795] usb: xhci: Handle USB transaction error on address |
| command |
| |
| Xhci driver handles USB transaction errors on transfer events, |
| but transaction errors are possible on address device command |
| completion events as well. |
| |
| The xHCI specification (section 4.6.5) says: A USB Transaction |
| Error Completion Code for an Address Device Command may be due |
| to a Stall response from a device. Software should issue a Disable |
| Slot Command for the Device Slot then an Enable Slot Command to |
| recover from this error. |
| |
| This patch handles USB transaction errors on address command |
| completion events. The related discussion threads can be found |
| through below links. |
| |
| http://marc.info/?l=linux-usb&m=149362010728921&w=2 |
| http://marc.info/?l=linux-usb&m=149252752825755&w=2 |
| |
| Suggested-by: Mathias Nyman <mathias.nyman@linux.intel.com> |
| Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> |
| Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| (cherry picked from commit 651aaf36a7d7b36a58980e70133f9437d4f6d312) |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> |
| --- |
| drivers/usb/host/xhci.c | 10 ++++++++-- |
| 1 file changed, 8 insertions(+), 2 deletions(-) |
| |
| diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c |
| index 2ac8f8622f8c..e13f9bb99baf 100644 |
| --- a/drivers/usb/host/xhci.c |
| +++ b/drivers/usb/host/xhci.c |
| @@ -3879,8 +3879,14 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, |
| break; |
| case COMP_USB_TRANSACTION_ERROR: |
| dev_warn(&udev->dev, "Device not responding to setup %s.\n", act); |
| - ret = -EPROTO; |
| - break; |
| + |
| + mutex_unlock(&xhci->mutex); |
| + ret = xhci_disable_slot(xhci, udev->slot_id); |
| + if (!ret) |
| + xhci_alloc_dev(hcd, udev); |
| + kfree(command->completion); |
| + kfree(command); |
| + return -EPROTO; |
| case COMP_INCOMPATIBLE_DEVICE_ERROR: |
| dev_warn(&udev->dev, |
| "ERROR: Incompatible device for setup %s command\n", act); |
| -- |
| 2.19.0 |
| |