xHCI 1.0: Incompatible Device Error
authorAlex He <alex.he@amd.com>
Wed, 8 Jun 2011 10:34:06 +0000 (18:34 +0800)
committerSarah Sharp <sarah.a.sharp@linux.intel.com>
Fri, 17 Jun 2011 18:28:08 +0000 (11:28 -0700)
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>
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h

index 0c00849..436332a 100644 (file)
@@ -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
index e5a0171..15eb4c3 100644 (file)
@@ -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;
index 7d1ea3b..ba90af1 100644 (file)
@@ -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 */