aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-ring.c
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@linux.intel.com>2009-12-09 18:59:13 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2010-03-02 17:53:12 -0500
commit2a8f82c4ceaffcfd64531dbdee1d1bc227387882 (patch)
treeb70b68e35d8a9e7264263848ce48a9863b387c55 /drivers/usb/host/xhci-ring.c
parent6219c047d3fe18dee4916d6898fc94f5a7ffd156 (diff)
USB: xhci: Notify the xHC when a device is reset.
When a USB device is reset, the xHCI hardware must know, in order to match the device state and disable all endpoints except control endpoint 0. Issue a Reset Device command after a USB device is successfully reset. Wait on the command to finish, and then cache or free the disabled endpoint rings. There are four different USB device states that the xHCI hardware tracks: - disabled/enabled - device connection has just been detected, - default - the device has been reset and has an address of 0, - addressed - the device has a non-zero address but no configuration has been set, - configured - a set configuration succeeded. The USB core may issue a port reset when a device is in any state, but the Reset Device command will fail for a 0.96 xHC if the device is not in the addressed or configured state. Don't consider this failure as an error, but don't free any endpoint rings if this command fails. A storage driver may request that the USB device be reset during error handling, so use GPF_NOIO instead of GPF_KERNEL while allocating memory for the Reset Device command. Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/xhci-ring.c')
-rw-r--r--drivers/usb/host/xhci-ring.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index f43e073dee96..6ba841bca4a2 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -953,6 +953,17 @@ bandwidth_change:
953 case TRB_TYPE(TRB_RESET_EP): 953 case TRB_TYPE(TRB_RESET_EP):
954 handle_reset_ep_completion(xhci, event, xhci->cmd_ring->dequeue); 954 handle_reset_ep_completion(xhci, event, xhci->cmd_ring->dequeue);
955 break; 955 break;
956 case TRB_TYPE(TRB_RESET_DEV):
957 xhci_dbg(xhci, "Completed reset device command.\n");
958 slot_id = TRB_TO_SLOT_ID(
959 xhci->cmd_ring->dequeue->generic.field[3]);
960 virt_dev = xhci->devs[slot_id];
961 if (virt_dev)
962 handle_cmd_in_cmd_wait_list(xhci, virt_dev, event);
963 else
964 xhci_warn(xhci, "Reset device command completion "
965 "for disabled slot %u\n", slot_id);
966 break;
956 default: 967 default:
957 /* Skip over unknown commands on the event ring */ 968 /* Skip over unknown commands on the event ring */
958 xhci->error_bitmask |= 1 << 6; 969 xhci->error_bitmask |= 1 << 6;
@@ -2189,6 +2200,14 @@ int xhci_queue_address_device(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr,
2189 false); 2200 false);
2190} 2201}
2191 2202
2203/* Queue a reset device command TRB */
2204int xhci_queue_reset_device(struct xhci_hcd *xhci, u32 slot_id)
2205{
2206 return queue_command(xhci, 0, 0, 0,
2207 TRB_TYPE(TRB_RESET_DEV) | SLOT_ID_FOR_TRB(slot_id),
2208 false);
2209}
2210
2192/* Queue a configure endpoint command TRB */ 2211/* Queue a configure endpoint command TRB */
2193int xhci_queue_configure_endpoint(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, 2212int xhci_queue_configure_endpoint(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr,
2194 u32 slot_id, bool command_must_succeed) 2213 u32 slot_id, bool command_must_succeed)