diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/core/hub.c | 27 | ||||
-rw-r--r-- | drivers/usb/host/xhci.c | 8 | ||||
-rw-r--r-- | drivers/usb/host/xhci.h | 2 |
3 files changed, 19 insertions, 18 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 5da546c4fd79..f07ab71859dd 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -2594,16 +2594,14 @@ static int hub_set_address(struct usb_device *udev, int devnum) | |||
2594 | return 0; | 2594 | return 0; |
2595 | if (udev->state != USB_STATE_DEFAULT) | 2595 | if (udev->state != USB_STATE_DEFAULT) |
2596 | return -EINVAL; | 2596 | return -EINVAL; |
2597 | if (hcd->driver->address_device) { | 2597 | if (hcd->driver->address_device) |
2598 | retval = hcd->driver->address_device(hcd, udev); | 2598 | retval = hcd->driver->address_device(hcd, udev); |
2599 | } else { | 2599 | else |
2600 | retval = usb_control_msg(udev, usb_sndaddr0pipe(), | 2600 | retval = usb_control_msg(udev, usb_sndaddr0pipe(), |
2601 | USB_REQ_SET_ADDRESS, 0, devnum, 0, | 2601 | USB_REQ_SET_ADDRESS, 0, devnum, 0, |
2602 | NULL, 0, USB_CTRL_SET_TIMEOUT); | 2602 | NULL, 0, USB_CTRL_SET_TIMEOUT); |
2603 | if (retval == 0) | ||
2604 | update_address(udev, devnum); | ||
2605 | } | ||
2606 | if (retval == 0) { | 2603 | if (retval == 0) { |
2604 | update_address(udev, devnum); | ||
2607 | /* Device now using proper address. */ | 2605 | /* Device now using proper address. */ |
2608 | usb_set_device_state(udev, USB_STATE_ADDRESS); | 2606 | usb_set_device_state(udev, USB_STATE_ADDRESS); |
2609 | usb_ep0_reinit(udev); | 2607 | usb_ep0_reinit(udev); |
@@ -3097,16 +3095,17 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
3097 | udev->speed = USB_SPEED_UNKNOWN; | 3095 | udev->speed = USB_SPEED_UNKNOWN; |
3098 | 3096 | ||
3099 | /* | 3097 | /* |
3100 | * xHCI needs to issue an address device command later | 3098 | * Set the address. |
3101 | * in the hub_port_init sequence for SS/HS/FS/LS devices. | 3099 | * Note xHCI needs to issue an address device command later |
3100 | * in the hub_port_init sequence for SS/HS/FS/LS devices, | ||
3101 | * and xHC will assign an address to the device. But use | ||
3102 | * kernel assigned address here, to avoid any address conflict | ||
3103 | * issue. | ||
3102 | */ | 3104 | */ |
3103 | if (!(hcd->driver->flags & HCD_USB3)) { | 3105 | choose_address(udev); |
3104 | /* set the address */ | 3106 | if (udev->devnum <= 0) { |
3105 | choose_address(udev); | 3107 | status = -ENOTCONN; /* Don't retry */ |
3106 | if (udev->devnum <= 0) { | 3108 | goto loop; |
3107 | status = -ENOTCONN; /* Don't retry */ | ||
3108 | goto loop; | ||
3109 | } | ||
3110 | } | 3109 | } |
3111 | 3110 | ||
3112 | /* reset (non-USB 3.0 devices) and get descriptor */ | 3111 | /* reset (non-USB 3.0 devices) and get descriptor */ |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 7928af5c91cb..caccecb7368e 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -2287,15 +2287,15 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
2287 | * address given back to us by the HC. | 2287 | * address given back to us by the HC. |
2288 | */ | 2288 | */ |
2289 | slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->out_ctx); | 2289 | slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->out_ctx); |
2290 | udev->devnum = (slot_ctx->dev_state & DEV_ADDR_MASK) + 1; | 2290 | /* Use kernel assigned address for devices; store xHC assigned |
2291 | * address locally. */ | ||
2292 | virt_dev->address = (slot_ctx->dev_state & DEV_ADDR_MASK) + 1; | ||
2291 | /* Zero the input context control for later use */ | 2293 | /* Zero the input context control for later use */ |
2292 | ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); | 2294 | ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); |
2293 | ctrl_ctx->add_flags = 0; | 2295 | ctrl_ctx->add_flags = 0; |
2294 | ctrl_ctx->drop_flags = 0; | 2296 | ctrl_ctx->drop_flags = 0; |
2295 | 2297 | ||
2296 | xhci_dbg(xhci, "Device address = %d\n", udev->devnum); | 2298 | xhci_dbg(xhci, "Internal device address = %d\n", virt_dev->address); |
2297 | /* XXX Meh, not sure if anyone else but choose_address uses this. */ | ||
2298 | set_bit(udev->devnum, udev->bus->devmap.devicemap); | ||
2299 | 2299 | ||
2300 | return 0; | 2300 | return 0; |
2301 | } | 2301 | } |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 490409f918f2..a7181b491e67 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -746,6 +746,8 @@ struct xhci_virt_device { | |||
746 | /* Rings saved to ensure old alt settings can be re-instated */ | 746 | /* Rings saved to ensure old alt settings can be re-instated */ |
747 | struct xhci_ring **ring_cache; | 747 | struct xhci_ring **ring_cache; |
748 | int num_rings_cached; | 748 | int num_rings_cached; |
749 | /* Store xHC assigned device address */ | ||
750 | int address; | ||
749 | #define XHCI_MAX_RINGS_CACHED 31 | 751 | #define XHCI_MAX_RINGS_CACHED 31 |
750 | struct xhci_virt_ep eps[31]; | 752 | struct xhci_virt_ep eps[31]; |
751 | struct completion cmd_completion; | 753 | struct completion cmd_completion; |