diff options
-rw-r--r-- | drivers/usb/core/hub.c | 46 | ||||
-rw-r--r-- | drivers/usb/host/xhci-pci.c | 1 | ||||
-rw-r--r-- | drivers/usb/host/xhci-plat.c | 1 | ||||
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 6 | ||||
-rw-r--r-- | drivers/usb/host/xhci.c | 19 | ||||
-rw-r--r-- | drivers/usb/host/xhci.h | 11 | ||||
-rw-r--r-- | include/linux/usb/hcd.h | 2 |
7 files changed, 75 insertions, 11 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 32e1035d4f59..6a11eff74d3c 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -2498,6 +2498,21 @@ static unsigned hub_is_wusb(struct usb_hub *hub) | |||
2498 | #define HUB_LONG_RESET_TIME 200 | 2498 | #define HUB_LONG_RESET_TIME 200 |
2499 | #define HUB_RESET_TIMEOUT 800 | 2499 | #define HUB_RESET_TIMEOUT 800 |
2500 | 2500 | ||
2501 | /* | ||
2502 | * "New scheme" enumeration causes an extra state transition to be | ||
2503 | * exposed to an xhci host and causes USB3 devices to receive control | ||
2504 | * commands in the default state. This has been seen to cause | ||
2505 | * enumeration failures, so disable this enumeration scheme for USB3 | ||
2506 | * devices. | ||
2507 | */ | ||
2508 | static bool use_new_scheme(struct usb_device *udev, int retry) | ||
2509 | { | ||
2510 | if (udev->speed == USB_SPEED_SUPER) | ||
2511 | return false; | ||
2512 | |||
2513 | return USE_NEW_SCHEME(retry); | ||
2514 | } | ||
2515 | |||
2501 | static int hub_port_reset(struct usb_hub *hub, int port1, | 2516 | static int hub_port_reset(struct usb_hub *hub, int port1, |
2502 | struct usb_device *udev, unsigned int delay, bool warm); | 2517 | struct usb_device *udev, unsigned int delay, bool warm); |
2503 | 2518 | ||
@@ -3956,6 +3971,20 @@ static void hub_set_initial_usb2_lpm_policy(struct usb_device *udev) | |||
3956 | } | 3971 | } |
3957 | } | 3972 | } |
3958 | 3973 | ||
3974 | static int hub_enable_device(struct usb_device *udev) | ||
3975 | { | ||
3976 | struct usb_hcd *hcd = bus_to_hcd(udev->bus); | ||
3977 | |||
3978 | if (!hcd->driver->enable_device) | ||
3979 | return 0; | ||
3980 | if (udev->state == USB_STATE_ADDRESS) | ||
3981 | return 0; | ||
3982 | if (udev->state != USB_STATE_DEFAULT) | ||
3983 | return -EINVAL; | ||
3984 | |||
3985 | return hcd->driver->enable_device(hcd, udev); | ||
3986 | } | ||
3987 | |||
3959 | /* Reset device, (re)assign address, get device descriptor. | 3988 | /* Reset device, (re)assign address, get device descriptor. |
3960 | * Device connection must be stable, no more debouncing needed. | 3989 | * Device connection must be stable, no more debouncing needed. |
3961 | * Returns device in USB_STATE_ADDRESS, except on error. | 3990 | * Returns device in USB_STATE_ADDRESS, except on error. |
@@ -4068,7 +4097,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
4068 | * this area, and this is how Linux has done it for ages. | 4097 | * this area, and this is how Linux has done it for ages. |
4069 | * Change it cautiously. | 4098 | * Change it cautiously. |
4070 | * | 4099 | * |
4071 | * NOTE: If USE_NEW_SCHEME() is true we will start by issuing | 4100 | * NOTE: If use_new_scheme() is true we will start by issuing |
4072 | * a 64-byte GET_DESCRIPTOR request. This is what Windows does, | 4101 | * a 64-byte GET_DESCRIPTOR request. This is what Windows does, |
4073 | * so it may help with some non-standards-compliant devices. | 4102 | * so it may help with some non-standards-compliant devices. |
4074 | * Otherwise we start with SET_ADDRESS and then try to read the | 4103 | * Otherwise we start with SET_ADDRESS and then try to read the |
@@ -4076,10 +4105,17 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
4076 | * value. | 4105 | * value. |
4077 | */ | 4106 | */ |
4078 | for (i = 0; i < GET_DESCRIPTOR_TRIES; (++i, msleep(100))) { | 4107 | for (i = 0; i < GET_DESCRIPTOR_TRIES; (++i, msleep(100))) { |
4079 | if (USE_NEW_SCHEME(retry_counter) && !(hcd->driver->flags & HCD_USB3)) { | 4108 | bool did_new_scheme = false; |
4109 | |||
4110 | if (use_new_scheme(udev, retry_counter)) { | ||
4080 | struct usb_device_descriptor *buf; | 4111 | struct usb_device_descriptor *buf; |
4081 | int r = 0; | 4112 | int r = 0; |
4082 | 4113 | ||
4114 | did_new_scheme = true; | ||
4115 | retval = hub_enable_device(udev); | ||
4116 | if (retval < 0) | ||
4117 | goto fail; | ||
4118 | |||
4083 | #define GET_DESCRIPTOR_BUFSIZE 64 | 4119 | #define GET_DESCRIPTOR_BUFSIZE 64 |
4084 | buf = kmalloc(GET_DESCRIPTOR_BUFSIZE, GFP_NOIO); | 4120 | buf = kmalloc(GET_DESCRIPTOR_BUFSIZE, GFP_NOIO); |
4085 | if (!buf) { | 4121 | if (!buf) { |
@@ -4168,7 +4204,11 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
4168 | * - read ep0 maxpacket even for high and low speed, | 4204 | * - read ep0 maxpacket even for high and low speed, |
4169 | */ | 4205 | */ |
4170 | msleep(10); | 4206 | msleep(10); |
4171 | if (USE_NEW_SCHEME(retry_counter) && !(hcd->driver->flags & HCD_USB3)) | 4207 | /* use_new_scheme() checks the speed which may have |
4208 | * changed since the initial look so we cache the result | ||
4209 | * in did_new_scheme | ||
4210 | */ | ||
4211 | if (did_new_scheme) | ||
4172 | break; | 4212 | break; |
4173 | } | 4213 | } |
4174 | 4214 | ||
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index b8dffd59eb25..4221dee924b5 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c | |||
@@ -331,6 +331,7 @@ static const struct hc_driver xhci_pci_hc_driver = { | |||
331 | .check_bandwidth = xhci_check_bandwidth, | 331 | .check_bandwidth = xhci_check_bandwidth, |
332 | .reset_bandwidth = xhci_reset_bandwidth, | 332 | .reset_bandwidth = xhci_reset_bandwidth, |
333 | .address_device = xhci_address_device, | 333 | .address_device = xhci_address_device, |
334 | .enable_device = xhci_enable_device, | ||
334 | .update_hub_device = xhci_update_hub_device, | 335 | .update_hub_device = xhci_update_hub_device, |
335 | .reset_device = xhci_discover_or_reset_device, | 336 | .reset_device = xhci_discover_or_reset_device, |
336 | 337 | ||
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 9d29aa1b1bc8..8abda5c73ca1 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c | |||
@@ -69,6 +69,7 @@ static const struct hc_driver xhci_plat_xhci_driver = { | |||
69 | .check_bandwidth = xhci_check_bandwidth, | 69 | .check_bandwidth = xhci_check_bandwidth, |
70 | .reset_bandwidth = xhci_reset_bandwidth, | 70 | .reset_bandwidth = xhci_reset_bandwidth, |
71 | .address_device = xhci_address_device, | 71 | .address_device = xhci_address_device, |
72 | .enable_device = xhci_enable_device, | ||
72 | .update_hub_device = xhci_update_hub_device, | 73 | .update_hub_device = xhci_update_hub_device, |
73 | .reset_device = xhci_discover_or_reset_device, | 74 | .reset_device = xhci_discover_or_reset_device, |
74 | 75 | ||
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index fe9208a5d103..d26cd9474aa6 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -4004,12 +4004,12 @@ int xhci_queue_slot_control(struct xhci_hcd *xhci, u32 trb_type, u32 slot_id) | |||
4004 | 4004 | ||
4005 | /* Queue an address device command TRB */ | 4005 | /* Queue an address device command TRB */ |
4006 | int xhci_queue_address_device(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, | 4006 | int xhci_queue_address_device(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, |
4007 | u32 slot_id) | 4007 | u32 slot_id, enum xhci_setup_dev setup) |
4008 | { | 4008 | { |
4009 | return queue_command(xhci, lower_32_bits(in_ctx_ptr), | 4009 | return queue_command(xhci, lower_32_bits(in_ctx_ptr), |
4010 | upper_32_bits(in_ctx_ptr), 0, | 4010 | upper_32_bits(in_ctx_ptr), 0, |
4011 | TRB_TYPE(TRB_ADDR_DEV) | SLOT_ID_FOR_TRB(slot_id), | 4011 | TRB_TYPE(TRB_ADDR_DEV) | SLOT_ID_FOR_TRB(slot_id) |
4012 | false); | 4012 | | (setup == SETUP_CONTEXT_ONLY ? TRB_BSR : 0), false); |
4013 | } | 4013 | } |
4014 | 4014 | ||
4015 | int xhci_queue_vendor_command(struct xhci_hcd *xhci, | 4015 | int xhci_queue_vendor_command(struct xhci_hcd *xhci, |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 7fe6f664054f..6598f7ee7938 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -3709,12 +3709,13 @@ disable_slot: | |||
3709 | } | 3709 | } |
3710 | 3710 | ||
3711 | /* | 3711 | /* |
3712 | * Issue an Address Device command (which will issue a SetAddress request to | 3712 | * Issue an Address Device command and optionally send a corresponding |
3713 | * the device). | 3713 | * SetAddress request to the device. |
3714 | * We should be protected by the usb_address0_mutex in khubd's hub_port_init, so | 3714 | * We should be protected by the usb_address0_mutex in khubd's hub_port_init, so |
3715 | * we should only issue and wait on one address command at the same time. | 3715 | * we should only issue and wait on one address command at the same time. |
3716 | */ | 3716 | */ |
3717 | int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) | 3717 | static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, |
3718 | enum xhci_setup_dev setup) | ||
3718 | { | 3719 | { |
3719 | unsigned long flags; | 3720 | unsigned long flags; |
3720 | int timeleft; | 3721 | int timeleft; |
@@ -3773,7 +3774,7 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
3773 | spin_lock_irqsave(&xhci->lock, flags); | 3774 | spin_lock_irqsave(&xhci->lock, flags); |
3774 | cmd_trb = xhci_find_next_enqueue(xhci->cmd_ring); | 3775 | cmd_trb = xhci_find_next_enqueue(xhci->cmd_ring); |
3775 | ret = xhci_queue_address_device(xhci, virt_dev->in_ctx->dma, | 3776 | ret = xhci_queue_address_device(xhci, virt_dev->in_ctx->dma, |
3776 | udev->slot_id); | 3777 | udev->slot_id, setup); |
3777 | if (ret) { | 3778 | if (ret) { |
3778 | spin_unlock_irqrestore(&xhci->lock, flags); | 3779 | spin_unlock_irqrestore(&xhci->lock, flags); |
3779 | xhci_dbg_trace(xhci, trace_xhci_dbg_address, | 3780 | xhci_dbg_trace(xhci, trace_xhci_dbg_address, |
@@ -3868,6 +3869,16 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
3868 | return 0; | 3869 | return 0; |
3869 | } | 3870 | } |
3870 | 3871 | ||
3872 | int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) | ||
3873 | { | ||
3874 | return xhci_setup_device(hcd, udev, SETUP_CONTEXT_ADDRESS); | ||
3875 | } | ||
3876 | |||
3877 | int xhci_enable_device(struct usb_hcd *hcd, struct usb_device *udev) | ||
3878 | { | ||
3879 | return xhci_setup_device(hcd, udev, SETUP_CONTEXT_ONLY); | ||
3880 | } | ||
3881 | |||
3871 | /* | 3882 | /* |
3872 | * Transfer the port index into real index in the HW port status | 3883 | * Transfer the port index into real index in the HW port status |
3873 | * registers. Caculate offset between the port's PORTSC register | 3884 | * registers. Caculate offset between the port's PORTSC register |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 7807f621a713..24344aab2107 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -1108,6 +1108,14 @@ struct xhci_event_cmd { | |||
1108 | }; | 1108 | }; |
1109 | 1109 | ||
1110 | /* flags bitmasks */ | 1110 | /* flags bitmasks */ |
1111 | |||
1112 | /* Address device - disable SetAddress */ | ||
1113 | #define TRB_BSR (1<<9) | ||
1114 | enum xhci_setup_dev { | ||
1115 | SETUP_CONTEXT_ONLY, | ||
1116 | SETUP_CONTEXT_ADDRESS, | ||
1117 | }; | ||
1118 | |||
1111 | /* bits 16:23 are the virtual function ID */ | 1119 | /* bits 16:23 are the virtual function ID */ |
1112 | /* bits 24:31 are the slot ID */ | 1120 | /* bits 24:31 are the slot ID */ |
1113 | #define TRB_TO_SLOT_ID(p) (((p) & (0xff<<24)) >> 24) | 1121 | #define TRB_TO_SLOT_ID(p) (((p) & (0xff<<24)) >> 24) |
@@ -1760,6 +1768,7 @@ int xhci_free_streams(struct usb_hcd *hcd, struct usb_device *udev, | |||
1760 | struct usb_host_endpoint **eps, unsigned int num_eps, | 1768 | struct usb_host_endpoint **eps, unsigned int num_eps, |
1761 | gfp_t mem_flags); | 1769 | gfp_t mem_flags); |
1762 | int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev); | 1770 | int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev); |
1771 | int xhci_enable_device(struct usb_hcd *hcd, struct usb_device *udev); | ||
1763 | int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev); | 1772 | int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev); |
1764 | int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd, | 1773 | int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd, |
1765 | struct usb_device *udev, int enable); | 1774 | struct usb_device *udev, int enable); |
@@ -1783,7 +1792,7 @@ int xhci_is_vendor_info_code(struct xhci_hcd *xhci, unsigned int trb_comp_code); | |||
1783 | void xhci_ring_cmd_db(struct xhci_hcd *xhci); | 1792 | void xhci_ring_cmd_db(struct xhci_hcd *xhci); |
1784 | int xhci_queue_slot_control(struct xhci_hcd *xhci, u32 trb_type, u32 slot_id); | 1793 | int xhci_queue_slot_control(struct xhci_hcd *xhci, u32 trb_type, u32 slot_id); |
1785 | int xhci_queue_address_device(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, | 1794 | int xhci_queue_address_device(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, |
1786 | u32 slot_id); | 1795 | u32 slot_id, enum xhci_setup_dev); |
1787 | int xhci_queue_vendor_command(struct xhci_hcd *xhci, | 1796 | int xhci_queue_vendor_command(struct xhci_hcd *xhci, |
1788 | u32 field1, u32 field2, u32 field3, u32 field4); | 1797 | u32 field1, u32 field2, u32 field3, u32 field4); |
1789 | int xhci_queue_stop_endpoint(struct xhci_hcd *xhci, int slot_id, | 1798 | int xhci_queue_stop_endpoint(struct xhci_hcd *xhci, int slot_id, |
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 758ce80d085f..efe8d8a7c7ad 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h | |||
@@ -353,6 +353,8 @@ struct hc_driver { | |||
353 | void (*reset_bandwidth)(struct usb_hcd *, struct usb_device *); | 353 | void (*reset_bandwidth)(struct usb_hcd *, struct usb_device *); |
354 | /* Returns the hardware-chosen device address */ | 354 | /* Returns the hardware-chosen device address */ |
355 | int (*address_device)(struct usb_hcd *, struct usb_device *udev); | 355 | int (*address_device)(struct usb_hcd *, struct usb_device *udev); |
356 | /* prepares the hardware to send commands to the device */ | ||
357 | int (*enable_device)(struct usb_hcd *, struct usb_device *udev); | ||
356 | /* Notifies the HCD after a hub descriptor is fetched. | 358 | /* Notifies the HCD after a hub descriptor is fetched. |
357 | * Will block. | 359 | * Will block. |
358 | */ | 360 | */ |