Commit f6ba6fe2 authored by Alex He's avatar Alex He Committed by Sarah Sharp

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: default avatarAlex He <alex.he@amd.com>
Signed-off-by: default avatarSarah Sharp <sarah.a.sharp@linux.intel.com>
parent e1cf486d
...@@ -1733,6 +1733,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, ...@@ -1733,6 +1733,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
frame->status = -EOVERFLOW; frame->status = -EOVERFLOW;
skip_td = true; skip_td = true;
break; break;
case COMP_DEV_ERR:
case COMP_STALL: case COMP_STALL:
frame->status = -EPROTO; frame->status = -EPROTO;
skip_td = true; skip_td = true;
...@@ -2016,6 +2017,10 @@ static int handle_tx_event(struct xhci_hcd *xhci, ...@@ -2016,6 +2017,10 @@ static int handle_tx_event(struct xhci_hcd *xhci,
TRB_TO_SLOT_ID(le32_to_cpu(event->flags)), TRB_TO_SLOT_ID(le32_to_cpu(event->flags)),
ep_index); ep_index);
goto cleanup; goto cleanup;
case COMP_DEV_ERR:
xhci_warn(xhci, "WARN: detect an incompatible device");
status = -EPROTO;
break;
case COMP_MISSED_INT: case COMP_MISSED_INT:
/* /*
* When encounter missed service error, one or more isoc tds * When encounter missed service error, one or more isoc tds
......
...@@ -1551,6 +1551,11 @@ static int xhci_configure_endpoint_result(struct xhci_hcd *xhci, ...@@ -1551,6 +1551,11 @@ static int xhci_configure_endpoint_result(struct xhci_hcd *xhci,
"and endpoint is not disabled.\n"); "and endpoint is not disabled.\n");
ret = -EINVAL; ret = -EINVAL;
break; break;
case COMP_DEV_ERR:
dev_warn(&udev->dev, "ERROR: Incompatible device for endpoint "
"configure command.\n");
ret = -ENODEV;
break;
case COMP_SUCCESS: case COMP_SUCCESS:
dev_dbg(&udev->dev, "Successful Endpoint Configure command\n"); dev_dbg(&udev->dev, "Successful Endpoint Configure command\n");
ret = 0; ret = 0;
...@@ -1585,6 +1590,11 @@ static int xhci_evaluate_context_result(struct xhci_hcd *xhci, ...@@ -1585,6 +1590,11 @@ static int xhci_evaluate_context_result(struct xhci_hcd *xhci,
xhci_dbg_ctx(xhci, virt_dev->out_ctx, 1); xhci_dbg_ctx(xhci, virt_dev->out_ctx, 1);
ret = -EINVAL; ret = -EINVAL;
break; break;
case COMP_DEV_ERR:
dev_warn(&udev->dev, "ERROR: Incompatible device for evaluate "
"context command.\n");
ret = -ENODEV;
break;
case COMP_MEL_ERR: case COMP_MEL_ERR:
/* Max Exit Latency too large error */ /* Max Exit Latency too large error */
dev_warn(&udev->dev, "WARN: Max Exit Latency too large\n"); 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) ...@@ -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"); dev_warn(&udev->dev, "Device not responding to set address.\n");
ret = -EPROTO; ret = -EPROTO;
break; break;
case COMP_DEV_ERR:
dev_warn(&udev->dev, "ERROR: Incompatible device for address "
"device command.\n");
ret = -ENODEV;
break;
case COMP_SUCCESS: case COMP_SUCCESS:
xhci_dbg(xhci, "Successful Address Device command\n"); xhci_dbg(xhci, "Successful Address Device command\n");
break; break;
......
...@@ -874,6 +874,8 @@ struct xhci_transfer_event { ...@@ -874,6 +874,8 @@ struct xhci_transfer_event {
#define COMP_PING_ERR 20 #define COMP_PING_ERR 20
/* Event Ring is full */ /* Event Ring is full */
#define COMP_ER_FULL 21 #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 */ /* Missed Service Error - HC couldn't service an isoc ep within interval */
#define COMP_MISSED_INT 23 #define COMP_MISSED_INT 23
/* Successfully stopped command ring */ /* Successfully stopped command ring */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment