]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
USB: xHCI: Add pointer to udev in struct xhci_virt_device
authorAndiry Xu <andiry.xu@amd.com>
Thu, 14 Oct 2010 14:22:45 +0000 (07:22 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 22 Oct 2010 17:22:11 +0000 (10:22 -0700)
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>
drivers/usb/host/xhci-mem.c
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h

index 4e51343ddffcd4219a88bf781bafa29e10ad5043..be901808e4746b9b6229676671d2c86b2fd253bb 100644 (file)
@@ -778,6 +778,7 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id,
 
        init_completion(&dev->cmd_completion);
        INIT_LIST_HEAD(&dev->cmd_list);
+       dev->udev = udev;
 
        /* Point to output device context in dcbaa. */
        xhci->dcbaa->dev_context_ptrs[slot_id] = dev->out_ctx->dma;
index d5c550ea3e68e5181289bfb009af78cd3f193b7c..0bec0407033491c38b4a8973ab754c86d2715f5f 100644 (file)
@@ -607,7 +607,11 @@ unsigned int xhci_last_valid_endpoint(u32 added_ctxs)
  * returns 0 this is a root hub; returns -EINVAL for NULL pointers.
  */
 int xhci_check_args(struct usb_hcd *hcd, struct usb_device *udev,
-               struct usb_host_endpoint *ep, int check_ep, const char *func) {
+               struct usb_host_endpoint *ep, int check_ep, bool check_virt_dev,
+               const char *func) {
+       struct xhci_hcd *xhci;
+       struct xhci_virt_device *virt_dev;
+
        if (!hcd || (check_ep && !ep) || !udev) {
                printk(KERN_DEBUG "xHCI %s called with invalid args\n",
                                func);
@@ -618,11 +622,24 @@ int xhci_check_args(struct usb_hcd *hcd, struct usb_device *udev,
                                func);
                return 0;
        }
-       if (!udev->slot_id) {
-               printk(KERN_DEBUG "xHCI %s called with unaddressed device\n",
-                               func);
-               return -EINVAL;
+
+       if (check_virt_dev) {
+               xhci = hcd_to_xhci(hcd);
+               if (!udev->slot_id || !xhci->devs
+                       || !xhci->devs[udev->slot_id]) {
+                       printk(KERN_DEBUG "xHCI %s called with unaddressed "
+                                               "device\n", func);
+                       return -EINVAL;
+               }
+
+               virt_dev = xhci->devs[udev->slot_id];
+               if (virt_dev->udev != udev) {
+                       printk(KERN_DEBUG "xHCI %s called with udev and "
+                                         "virt_dev does not match\n", func);
+                       return -EINVAL;
+               }
        }
+
        return 1;
 }
 
@@ -704,18 +721,13 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
        struct urb_priv *urb_priv;
        int size, i;
 
-       if (!urb || xhci_check_args(hcd, urb->dev, urb->ep, true, __func__) <= 0)
+       if (!urb || xhci_check_args(hcd, urb->dev, urb->ep,
+                                       true, true, __func__) <= 0)
                return -EINVAL;
 
        slot_id = urb->dev->slot_id;
        ep_index = xhci_get_endpoint_index(&urb->ep->desc);
 
-       if (!xhci->devs || !xhci->devs[slot_id]) {
-               if (!in_interrupt())
-                       dev_warn(&urb->dev->dev, "WARN: urb submitted for dev with no Slot ID\n");
-               ret = -EINVAL;
-               goto exit;
-       }
        if (!HCD_HW_ACCESSIBLE(hcd)) {
                if (!in_interrupt())
                        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,
        u32 new_add_flags, new_drop_flags, new_slot_info;
        int ret;
 
-       ret = xhci_check_args(hcd, udev, ep, 1, __func__);
+       ret = xhci_check_args(hcd, udev, ep, 1, true, __func__);
        if (ret <= 0)
                return ret;
        xhci = hcd_to_xhci(hcd);
@@ -1004,12 +1016,6 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
                return 0;
        }
 
-       if (!xhci->devs || !xhci->devs[udev->slot_id]) {
-               xhci_warn(xhci, "xHCI %s called with unaddressed device\n",
-                               __func__);
-               return -EINVAL;
-       }
-
        in_ctx = xhci->devs[udev->slot_id]->in_ctx;
        out_ctx = xhci->devs[udev->slot_id]->out_ctx;
        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,
        u32 new_add_flags, new_drop_flags, new_slot_info;
        int ret = 0;
 
-       ret = xhci_check_args(hcd, udev, ep, 1, __func__);
+       ret = xhci_check_args(hcd, udev, ep, 1, true, __func__);
        if (ret <= 0) {
                /* So we won't queue a reset ep command for a root hub */
                ep->hcpriv = NULL;
@@ -1098,12 +1104,6 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
                return 0;
        }
 
-       if (!xhci->devs || !xhci->devs[udev->slot_id]) {
-               xhci_warn(xhci, "xHCI %s called with unaddressed device\n",
-                               __func__);
-               return -EINVAL;
-       }
-
        in_ctx = xhci->devs[udev->slot_id]->in_ctx;
        out_ctx = xhci->devs[udev->slot_id]->out_ctx;
        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)
        struct xhci_input_control_ctx *ctrl_ctx;
        struct xhci_slot_ctx *slot_ctx;
 
-       ret = xhci_check_args(hcd, udev, NULL, 0, __func__);
+       ret = xhci_check_args(hcd, udev, NULL, 0, true, __func__);
        if (ret <= 0)
                return ret;
        xhci = hcd_to_xhci(hcd);
 
-       if (!udev->slot_id || !xhci->devs || !xhci->devs[udev->slot_id]) {
-               xhci_warn(xhci, "xHCI %s called with unaddressed device\n",
-                               __func__);
-               return -EINVAL;
-       }
        xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev);
        virt_dev = xhci->devs[udev->slot_id];
 
@@ -1405,16 +1400,11 @@ void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
        struct xhci_virt_device *virt_dev;
        int i, ret;
 
-       ret = xhci_check_args(hcd, udev, NULL, 0, __func__);
+       ret = xhci_check_args(hcd, udev, NULL, 0, true, __func__);
        if (ret <= 0)
                return;
        xhci = hcd_to_xhci(hcd);
 
-       if (!xhci->devs || !xhci->devs[udev->slot_id]) {
-               xhci_warn(xhci, "xHCI %s called with unaddressed device\n",
-                               __func__);
-               return;
-       }
        xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev);
        virt_dev = xhci->devs[udev->slot_id];
        /* Free any rings allocated for added endpoints */
@@ -1575,7 +1565,7 @@ static int xhci_check_streams_endpoint(struct xhci_hcd *xhci,
 
        if (!ep)
                return -EINVAL;
-       ret = xhci_check_args(xhci_to_hcd(xhci), udev, ep, 1, __func__);
+       ret = xhci_check_args(xhci_to_hcd(xhci), udev, ep, 1, true, __func__);
        if (ret <= 0)
                return -EINVAL;
        if (ep->ss_ep_comp.bmAttributes == 0) {
@@ -1965,17 +1955,12 @@ int xhci_reset_device(struct usb_hcd *hcd, struct usb_device *udev)
        int timeleft;
        int last_freed_endpoint;
 
-       ret = xhci_check_args(hcd, udev, NULL, 0, __func__);
+       ret = xhci_check_args(hcd, udev, NULL, 0, true, __func__);
        if (ret <= 0)
                return ret;
        xhci = hcd_to_xhci(hcd);
        slot_id = udev->slot_id;
        virt_dev = xhci->devs[slot_id];
-       if (!virt_dev) {
-               xhci_dbg(xhci, "%s called with invalid slot ID %u\n",
-                               __func__, slot_id);
-               return -EINVAL;
-       }
 
        xhci_dbg(xhci, "Resetting device with slot ID %u\n", slot_id);
        /* 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)
        struct xhci_virt_device *virt_dev;
        unsigned long flags;
        u32 state;
-       int i;
+       int i, ret;
 
-       if (udev->slot_id == 0)
+       ret = xhci_check_args(hcd, udev, NULL, 0, true, __func__);
+       if (ret <= 0)
                return;
+
        virt_dev = xhci->devs[udev->slot_id];
-       if (!virt_dev)
-               return;
 
        /* Stop any wayward timer functions (which may grab the lock) */
        for (i = 0; i < 31; ++i) {
index 34a60d9f056a2b71a65d22cc9942f60d5d844da5..f03f140a7d9aa8ffce106516a351da70c43b2238 100644 (file)
@@ -731,6 +731,7 @@ struct xhci_virt_ep {
 };
 
 struct xhci_virt_device {
+       struct usb_device               *udev;
        /*
         * Commands to the hardware are passed an "input context" that
         * tells the hardware what to change in its data structures.