| From b21483a406b1e5d743f73d79fe704f8883eab8a4 Mon Sep 17 00:00:00 2001 |
| From: Lu Baolu <baolu.lu@linux.intel.com> |
| Date: Fri, 11 Nov 2016 15:13:30 +0200 |
| Subject: [PATCH 292/299] usb: xhci: remove the use of xhci->addr_dev |
| |
| xhci->addr_dev is used for the completion of both address device |
| and enable slot commands. It's shared by enumerations of all USB |
| devices connected to an xhci host. Hence, it's just a source for |
| possible races. Since we've introduced command structure and the |
| command queue to xhci driver. It is time to get rid of addr_dev |
| and use the completion in the command structure instead. |
| |
| Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> |
| Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| (cherry picked from commit 87e44f2aac8d45c1e48c94017942fa10037daae0) |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| --- |
| drivers/usb/host/xhci-mem.c | 1 - |
| drivers/usb/host/xhci.c | 18 ++++++++++-------- |
| drivers/usb/host/xhci.h | 1 - |
| 3 files changed, 10 insertions(+), 10 deletions(-) |
| |
| --- a/drivers/usb/host/xhci-mem.c |
| +++ b/drivers/usb/host/xhci-mem.c |
| @@ -2597,7 +2597,6 @@ int xhci_mem_init(struct xhci_hcd *xhci, |
| * something other than the default (~1ms minimum between interrupts). |
| * See section 5.5.1.2. |
| */ |
| - init_completion(&xhci->addr_dev); |
| for (i = 0; i < MAX_HC_SLOTS; ++i) |
| xhci->devs[i] = NULL; |
| for (i = 0; i < USB_MAXCHILDREN; ++i) { |
| --- a/drivers/usb/host/xhci.c |
| +++ b/drivers/usb/host/xhci.c |
| @@ -3680,20 +3680,19 @@ int xhci_alloc_dev(struct usb_hcd *hcd, |
| int ret, slot_id; |
| struct xhci_command *command; |
| |
| - command = xhci_alloc_command(xhci, false, false, GFP_KERNEL); |
| + command = xhci_alloc_command(xhci, false, true, GFP_KERNEL); |
| if (!command) |
| return 0; |
| |
| /* xhci->slot_id and xhci->addr_dev are not thread-safe */ |
| mutex_lock(&xhci->mutex); |
| spin_lock_irqsave(&xhci->lock, flags); |
| - command->completion = &xhci->addr_dev; |
| ret = xhci_queue_slot_control(xhci, command, TRB_ENABLE_SLOT, 0); |
| if (ret) { |
| spin_unlock_irqrestore(&xhci->lock, flags); |
| mutex_unlock(&xhci->mutex); |
| xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); |
| - kfree(command); |
| + xhci_free_command(xhci, command); |
| return 0; |
| } |
| xhci_ring_cmd_db(xhci); |
| @@ -3708,7 +3707,7 @@ int xhci_alloc_dev(struct usb_hcd *hcd, |
| xhci_err(xhci, "Max number of devices this xHCI host supports is %u.\n", |
| HCS_MAX_SLOTS( |
| readl(&xhci->cap_regs->hcs_params1))); |
| - kfree(command); |
| + xhci_free_command(xhci, command); |
| return 0; |
| } |
| |
| @@ -3744,7 +3743,7 @@ int xhci_alloc_dev(struct usb_hcd *hcd, |
| #endif |
| |
| |
| - kfree(command); |
| + xhci_free_command(xhci, command); |
| /* Is this a LS or FS device under a HS hub? */ |
| /* Hub or peripherial? */ |
| return 1; |
| @@ -3752,6 +3751,7 @@ int xhci_alloc_dev(struct usb_hcd *hcd, |
| disable_slot: |
| /* Disable slot, if we can do it without mem alloc */ |
| spin_lock_irqsave(&xhci->lock, flags); |
| + kfree(command->completion); |
| command->completion = NULL; |
| command->status = 0; |
| if (!xhci_queue_slot_control(xhci, command, TRB_DISABLE_SLOT, |
| @@ -3815,14 +3815,13 @@ static int xhci_setup_device(struct usb_ |
| } |
| } |
| |
| - command = xhci_alloc_command(xhci, false, false, GFP_KERNEL); |
| + command = xhci_alloc_command(xhci, false, true, GFP_KERNEL); |
| if (!command) { |
| ret = -ENOMEM; |
| goto out; |
| } |
| |
| command->in_ctx = virt_dev->in_ctx; |
| - command->completion = &xhci->addr_dev; |
| |
| slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); |
| ctrl_ctx = xhci_get_input_control_ctx(virt_dev->in_ctx); |
| @@ -3940,7 +3939,10 @@ static int xhci_setup_device(struct usb_ |
| le32_to_cpu(slot_ctx->dev_state) & DEV_ADDR_MASK); |
| out: |
| mutex_unlock(&xhci->mutex); |
| - kfree(command); |
| + if (command) { |
| + kfree(command->completion); |
| + kfree(command); |
| + } |
| return ret; |
| } |
| |
| --- a/drivers/usb/host/xhci.h |
| +++ b/drivers/usb/host/xhci.h |
| @@ -1580,7 +1580,6 @@ struct xhci_hcd { |
| /* slot enabling and address device helpers */ |
| /* these are not thread safe so use mutex */ |
| struct mutex mutex; |
| - struct completion addr_dev; |
| int slot_id; |
| /* For USB 3.0 LPM enable/disable. */ |
| struct xhci_command *lpm_command; |