aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAndiry Xu <andiry.xu@amd.com>2010-10-14 10:22:45 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-10-22 13:22:11 -0400
commit64927730c66333c9d5987aa72a0e6d44ed91cec7 (patch)
treeedc1da4d69cbd66d9ba1cff75a5738900d2e8cef /drivers
parentac9dfe9cdda4eb42ecaa9f13b0fee518e0b6518e (diff)
USB: xHCI: Add pointer to udev in struct xhci_virt_device
Add a pointer to udev in struct xhci_virt_device. When allocate a new virt_device, make the pointer point to the corresponding udev. Modify xhci_check_args(), check if virt_dev->udev matches the target udev, to make sure command is issued to the right device. 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-mem.c1
-rw-r--r--drivers/usb/host/xhci.c83
-rw-r--r--drivers/usb/host/xhci.h1
3 files changed, 36 insertions, 49 deletions
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 4e51343ddffc..be901808e474 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -778,6 +778,7 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id,
778 778
779 init_completion(&dev->cmd_completion); 779 init_completion(&dev->cmd_completion);
780 INIT_LIST_HEAD(&dev->cmd_list); 780 INIT_LIST_HEAD(&dev->cmd_list);
781 dev->udev = udev;
781 782
782 /* Point to output device context in dcbaa. */ 783 /* Point to output device context in dcbaa. */
783 xhci->dcbaa->dev_context_ptrs[slot_id] = dev->out_ctx->dma; 784 xhci->dcbaa->dev_context_ptrs[slot_id] = dev->out_ctx->dma;
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index d5c550ea3e68..0bec04070334 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -607,7 +607,11 @@ unsigned int xhci_last_valid_endpoint(u32 added_ctxs)
607 * returns 0 this is a root hub; returns -EINVAL for NULL pointers. 607 * returns 0 this is a root hub; returns -EINVAL for NULL pointers.
608 */ 608 */
609int xhci_check_args(struct usb_hcd *hcd, struct usb_device *udev, 609int xhci_check_args(struct usb_hcd *hcd, struct usb_device *udev,
610 struct usb_host_endpoint *ep, int check_ep, const char *func) { 610 struct usb_host_endpoint *ep, int check_ep, bool check_virt_dev,
611 const char *func) {
612 struct xhci_hcd *xhci;
613 struct xhci_virt_device *virt_dev;
614
611 if (!hcd || (check_ep && !ep) || !udev) { 615 if (!hcd || (check_ep && !ep) || !udev) {
612 printk(KERN_DEBUG "xHCI %s called with invalid args\n", 616 printk(KERN_DEBUG "xHCI %s called with invalid args\n",
613 func); 617 func);
@@ -618,11 +622,24 @@ int xhci_check_args(struct usb_hcd *hcd, struct usb_device *udev,
618 func); 622 func);
619 return 0; 623 return 0;
620 } 624 }
621 if (!udev->slot_id) { 625
622 printk(KERN_DEBUG "xHCI %s called with unaddressed device\n", 626 if (check_virt_dev) {
623 func); 627 xhci = hcd_to_xhci(hcd);
624 return -EINVAL; 628 if (!udev->slot_id || !xhci->devs
629 || !xhci->devs[udev->slot_id]) {
630 printk(KERN_DEBUG "xHCI %s called with unaddressed "
631 "device\n", func);
632 return -EINVAL;
633 }
634
635 virt_dev = xhci->devs[udev->slot_id];
636 if (virt_dev->udev != udev) {
637 printk(KERN_DEBUG "xHCI %s called with udev and "
638 "virt_dev does not match\n", func);
639 return -EINVAL;
640 }
625 } 641 }
642
626 return 1; 643 return 1;
627} 644}
628 645
@@ -704,18 +721,13 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
704 struct urb_priv *urb_priv; 721 struct urb_priv *urb_priv;
705 int size, i; 722 int size, i;
706 723
707 if (!urb || xhci_check_args(hcd, urb->dev, urb->ep, true, __func__) <= 0) 724 if (!urb || xhci_check_args(hcd, urb->dev, urb->ep,
725 true, true, __func__) <= 0)
708 return -EINVAL; 726 return -EINVAL;
709 727
710 slot_id = urb->dev->slot_id; 728 slot_id = urb->dev->slot_id;
711 ep_index = xhci_get_endpoint_index(&urb->ep->desc); 729 ep_index = xhci_get_endpoint_index(&urb->ep->desc);
712 730
713 if (!xhci->devs || !xhci->devs[slot_id]) {
714 if (!in_interrupt())
715 dev_warn(&urb->dev->dev, "WARN: urb submitted for dev with no Slot ID\n");
716 ret = -EINVAL;
717 goto exit;
718 }
719 if (!HCD_HW_ACCESSIBLE(hcd)) { 731 if (!HCD_HW_ACCESSIBLE(hcd)) {
720 if (!in_interrupt()) 732 if (!in_interrupt())
721 xhci_dbg(xhci, "urb submitted during PCI suspend\n"); 733 xhci_dbg(xhci, "urb submitted during PCI suspend\n");
@@ -991,7 +1003,7 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
991 u32 new_add_flags, new_drop_flags, new_slot_info; 1003 u32 new_add_flags, new_drop_flags, new_slot_info;
992 int ret; 1004 int ret;
993 1005
994 ret = xhci_check_args(hcd, udev, ep, 1, __func__); 1006 ret = xhci_check_args(hcd, udev, ep, 1, true, __func__);
995 if (ret <= 0) 1007 if (ret <= 0)
996 return ret; 1008 return ret;
997 xhci = hcd_to_xhci(hcd); 1009 xhci = hcd_to_xhci(hcd);
@@ -1004,12 +1016,6 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
1004 return 0; 1016 return 0;
1005 } 1017 }
1006 1018
1007 if (!xhci->devs || !xhci->devs[udev->slot_id]) {
1008 xhci_warn(xhci, "xHCI %s called with unaddressed device\n",
1009 __func__);
1010 return -EINVAL;
1011 }
1012
1013 in_ctx = xhci->devs[udev->slot_id]->in_ctx; 1019 in_ctx = xhci->devs[udev->slot_id]->in_ctx;
1014 out_ctx = xhci->devs[udev->slot_id]->out_ctx; 1020 out_ctx = xhci->devs[udev->slot_id]->out_ctx;
1015 ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); 1021 ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
@@ -1078,7 +1084,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
1078 u32 new_add_flags, new_drop_flags, new_slot_info; 1084 u32 new_add_flags, new_drop_flags, new_slot_info;
1079 int ret = 0; 1085 int ret = 0;
1080 1086
1081 ret = xhci_check_args(hcd, udev, ep, 1, __func__); 1087 ret = xhci_check_args(hcd, udev, ep, 1, true, __func__);
1082 if (ret <= 0) { 1088 if (ret <= 0) {
1083 /* So we won't queue a reset ep command for a root hub */ 1089 /* So we won't queue a reset ep command for a root hub */
1084 ep->hcpriv = NULL; 1090 ep->hcpriv = NULL;
@@ -1098,12 +1104,6 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
1098 return 0; 1104 return 0;
1099 } 1105 }
1100 1106
1101 if (!xhci->devs || !xhci->devs[udev->slot_id]) {
1102 xhci_warn(xhci, "xHCI %s called with unaddressed device\n",
1103 __func__);
1104 return -EINVAL;
1105 }
1106
1107 in_ctx = xhci->devs[udev->slot_id]->in_ctx; 1107 in_ctx = xhci->devs[udev->slot_id]->in_ctx;
1108 out_ctx = xhci->devs[udev->slot_id]->out_ctx; 1108 out_ctx = xhci->devs[udev->slot_id]->out_ctx;
1109 ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); 1109 ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
@@ -1346,16 +1346,11 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
1346 struct xhci_input_control_ctx *ctrl_ctx; 1346 struct xhci_input_control_ctx *ctrl_ctx;
1347 struct xhci_slot_ctx *slot_ctx; 1347 struct xhci_slot_ctx *slot_ctx;
1348 1348
1349 ret = xhci_check_args(hcd, udev, NULL, 0, __func__); 1349 ret = xhci_check_args(hcd, udev, NULL, 0, true, __func__);
1350 if (ret <= 0) 1350 if (ret <= 0)
1351 return ret; 1351 return ret;
1352 xhci = hcd_to_xhci(hcd); 1352 xhci = hcd_to_xhci(hcd);
1353 1353
1354 if (!udev->slot_id || !xhci->devs || !xhci->devs[udev->slot_id]) {
1355 xhci_warn(xhci, "xHCI %s called with unaddressed device\n",
1356 __func__);
1357 return -EINVAL;
1358 }
1359 xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); 1354 xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev);
1360 virt_dev = xhci->devs[udev->slot_id]; 1355 virt_dev = xhci->devs[udev->slot_id];
1361 1356
@@ -1405,16 +1400,11 @@ void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
1405 struct xhci_virt_device *virt_dev; 1400 struct xhci_virt_device *virt_dev;
1406 int i, ret; 1401 int i, ret;
1407 1402
1408 ret = xhci_check_args(hcd, udev, NULL, 0, __func__); 1403 ret = xhci_check_args(hcd, udev, NULL, 0, true, __func__);
1409 if (ret <= 0) 1404 if (ret <= 0)
1410 return; 1405 return;
1411 xhci = hcd_to_xhci(hcd); 1406 xhci = hcd_to_xhci(hcd);
1412 1407
1413 if (!xhci->devs || !xhci->devs[udev->slot_id]) {
1414 xhci_warn(xhci, "xHCI %s called with unaddressed device\n",
1415 __func__);
1416 return;
1417 }
1418 xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); 1408 xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev);
1419 virt_dev = xhci->devs[udev->slot_id]; 1409 virt_dev = xhci->devs[udev->slot_id];
1420 /* Free any rings allocated for added endpoints */ 1410 /* Free any rings allocated for added endpoints */
@@ -1575,7 +1565,7 @@ static int xhci_check_streams_endpoint(struct xhci_hcd *xhci,
1575 1565
1576 if (!ep) 1566 if (!ep)
1577 return -EINVAL; 1567 return -EINVAL;
1578 ret = xhci_check_args(xhci_to_hcd(xhci), udev, ep, 1, __func__); 1568 ret = xhci_check_args(xhci_to_hcd(xhci), udev, ep, 1, true, __func__);
1579 if (ret <= 0) 1569 if (ret <= 0)
1580 return -EINVAL; 1570 return -EINVAL;
1581 if (ep->ss_ep_comp.bmAttributes == 0) { 1571 if (ep->ss_ep_comp.bmAttributes == 0) {
@@ -1965,17 +1955,12 @@ int xhci_reset_device(struct usb_hcd *hcd, struct usb_device *udev)
1965 int timeleft; 1955 int timeleft;
1966 int last_freed_endpoint; 1956 int last_freed_endpoint;
1967 1957
1968 ret = xhci_check_args(hcd, udev, NULL, 0, __func__); 1958 ret = xhci_check_args(hcd, udev, NULL, 0, true, __func__);
1969 if (ret <= 0) 1959 if (ret <= 0)
1970 return ret; 1960 return ret;
1971 xhci = hcd_to_xhci(hcd); 1961 xhci = hcd_to_xhci(hcd);
1972 slot_id = udev->slot_id; 1962 slot_id = udev->slot_id;
1973 virt_dev = xhci->devs[slot_id]; 1963 virt_dev = xhci->devs[slot_id];
1974 if (!virt_dev) {
1975 xhci_dbg(xhci, "%s called with invalid slot ID %u\n",
1976 __func__, slot_id);
1977 return -EINVAL;
1978 }
1979 1964
1980 xhci_dbg(xhci, "Resetting device with slot ID %u\n", slot_id); 1965 xhci_dbg(xhci, "Resetting device with slot ID %u\n", slot_id);
1981 /* Allocate the command structure that holds the struct completion. 1966 /* Allocate the command structure that holds the struct completion.
@@ -2077,13 +2062,13 @@ void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev)
2077 struct xhci_virt_device *virt_dev; 2062 struct xhci_virt_device *virt_dev;
2078 unsigned long flags; 2063 unsigned long flags;
2079 u32 state; 2064 u32 state;
2080 int i; 2065 int i, ret;
2081 2066
2082 if (udev->slot_id == 0) 2067 ret = xhci_check_args(hcd, udev, NULL, 0, true, __func__);
2068 if (ret <= 0)
2083 return; 2069 return;
2070
2084 virt_dev = xhci->devs[udev->slot_id]; 2071 virt_dev = xhci->devs[udev->slot_id];
2085 if (!virt_dev)
2086 return;
2087 2072
2088 /* Stop any wayward timer functions (which may grab the lock) */ 2073 /* Stop any wayward timer functions (which may grab the lock) */
2089 for (i = 0; i < 31; ++i) { 2074 for (i = 0; i < 31; ++i) {
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 34a60d9f056a..f03f140a7d9a 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -731,6 +731,7 @@ struct xhci_virt_ep {
731}; 731};
732 732
733struct xhci_virt_device { 733struct xhci_virt_device {
734 struct usb_device *udev;
734 /* 735 /*
735 * Commands to the hardware are passed an "input context" that 736 * Commands to the hardware are passed an "input context" that
736 * tells the hardware what to change in its data structures. 737 * tells the hardware what to change in its data structures.