usb: xhci: move slot_id from xhci_hcd to xhci_command structure
authorLu Baolu <baolu.lu@linux.intel.com>
Fri, 11 Nov 2016 13:13:31 +0000 (15:13 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 14 Nov 2016 09:18:23 +0000 (10:18 +0100)
xhci->slot_id is used for providing a way to pass slot id from the
command completion handler to the function waiting for completion.
It's shared by enumerations of all USB devices connected to an
xhci host. Hence, it's a source for possible races. Since we've
introduced command structure and the command queue to xhci driver.
It's better to move slot_id from xhci_hcd structure to xhci_command
structure. Hence the race source is removed.

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>
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h

index 7d6fe92a5db78786d35030ea52368200604e5fb5..822f88a52b729d3637b9f3cde41d21579d9f53c2 100644 (file)
@@ -1092,12 +1092,12 @@ static void xhci_handle_cmd_reset_ep(struct xhci_hcd *xhci, int slot_id,
 }
 
 static void xhci_handle_cmd_enable_slot(struct xhci_hcd *xhci, int slot_id,
-               u32 cmd_comp_code)
+               struct xhci_command *command, u32 cmd_comp_code)
 {
        if (cmd_comp_code == COMP_SUCCESS)
-               xhci->slot_id = slot_id;
+               command->slot_id = slot_id;
        else
-               xhci->slot_id = 0;
+               command->slot_id = 0;
 }
 
 static void xhci_handle_cmd_disable_slot(struct xhci_hcd *xhci, int slot_id)
@@ -1366,7 +1366,7 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
        cmd_type = TRB_FIELD_TO_TYPE(le32_to_cpu(cmd_trb->generic.field[3]));
        switch (cmd_type) {
        case TRB_ENABLE_SLOT:
-               xhci_handle_cmd_enable_slot(xhci, slot_id, cmd_comp_code);
+               xhci_handle_cmd_enable_slot(xhci, slot_id, cmd, cmd_comp_code);
                break;
        case TRB_DISABLE_SLOT:
                xhci_handle_cmd_disable_slot(xhci, slot_id);
index 63c902a1f02ab5eb481609ea872a5733c9c8f930..ba46c705225d78933d15e1776b659459bee53598 100644 (file)
@@ -3706,7 +3706,7 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
        spin_unlock_irqrestore(&xhci->lock, flags);
 
        wait_for_completion(command->completion);
-       slot_id = xhci->slot_id;
+       slot_id = command->slot_id;
        mutex_unlock(&xhci->mutex);
 
        if (!slot_id || command->status != COMP_SUCCESS) {
index f24ae0ac12ae53cf7ab2b664fe6ebded2b8f7ddc..266e3a86b6b49e34d3ec69ca71bafd12bd07c587 100644 (file)
@@ -791,6 +791,7 @@ struct xhci_command {
        /* Input context for changing device state */
        struct xhci_container_ctx       *in_ctx;
        u32                             status;
+       int                             slot_id;
        /* If completion is null, no one is waiting on this command
         * and the structure can be freed after the command completes.
         */
@@ -1584,7 +1585,6 @@ struct xhci_hcd {
        /* slot enabling and address device helpers */
        /* these are not thread safe so use mutex */
        struct mutex mutex;
-       int slot_id;
        /* For USB 3.0 LPM enable/disable. */
        struct xhci_command             *lpm_command;
        /* Internal mirror of the HW's dcbaa */