diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-23 15:33:02 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-23 15:33:02 -0400 |
commit | c44dead70a841d90ddc01968012f323c33217c9e (patch) | |
tree | 85489ebe9b9a3413cd8ee197ffb40c8aa8d97e63 /drivers/usb/core | |
parent | 99dff5856220a02b8711f2e8746413ea6e53ccf6 (diff) | |
parent | d5f6db9e1aff6ccf1876224f152c0268b0c8a992 (diff) |
Merge branch 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (205 commits)
USB: EHCI: Remove SPARC_LEON {read,write}_be definitions from ehci.h
USB: UHCI: Support big endian GRUSBHC HC
sparc: add {read,write}*_be routines
USB: UHCI: Add support for big endian descriptors
USB: UHCI: Use ACCESS_ONCE rather than using a full compiler barrier
USB: UHCI: Add support for big endian mmio
usb-storage: Correct adjust_quirks to include latest flags
usb/isp1760: Fix possible unlink problems
usb/isp1760: Move function isp1760_endpoint_disable() within file.
USB: remove remaining usages of hcd->state from usbcore and fix regression
usb: musb: ux500: add configuration and build options for ux500 dma
usb: musb: ux500: add dma glue layer for ux500
usb: musb: ux500: add dma name for ux500
usb: musb: ux500: add ux500 specific code for gadget side
usb: musb: fix compile error
usb-storage: fix up the unusual_realtek device list
USB: gadget: f_audio: Fix invalid dereference of initdata
EHCI: don't rescan interrupt QHs needlessly
OHCI: fix regression caused by nVidia shutdown workaround
USB: OTG: msm: Free VCCCX regulator even if we can't set the voltage
...
Diffstat (limited to 'drivers/usb/core')
-rw-r--r-- | drivers/usb/core/config.c | 2 | ||||
-rw-r--r-- | drivers/usb/core/devices.c | 22 | ||||
-rw-r--r-- | drivers/usb/core/file.c | 8 | ||||
-rw-r--r-- | drivers/usb/core/hcd.c | 6 | ||||
-rw-r--r-- | drivers/usb/core/hub.c | 131 | ||||
-rw-r--r-- | drivers/usb/core/sysfs.c | 13 | ||||
-rw-r--r-- | drivers/usb/core/usb.c | 3 | ||||
-rw-r--r-- | drivers/usb/core/usb.h | 2 |
8 files changed, 124 insertions, 63 deletions
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 83126b03e7c..c962608b4b9 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c | |||
@@ -129,7 +129,7 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, | |||
129 | max_tx = ep->desc.wMaxPacketSize * (desc->bMaxBurst + 1); | 129 | max_tx = ep->desc.wMaxPacketSize * (desc->bMaxBurst + 1); |
130 | else | 130 | else |
131 | max_tx = 999999; | 131 | max_tx = 999999; |
132 | if (desc->wBytesPerInterval > max_tx) { | 132 | if (le16_to_cpu(desc->wBytesPerInterval) > max_tx) { |
133 | dev_warn(ddev, "%s endpoint with wBytesPerInterval of %d in " | 133 | dev_warn(ddev, "%s endpoint with wBytesPerInterval of %d in " |
134 | "config %d interface %d altsetting %d ep %d: " | 134 | "config %d interface %d altsetting %d ep %d: " |
135 | "setting to %d\n", | 135 | "setting to %d\n", |
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c index 96fdfb815f8..0149c0976e9 100644 --- a/drivers/usb/core/devices.c +++ b/drivers/usb/core/devices.c | |||
@@ -64,49 +64,49 @@ | |||
64 | /* Define ALLOW_SERIAL_NUMBER if you want to see the serial number of devices */ | 64 | /* Define ALLOW_SERIAL_NUMBER if you want to see the serial number of devices */ |
65 | #define ALLOW_SERIAL_NUMBER | 65 | #define ALLOW_SERIAL_NUMBER |
66 | 66 | ||
67 | static const char *format_topo = | 67 | static const char format_topo[] = |
68 | /* T: Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=dddd MxCh=dd */ | 68 | /* T: Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=dddd MxCh=dd */ |
69 | "\nT: Bus=%2.2d Lev=%2.2d Prnt=%2.2d Port=%2.2d Cnt=%2.2d Dev#=%3d Spd=%-4s MxCh=%2d\n"; | 69 | "\nT: Bus=%2.2d Lev=%2.2d Prnt=%2.2d Port=%2.2d Cnt=%2.2d Dev#=%3d Spd=%-4s MxCh=%2d\n"; |
70 | 70 | ||
71 | static const char *format_string_manufacturer = | 71 | static const char format_string_manufacturer[] = |
72 | /* S: Manufacturer=xxxx */ | 72 | /* S: Manufacturer=xxxx */ |
73 | "S: Manufacturer=%.100s\n"; | 73 | "S: Manufacturer=%.100s\n"; |
74 | 74 | ||
75 | static const char *format_string_product = | 75 | static const char format_string_product[] = |
76 | /* S: Product=xxxx */ | 76 | /* S: Product=xxxx */ |
77 | "S: Product=%.100s\n"; | 77 | "S: Product=%.100s\n"; |
78 | 78 | ||
79 | #ifdef ALLOW_SERIAL_NUMBER | 79 | #ifdef ALLOW_SERIAL_NUMBER |
80 | static const char *format_string_serialnumber = | 80 | static const char format_string_serialnumber[] = |
81 | /* S: SerialNumber=xxxx */ | 81 | /* S: SerialNumber=xxxx */ |
82 | "S: SerialNumber=%.100s\n"; | 82 | "S: SerialNumber=%.100s\n"; |
83 | #endif | 83 | #endif |
84 | 84 | ||
85 | static const char *format_bandwidth = | 85 | static const char format_bandwidth[] = |
86 | /* B: Alloc=ddd/ddd us (xx%), #Int=ddd, #Iso=ddd */ | 86 | /* B: Alloc=ddd/ddd us (xx%), #Int=ddd, #Iso=ddd */ |
87 | "B: Alloc=%3d/%3d us (%2d%%), #Int=%3d, #Iso=%3d\n"; | 87 | "B: Alloc=%3d/%3d us (%2d%%), #Int=%3d, #Iso=%3d\n"; |
88 | 88 | ||
89 | static const char *format_device1 = | 89 | static const char format_device1[] = |
90 | /* D: Ver=xx.xx Cls=xx(sssss) Sub=xx Prot=xx MxPS=dd #Cfgs=dd */ | 90 | /* D: Ver=xx.xx Cls=xx(sssss) Sub=xx Prot=xx MxPS=dd #Cfgs=dd */ |
91 | "D: Ver=%2x.%02x Cls=%02x(%-5s) Sub=%02x Prot=%02x MxPS=%2d #Cfgs=%3d\n"; | 91 | "D: Ver=%2x.%02x Cls=%02x(%-5s) Sub=%02x Prot=%02x MxPS=%2d #Cfgs=%3d\n"; |
92 | 92 | ||
93 | static const char *format_device2 = | 93 | static const char format_device2[] = |
94 | /* P: Vendor=xxxx ProdID=xxxx Rev=xx.xx */ | 94 | /* P: Vendor=xxxx ProdID=xxxx Rev=xx.xx */ |
95 | "P: Vendor=%04x ProdID=%04x Rev=%2x.%02x\n"; | 95 | "P: Vendor=%04x ProdID=%04x Rev=%2x.%02x\n"; |
96 | 96 | ||
97 | static const char *format_config = | 97 | static const char format_config[] = |
98 | /* C: #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA */ | 98 | /* C: #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA */ |
99 | "C:%c #Ifs=%2d Cfg#=%2d Atr=%02x MxPwr=%3dmA\n"; | 99 | "C:%c #Ifs=%2d Cfg#=%2d Atr=%02x MxPwr=%3dmA\n"; |
100 | 100 | ||
101 | static const char *format_iad = | 101 | static const char format_iad[] = |
102 | /* A: FirstIf#=dd IfCount=dd Cls=xx(sssss) Sub=xx Prot=xx */ | 102 | /* A: FirstIf#=dd IfCount=dd Cls=xx(sssss) Sub=xx Prot=xx */ |
103 | "A: FirstIf#=%2d IfCount=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x\n"; | 103 | "A: FirstIf#=%2d IfCount=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x\n"; |
104 | 104 | ||
105 | static const char *format_iface = | 105 | static const char format_iface[] = |
106 | /* I: If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=xxxx*/ | 106 | /* I: If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=xxxx*/ |
107 | "I:%c If#=%2d Alt=%2d #EPs=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x Driver=%s\n"; | 107 | "I:%c If#=%2d Alt=%2d #EPs=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x Driver=%s\n"; |
108 | 108 | ||
109 | static const char *format_endpt = | 109 | static const char format_endpt[] = |
110 | /* E: Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=D?s */ | 110 | /* E: Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=D?s */ |
111 | "E: Ad=%02x(%c) Atr=%02x(%-4s) MxPS=%4d Ivl=%d%cs\n"; | 111 | "E: Ad=%02x(%c) Atr=%02x(%-4s) MxPS=%4d Ivl=%d%cs\n"; |
112 | 112 | ||
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index cf6a5423de0..99458c843d6 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c | |||
@@ -236,13 +236,6 @@ EXPORT_SYMBOL_GPL(usb_register_dev); | |||
236 | void usb_deregister_dev(struct usb_interface *intf, | 236 | void usb_deregister_dev(struct usb_interface *intf, |
237 | struct usb_class_driver *class_driver) | 237 | struct usb_class_driver *class_driver) |
238 | { | 238 | { |
239 | int minor_base = class_driver->minor_base; | ||
240 | char name[20]; | ||
241 | |||
242 | #ifdef CONFIG_USB_DYNAMIC_MINORS | ||
243 | minor_base = 0; | ||
244 | #endif | ||
245 | |||
246 | if (intf->minor == -1) | 239 | if (intf->minor == -1) |
247 | return; | 240 | return; |
248 | 241 | ||
@@ -252,7 +245,6 @@ void usb_deregister_dev(struct usb_interface *intf, | |||
252 | usb_minors[intf->minor] = NULL; | 245 | usb_minors[intf->minor] = NULL; |
253 | up_write(&minor_rwsem); | 246 | up_write(&minor_rwsem); |
254 | 247 | ||
255 | snprintf(name, sizeof(name), class_driver->name, intf->minor - minor_base); | ||
256 | device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor)); | 248 | device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor)); |
257 | intf->usb_dev = NULL; | 249 | intf->usb_dev = NULL; |
258 | intf->minor = -1; | 250 | intf->minor = -1; |
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 77a7faec8d7..ace9f8442e5 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -986,7 +986,7 @@ static int register_root_hub(struct usb_hcd *hcd) | |||
986 | spin_unlock_irq (&hcd_root_hub_lock); | 986 | spin_unlock_irq (&hcd_root_hub_lock); |
987 | 987 | ||
988 | /* Did the HC die before the root hub was registered? */ | 988 | /* Did the HC die before the root hub was registered? */ |
989 | if (HCD_DEAD(hcd) || hcd->state == HC_STATE_HALT) | 989 | if (HCD_DEAD(hcd)) |
990 | usb_hc_died (hcd); /* This time clean up */ | 990 | usb_hc_died (hcd); /* This time clean up */ |
991 | } | 991 | } |
992 | 992 | ||
@@ -2128,9 +2128,6 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd) | |||
2128 | set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); | 2128 | set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); |
2129 | if (hcd->shared_hcd) | 2129 | if (hcd->shared_hcd) |
2130 | set_bit(HCD_FLAG_SAW_IRQ, &hcd->shared_hcd->flags); | 2130 | set_bit(HCD_FLAG_SAW_IRQ, &hcd->shared_hcd->flags); |
2131 | |||
2132 | if (unlikely(hcd->state == HC_STATE_HALT)) | ||
2133 | usb_hc_died(hcd); | ||
2134 | rc = IRQ_HANDLED; | 2131 | rc = IRQ_HANDLED; |
2135 | } | 2132 | } |
2136 | 2133 | ||
@@ -2407,6 +2404,7 @@ int usb_add_hcd(struct usb_hcd *hcd, | |||
2407 | rhdev->speed = USB_SPEED_SUPER; | 2404 | rhdev->speed = USB_SPEED_SUPER; |
2408 | break; | 2405 | break; |
2409 | default: | 2406 | default: |
2407 | retval = -EINVAL; | ||
2410 | goto err_set_rh_speed; | 2408 | goto err_set_rh_speed; |
2411 | } | 2409 | } |
2412 | 2410 | ||
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 93720bdc9ef..79a58c3a2e2 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -379,15 +379,6 @@ static int hub_port_status(struct usb_hub *hub, int port1, | |||
379 | *status = le16_to_cpu(hub->status->port.wPortStatus); | 379 | *status = le16_to_cpu(hub->status->port.wPortStatus); |
380 | *change = le16_to_cpu(hub->status->port.wPortChange); | 380 | *change = le16_to_cpu(hub->status->port.wPortChange); |
381 | 381 | ||
382 | if ((hub->hdev->parent != NULL) && | ||
383 | hub_is_superspeed(hub->hdev)) { | ||
384 | /* Translate the USB 3 port status */ | ||
385 | u16 tmp = *status & USB_SS_PORT_STAT_MASK; | ||
386 | if (*status & USB_SS_PORT_STAT_POWER) | ||
387 | tmp |= USB_PORT_STAT_POWER; | ||
388 | *status = tmp; | ||
389 | } | ||
390 | |||
391 | ret = 0; | 382 | ret = 0; |
392 | } | 383 | } |
393 | mutex_unlock(&hub->status_mutex); | 384 | mutex_unlock(&hub->status_mutex); |
@@ -2160,11 +2151,76 @@ static int hub_port_reset(struct usb_hub *hub, int port1, | |||
2160 | return status; | 2151 | return status; |
2161 | } | 2152 | } |
2162 | 2153 | ||
2154 | /* Warm reset a USB3 protocol port */ | ||
2155 | static int hub_port_warm_reset(struct usb_hub *hub, int port) | ||
2156 | { | ||
2157 | int ret; | ||
2158 | u16 portstatus, portchange; | ||
2159 | |||
2160 | if (!hub_is_superspeed(hub->hdev)) { | ||
2161 | dev_err(hub->intfdev, "only USB3 hub support warm reset\n"); | ||
2162 | return -EINVAL; | ||
2163 | } | ||
2164 | |||
2165 | /* Warm reset the port */ | ||
2166 | ret = set_port_feature(hub->hdev, | ||
2167 | port, USB_PORT_FEAT_BH_PORT_RESET); | ||
2168 | if (ret) { | ||
2169 | dev_err(hub->intfdev, "cannot warm reset port %d\n", port); | ||
2170 | return ret; | ||
2171 | } | ||
2172 | |||
2173 | msleep(20); | ||
2174 | ret = hub_port_status(hub, port, &portstatus, &portchange); | ||
2175 | |||
2176 | if (portchange & USB_PORT_STAT_C_RESET) | ||
2177 | clear_port_feature(hub->hdev, port, USB_PORT_FEAT_C_RESET); | ||
2178 | |||
2179 | if (portchange & USB_PORT_STAT_C_BH_RESET) | ||
2180 | clear_port_feature(hub->hdev, port, | ||
2181 | USB_PORT_FEAT_C_BH_PORT_RESET); | ||
2182 | |||
2183 | if (portchange & USB_PORT_STAT_C_LINK_STATE) | ||
2184 | clear_port_feature(hub->hdev, port, | ||
2185 | USB_PORT_FEAT_C_PORT_LINK_STATE); | ||
2186 | |||
2187 | return ret; | ||
2188 | } | ||
2189 | |||
2190 | /* Check if a port is power on */ | ||
2191 | static int port_is_power_on(struct usb_hub *hub, unsigned portstatus) | ||
2192 | { | ||
2193 | int ret = 0; | ||
2194 | |||
2195 | if (hub_is_superspeed(hub->hdev)) { | ||
2196 | if (portstatus & USB_SS_PORT_STAT_POWER) | ||
2197 | ret = 1; | ||
2198 | } else { | ||
2199 | if (portstatus & USB_PORT_STAT_POWER) | ||
2200 | ret = 1; | ||
2201 | } | ||
2202 | |||
2203 | return ret; | ||
2204 | } | ||
2205 | |||
2163 | #ifdef CONFIG_PM | 2206 | #ifdef CONFIG_PM |
2164 | 2207 | ||
2165 | #define MASK_BITS (USB_PORT_STAT_POWER | USB_PORT_STAT_CONNECTION | \ | 2208 | /* Check if a port is suspended(USB2.0 port) or in U3 state(USB3.0 port) */ |
2166 | USB_PORT_STAT_SUSPEND) | 2209 | static int port_is_suspended(struct usb_hub *hub, unsigned portstatus) |
2167 | #define WANT_BITS (USB_PORT_STAT_POWER | USB_PORT_STAT_CONNECTION) | 2210 | { |
2211 | int ret = 0; | ||
2212 | |||
2213 | if (hub_is_superspeed(hub->hdev)) { | ||
2214 | if ((portstatus & USB_PORT_STAT_LINK_STATE) | ||
2215 | == USB_SS_PORT_LS_U3) | ||
2216 | ret = 1; | ||
2217 | } else { | ||
2218 | if (portstatus & USB_PORT_STAT_SUSPEND) | ||
2219 | ret = 1; | ||
2220 | } | ||
2221 | |||
2222 | return ret; | ||
2223 | } | ||
2168 | 2224 | ||
2169 | /* Determine whether the device on a port is ready for a normal resume, | 2225 | /* Determine whether the device on a port is ready for a normal resume, |
2170 | * is ready for a reset-resume, or should be disconnected. | 2226 | * is ready for a reset-resume, or should be disconnected. |
@@ -2174,7 +2230,9 @@ static int check_port_resume_type(struct usb_device *udev, | |||
2174 | int status, unsigned portchange, unsigned portstatus) | 2230 | int status, unsigned portchange, unsigned portstatus) |
2175 | { | 2231 | { |
2176 | /* Is the device still present? */ | 2232 | /* Is the device still present? */ |
2177 | if (status || (portstatus & MASK_BITS) != WANT_BITS) { | 2233 | if (status || port_is_suspended(hub, portstatus) || |
2234 | !port_is_power_on(hub, portstatus) || | ||
2235 | !(portstatus & USB_PORT_STAT_CONNECTION)) { | ||
2178 | if (status >= 0) | 2236 | if (status >= 0) |
2179 | status = -ENODEV; | 2237 | status = -ENODEV; |
2180 | } | 2238 | } |
@@ -2285,14 +2343,10 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) | |||
2285 | } | 2343 | } |
2286 | 2344 | ||
2287 | /* see 7.1.7.6 */ | 2345 | /* see 7.1.7.6 */ |
2288 | /* Clear PORT_POWER if it's a USB3.0 device connected to USB 3.0 | 2346 | if (hub_is_superspeed(hub->hdev)) |
2289 | * external hub. | 2347 | status = set_port_feature(hub->hdev, |
2290 | * FIXME: this is a temporary workaround to make the system able | 2348 | port1 | (USB_SS_PORT_LS_U3 << 3), |
2291 | * to suspend/resume. | 2349 | USB_PORT_FEAT_LINK_STATE); |
2292 | */ | ||
2293 | if ((hub->hdev->parent != NULL) && hub_is_superspeed(hub->hdev)) | ||
2294 | status = clear_port_feature(hub->hdev, port1, | ||
2295 | USB_PORT_FEAT_POWER); | ||
2296 | else | 2350 | else |
2297 | status = set_port_feature(hub->hdev, port1, | 2351 | status = set_port_feature(hub->hdev, port1, |
2298 | USB_PORT_FEAT_SUSPEND); | 2352 | USB_PORT_FEAT_SUSPEND); |
@@ -2439,7 +2493,7 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg) | |||
2439 | 2493 | ||
2440 | /* Skip the initial Clear-Suspend step for a remote wakeup */ | 2494 | /* Skip the initial Clear-Suspend step for a remote wakeup */ |
2441 | status = hub_port_status(hub, port1, &portstatus, &portchange); | 2495 | status = hub_port_status(hub, port1, &portstatus, &portchange); |
2442 | if (status == 0 && !(portstatus & USB_PORT_STAT_SUSPEND)) | 2496 | if (status == 0 && !port_is_suspended(hub, portstatus)) |
2443 | goto SuspendCleared; | 2497 | goto SuspendCleared; |
2444 | 2498 | ||
2445 | // dev_dbg(hub->intfdev, "resume port %d\n", port1); | 2499 | // dev_dbg(hub->intfdev, "resume port %d\n", port1); |
@@ -2447,8 +2501,13 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg) | |||
2447 | set_bit(port1, hub->busy_bits); | 2501 | set_bit(port1, hub->busy_bits); |
2448 | 2502 | ||
2449 | /* see 7.1.7.7; affects power usage, but not budgeting */ | 2503 | /* see 7.1.7.7; affects power usage, but not budgeting */ |
2450 | status = clear_port_feature(hub->hdev, | 2504 | if (hub_is_superspeed(hub->hdev)) |
2451 | port1, USB_PORT_FEAT_SUSPEND); | 2505 | status = set_port_feature(hub->hdev, |
2506 | port1 | (USB_SS_PORT_LS_U0 << 3), | ||
2507 | USB_PORT_FEAT_LINK_STATE); | ||
2508 | else | ||
2509 | status = clear_port_feature(hub->hdev, | ||
2510 | port1, USB_PORT_FEAT_SUSPEND); | ||
2452 | if (status) { | 2511 | if (status) { |
2453 | dev_dbg(hub->intfdev, "can't resume port %d, status %d\n", | 2512 | dev_dbg(hub->intfdev, "can't resume port %d, status %d\n", |
2454 | port1, status); | 2513 | port1, status); |
@@ -2470,9 +2529,15 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg) | |||
2470 | 2529 | ||
2471 | SuspendCleared: | 2530 | SuspendCleared: |
2472 | if (status == 0) { | 2531 | if (status == 0) { |
2473 | if (portchange & USB_PORT_STAT_C_SUSPEND) | 2532 | if (hub_is_superspeed(hub->hdev)) { |
2474 | clear_port_feature(hub->hdev, port1, | 2533 | if (portchange & USB_PORT_STAT_C_LINK_STATE) |
2475 | USB_PORT_FEAT_C_SUSPEND); | 2534 | clear_port_feature(hub->hdev, port1, |
2535 | USB_PORT_FEAT_C_PORT_LINK_STATE); | ||
2536 | } else { | ||
2537 | if (portchange & USB_PORT_STAT_C_SUSPEND) | ||
2538 | clear_port_feature(hub->hdev, port1, | ||
2539 | USB_PORT_FEAT_C_SUSPEND); | ||
2540 | } | ||
2476 | } | 2541 | } |
2477 | 2542 | ||
2478 | clear_bit(port1, hub->busy_bits); | 2543 | clear_bit(port1, hub->busy_bits); |
@@ -3147,7 +3212,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
3147 | 3212 | ||
3148 | /* maybe switch power back on (e.g. root hub was reset) */ | 3213 | /* maybe switch power back on (e.g. root hub was reset) */ |
3149 | if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2 | 3214 | if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2 |
3150 | && !(portstatus & USB_PORT_STAT_POWER)) | 3215 | && !port_is_power_on(hub, portstatus)) |
3151 | set_port_feature(hdev, port1, USB_PORT_FEAT_POWER); | 3216 | set_port_feature(hdev, port1, USB_PORT_FEAT_POWER); |
3152 | 3217 | ||
3153 | if (portstatus & USB_PORT_STAT_ENABLE) | 3218 | if (portstatus & USB_PORT_STAT_ENABLE) |
@@ -3490,6 +3555,16 @@ static void hub_events(void) | |||
3490 | USB_PORT_FEAT_C_PORT_CONFIG_ERROR); | 3555 | USB_PORT_FEAT_C_PORT_CONFIG_ERROR); |
3491 | } | 3556 | } |
3492 | 3557 | ||
3558 | /* Warm reset a USB3 protocol port if it's in | ||
3559 | * SS.Inactive state. | ||
3560 | */ | ||
3561 | if (hub_is_superspeed(hub->hdev) && | ||
3562 | (portstatus & USB_PORT_STAT_LINK_STATE) | ||
3563 | == USB_SS_PORT_LS_SS_INACTIVE) { | ||
3564 | dev_dbg(hub_dev, "warm reset port %d\n", i); | ||
3565 | hub_port_warm_reset(hub, i); | ||
3566 | } | ||
3567 | |||
3493 | if (connect_change) | 3568 | if (connect_change) |
3494 | hub_port_connect_change(hub, i, | 3569 | hub_port_connect_change(hub, i, |
3495 | portstatus, portchange); | 3570 | portstatus, portchange); |
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 6781c369ce2..cf05b97693e 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c | |||
@@ -842,22 +842,19 @@ const struct attribute_group *usb_interface_groups[] = { | |||
842 | NULL | 842 | NULL |
843 | }; | 843 | }; |
844 | 844 | ||
845 | int usb_create_sysfs_intf_files(struct usb_interface *intf) | 845 | void usb_create_sysfs_intf_files(struct usb_interface *intf) |
846 | { | 846 | { |
847 | struct usb_device *udev = interface_to_usbdev(intf); | 847 | struct usb_device *udev = interface_to_usbdev(intf); |
848 | struct usb_host_interface *alt = intf->cur_altsetting; | 848 | struct usb_host_interface *alt = intf->cur_altsetting; |
849 | int retval; | ||
850 | 849 | ||
851 | if (intf->sysfs_files_created || intf->unregistering) | 850 | if (intf->sysfs_files_created || intf->unregistering) |
852 | return 0; | 851 | return; |
853 | 852 | ||
854 | if (alt->string == NULL && | 853 | if (!alt->string && !(udev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS)) |
855 | !(udev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS)) | ||
856 | alt->string = usb_cache_string(udev, alt->desc.iInterface); | 854 | alt->string = usb_cache_string(udev, alt->desc.iInterface); |
857 | if (alt->string) | 855 | if (alt->string && device_create_file(&intf->dev, &dev_attr_interface)) |
858 | retval = device_create_file(&intf->dev, &dev_attr_interface); | 856 | ; /* We don't actually care if the function fails. */ |
859 | intf->sysfs_files_created = 1; | 857 | intf->sysfs_files_created = 1; |
860 | return 0; | ||
861 | } | 858 | } |
862 | 859 | ||
863 | void usb_remove_sysfs_intf_files(struct usb_interface *intf) | 860 | void usb_remove_sysfs_intf_files(struct usb_interface *intf) |
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index d9d4b169404..8706fc97e60 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -953,8 +953,7 @@ static int usb_bus_notify(struct notifier_block *nb, unsigned long action, | |||
953 | if (dev->type == &usb_device_type) | 953 | if (dev->type == &usb_device_type) |
954 | (void) usb_create_sysfs_dev_files(to_usb_device(dev)); | 954 | (void) usb_create_sysfs_dev_files(to_usb_device(dev)); |
955 | else if (dev->type == &usb_if_device_type) | 955 | else if (dev->type == &usb_if_device_type) |
956 | (void) usb_create_sysfs_intf_files( | 956 | usb_create_sysfs_intf_files(to_usb_interface(dev)); |
957 | to_usb_interface(dev)); | ||
958 | break; | 957 | break; |
959 | 958 | ||
960 | case BUS_NOTIFY_DEL_DEVICE: | 959 | case BUS_NOTIFY_DEL_DEVICE: |
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index d450b742137..d44d4b7bbf1 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | extern int usb_create_sysfs_dev_files(struct usb_device *dev); | 5 | extern int usb_create_sysfs_dev_files(struct usb_device *dev); |
6 | extern void usb_remove_sysfs_dev_files(struct usb_device *dev); | 6 | extern void usb_remove_sysfs_dev_files(struct usb_device *dev); |
7 | extern int usb_create_sysfs_intf_files(struct usb_interface *intf); | 7 | extern void usb_create_sysfs_intf_files(struct usb_interface *intf); |
8 | extern void usb_remove_sysfs_intf_files(struct usb_interface *intf); | 8 | extern void usb_remove_sysfs_intf_files(struct usb_interface *intf); |
9 | extern int usb_create_ep_devs(struct device *parent, | 9 | extern int usb_create_ep_devs(struct device *parent, |
10 | struct usb_host_endpoint *endpoint, | 10 | struct usb_host_endpoint *endpoint, |