diff options
author | Alex He <alex.he@amd.com> | 2011-06-08 18:34:06 +0800 |
---|---|---|
committer | Sarah Sharp <sarah.a.sharp@linux.intel.com> | 2011-06-17 11:28:08 -0700 |
commit | f6ba6fe2d913da6707a71a413d6ec8ae98d6ce18 (patch) | |
tree | 2da2e6bc2b35659e5372825ecfd575ffad70ca5e /drivers/usb | |
parent | e1cf486d881d853d710e2d86a7adfc5fd260990f (diff) | |
download | linux-f6ba6fe2d913da6707a71a413d6ec8ae98d6ce18.tar.gz |
xHCI 1.0: Incompatible Device Error
It is one new TRB Completion Code for the xHCI spec v1.0.
Asserted if the xHC detects a problem with a device that does not allow it to
be successfully accessed, e.g. due to a device compliance or compatibility
problem. This error may be returned by any command or transfer, and is fatal
as far as the Slot is concerned. Return -EPROTO by urb->status or frame->status
of ISOC for transfer case. And return -ENODEV for configure endpoint command,
evaluate context command and address device command if there is an incompatible
Device Error. The error codes will be sent back to the USB core to decide how
to do. It's unnecessary for other commands because after the three commands run
successfully means that the device has been accepted.
Signed-off-by: Alex He <alex.he@amd.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 5 | ||||
-rw-r--r-- | drivers/usb/host/xhci.c | 15 | ||||
-rw-r--r-- | drivers/usb/host/xhci.h | 2 |
3 files changed, 22 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 0c008497edfd..436332aa341b 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1733,6 +1733,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, frame->status = -EOVERFLOW; skip_td = true; break; + case COMP_DEV_ERR: case COMP_STALL: frame->status = -EPROTO; skip_td = true; @@ -2016,6 +2017,10 @@ static int handle_tx_event(struct xhci_hcd *xhci, TRB_TO_SLOT_ID(le32_to_cpu(event->flags)), ep_index); goto cleanup; + case COMP_DEV_ERR: + xhci_warn(xhci, "WARN: detect an incompatible device"); + status = -EPROTO; + break; case COMP_MISSED_INT: /* * When encounter missed service error, one or more isoc tds diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index e5a01713f937..15eb4c3d793c 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1551,6 +1551,11 @@ static int xhci_configure_endpoint_result(struct xhci_hcd *xhci, "and endpoint is not disabled.\n"); ret = -EINVAL; break; + case COMP_DEV_ERR: + dev_warn(&udev->dev, "ERROR: Incompatible device for endpoint " + "configure command.\n"); + ret = -ENODEV; + break; case COMP_SUCCESS: dev_dbg(&udev->dev, "Successful Endpoint Configure command\n"); ret = 0; @@ -1585,6 +1590,11 @@ static int xhci_evaluate_context_result(struct xhci_hcd *xhci, xhci_dbg_ctx(xhci, virt_dev->out_ctx, 1); ret = -EINVAL; break; + case COMP_DEV_ERR: + dev_warn(&udev->dev, "ERROR: Incompatible device for evaluate " + "context command.\n"); + ret = -ENODEV; + break; case COMP_MEL_ERR: /* Max Exit Latency too large error */ dev_warn(&udev->dev, "WARN: Max Exit Latency too large\n"); @@ -2867,6 +2877,11 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) dev_warn(&udev->dev, "Device not responding to set address.\n"); ret = -EPROTO; break; + case COMP_DEV_ERR: + dev_warn(&udev->dev, "ERROR: Incompatible device for address " + "device command.\n"); + ret = -ENODEV; + break; case COMP_SUCCESS: xhci_dbg(xhci, "Successful Address Device command\n"); break; diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 7d1ea3bf5e1f..ba90af1c34b4 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -874,6 +874,8 @@ struct xhci_transfer_event { #define COMP_PING_ERR 20 /* Event Ring is full */ #define COMP_ER_FULL 21 +/* Incompatible Device Error */ +#define COMP_DEV_ERR 22 /* Missed Service Error - HC couldn't service an isoc ep within interval */ #define COMP_MISSED_INT 23 /* Successfully stopped command ring */ |