aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-05-23 15:33:02 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-23 15:33:02 -0400
commitc44dead70a841d90ddc01968012f323c33217c9e (patch)
tree85489ebe9b9a3413cd8ee197ffb40c8aa8d97e63 /drivers/usb/core
parent99dff5856220a02b8711f2e8746413ea6e53ccf6 (diff)
parentd5f6db9e1aff6ccf1876224f152c0268b0c8a992 (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.c2
-rw-r--r--drivers/usb/core/devices.c22
-rw-r--r--drivers/usb/core/file.c8
-rw-r--r--drivers/usb/core/hcd.c6
-rw-r--r--drivers/usb/core/hub.c131
-rw-r--r--drivers/usb/core/sysfs.c13
-rw-r--r--drivers/usb/core/usb.c3
-rw-r--r--drivers/usb/core/usb.h2
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
67static const char *format_topo = 67static 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
71static const char *format_string_manufacturer = 71static 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
75static const char *format_string_product = 75static 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
80static const char *format_string_serialnumber = 80static 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
85static const char *format_bandwidth = 85static 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
89static const char *format_device1 = 89static 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
93static const char *format_device2 = 93static 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
97static const char *format_config = 97static 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
101static const char *format_iad = 101static 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
105static const char *format_iface = 105static 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
109static const char *format_endpt = 109static 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);
236void usb_deregister_dev(struct usb_interface *intf, 236void 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 */
2155static 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 */
2191static 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) 2209static 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
845int usb_create_sysfs_intf_files(struct usb_interface *intf) 845void 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
863void usb_remove_sysfs_intf_files(struct usb_interface *intf) 860void 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
5extern int usb_create_sysfs_dev_files(struct usb_device *dev); 5extern int usb_create_sysfs_dev_files(struct usb_device *dev);
6extern void usb_remove_sysfs_dev_files(struct usb_device *dev); 6extern void usb_remove_sysfs_dev_files(struct usb_device *dev);
7extern int usb_create_sysfs_intf_files(struct usb_interface *intf); 7extern void usb_create_sysfs_intf_files(struct usb_interface *intf);
8extern void usb_remove_sysfs_intf_files(struct usb_interface *intf); 8extern void usb_remove_sysfs_intf_files(struct usb_interface *intf);
9extern int usb_create_ep_devs(struct device *parent, 9extern int usb_create_ep_devs(struct device *parent,
10 struct usb_host_endpoint *endpoint, 10 struct usb_host_endpoint *endpoint,