aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAndiry Xu <andiry.xu@amd.com>2010-10-14 10:22:48 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-10-22 13:22:11 -0400
commitf0615c45ce5feb141c1172480c5198d4b8d25436 (patch)
tree9c16dbd56591297d94286f7f3e12b80d07ec28a8 /drivers
parent64927730c66333c9d5987aa72a0e6d44ed91cec7 (diff)
USB: xHCI: change xhci_reset_device() to allocate new device
Rename xhci_reset_device() to xhci_discover_or_reset_device(). If xhci_discover_or_reset_device() is called to reset a device which does not exist or does not match the udev, it calls xhci_alloc_dev() to re-allocate the device. This would prevent the reset device failure, possibly due to the xHC restore error during S3/S4 resume. Signed-off-by: Andiry Xu <andiry.xu@amd.com> Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/host/xhci-pci.c2
-rw-r--r--drivers/usb/host/xhci.c44
-rw-r--r--drivers/usb/host/xhci.h2
3 files changed, 41 insertions, 7 deletions
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index f7efe025beda..aefc3496376a 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -152,7 +152,7 @@ static const struct hc_driver xhci_pci_hc_driver = {
152 .reset_bandwidth = xhci_reset_bandwidth, 152 .reset_bandwidth = xhci_reset_bandwidth,
153 .address_device = xhci_address_device, 153 .address_device = xhci_address_device,
154 .update_hub_device = xhci_update_hub_device, 154 .update_hub_device = xhci_update_hub_device,
155 .reset_device = xhci_reset_device, 155 .reset_device = xhci_discover_or_reset_device,
156 156
157 /* 157 /*
158 * scheduling support 158 * scheduling support
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 0bec04070334..7928af5c91cb 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -1943,8 +1943,13 @@ int xhci_free_streams(struct usb_hcd *hcd, struct usb_device *udev,
1943 * Wait for the Reset Device command to finish. Remove all structures 1943 * Wait for the Reset Device command to finish. Remove all structures
1944 * associated with the endpoints that were disabled. Clear the input device 1944 * associated with the endpoints that were disabled. Clear the input device
1945 * structure? Cache the rings? Reset the control endpoint 0 max packet size? 1945 * structure? Cache the rings? Reset the control endpoint 0 max packet size?
1946 *
1947 * If the virt_dev to be reset does not exist or does not match the udev,
1948 * it means the device is lost, possibly due to the xHC restore error and
1949 * re-initialization during S3/S4. In this case, call xhci_alloc_dev() to
1950 * re-allocate the device.
1946 */ 1951 */
1947int xhci_reset_device(struct usb_hcd *hcd, struct usb_device *udev) 1952int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev)
1948{ 1953{
1949 int ret, i; 1954 int ret, i;
1950 unsigned long flags; 1955 unsigned long flags;
@@ -1955,12 +1960,36 @@ int xhci_reset_device(struct usb_hcd *hcd, struct usb_device *udev)
1955 int timeleft; 1960 int timeleft;
1956 int last_freed_endpoint; 1961 int last_freed_endpoint;
1957 1962
1958 ret = xhci_check_args(hcd, udev, NULL, 0, true, __func__); 1963 ret = xhci_check_args(hcd, udev, NULL, 0, false, __func__);
1959 if (ret <= 0) 1964 if (ret <= 0)
1960 return ret; 1965 return ret;
1961 xhci = hcd_to_xhci(hcd); 1966 xhci = hcd_to_xhci(hcd);
1962 slot_id = udev->slot_id; 1967 slot_id = udev->slot_id;
1963 virt_dev = xhci->devs[slot_id]; 1968 virt_dev = xhci->devs[slot_id];
1969 if (!virt_dev) {
1970 xhci_dbg(xhci, "The device to be reset with slot ID %u does "
1971 "not exist. Re-allocate the device\n", slot_id);
1972 ret = xhci_alloc_dev(hcd, udev);
1973 if (ret == 1)
1974 return 0;
1975 else
1976 return -EINVAL;
1977 }
1978
1979 if (virt_dev->udev != udev) {
1980 /* If the virt_dev and the udev does not match, this virt_dev
1981 * may belong to another udev.
1982 * Re-allocate the device.
1983 */
1984 xhci_dbg(xhci, "The device to be reset with slot ID %u does "
1985 "not match the udev. Re-allocate the device\n",
1986 slot_id);
1987 ret = xhci_alloc_dev(hcd, udev);
1988 if (ret == 1)
1989 return 0;
1990 else
1991 return -EINVAL;
1992 }
1964 1993
1965 xhci_dbg(xhci, "Resetting device with slot ID %u\n", slot_id); 1994 xhci_dbg(xhci, "Resetting device with slot ID %u\n", slot_id);
1966 /* Allocate the command structure that holds the struct completion. 1995 /* Allocate the command structure that holds the struct completion.
@@ -2176,12 +2205,17 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
2176 2205
2177 virt_dev = xhci->devs[udev->slot_id]; 2206 virt_dev = xhci->devs[udev->slot_id];
2178 2207
2179 /* If this is a Set Address to an unconfigured device, setup ep 0 */ 2208 slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx);
2180 if (!udev->config) 2209 /*
2210 * If this is the first Set Address since device plug-in or
2211 * virt_device realloaction after a resume with an xHCI power loss,
2212 * then set up the slot context.
2213 */
2214 if (!slot_ctx->dev_info)
2181 xhci_setup_addressable_virt_dev(xhci, udev); 2215 xhci_setup_addressable_virt_dev(xhci, udev);
2216 /* Otherwise, update the control endpoint ring enqueue pointer. */
2182 else 2217 else
2183 xhci_copy_ep0_dequeue_into_input_ctx(xhci, udev); 2218 xhci_copy_ep0_dequeue_into_input_ctx(xhci, udev);
2184 /* Otherwise, assume the core has the device configured how it wants */
2185 xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id); 2219 xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id);
2186 xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2); 2220 xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2);
2187 2221
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index f03f140a7d9a..490409f918f2 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1389,7 +1389,7 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status);
1389int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep); 1389int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep);
1390int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep); 1390int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep);
1391void xhci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep); 1391void xhci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep);
1392int xhci_reset_device(struct usb_hcd *hcd, struct usb_device *udev); 1392int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev);
1393int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev); 1393int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev);
1394void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev); 1394void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev);
1395 1395