aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2006-08-11 04:55:12 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-12-01 17:25:52 -0500
commitc066475e1fe3b3afbd613ddf5f1eca9be4fb6de0 (patch)
tree43d9d68fd1d57a3ae376d0d3fe22df32482715d3 /drivers/usb/core
parent958e8741bf9ff5d0f0b82b7cef578e96c764a288 (diff)
USB: create a new thread for every USB device found during the probe sequence
Might speed up some systems. If nothing else, a bad driver should not take the whole USB subsystem down with it. Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/core')
-rw-r--r--drivers/usb/core/Kconfig15
-rw-r--r--drivers/usb/core/hub.c81
2 files changed, 74 insertions, 22 deletions
diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig
index 6e3b5358a760..f8324d8d06ac 100644
--- a/drivers/usb/core/Kconfig
+++ b/drivers/usb/core/Kconfig
@@ -72,6 +72,21 @@ config USB_SUSPEND
72 72
73 If you are unsure about this, say N here. 73 If you are unsure about this, say N here.
74 74
75config USB_MULTITHREAD_PROBE
76 bool "USB Multi-threaded probe (EXPERIMENTAL)"
77 depends on USB && EXPERIMENTAL
78 default n
79 help
80 Say Y here if you want the USB core to spawn a new thread for
81 every USB device that is probed. This can cause a small speedup
82 in boot times on systems with a lot of different USB devices.
83
84 This option should be safe to enable, but if any odd probing
85 problems are found, please disable it, or dynamically turn it
86 off in the /sys/module/usbcore/parameters/multithread_probe
87 file
88
89 When in doubt, say N.
75 90
76config USB_OTG 91config USB_OTG
77 bool 92 bool
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index c961a32f3176..f6e692180587 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -87,6 +87,16 @@ static DECLARE_WAIT_QUEUE_HEAD(khubd_wait);
87 87
88static struct task_struct *khubd_task; 88static struct task_struct *khubd_task;
89 89
90/* multithreaded probe logic */
91static int multithread_probe =
92#ifdef CONFIG_USB_MULTITHREAD_PROBE
93 1;
94#else
95 0;
96#endif
97module_param(multithread_probe, bool, S_IRUGO);
98MODULE_PARM_DESC(multithread_probe, "Run each USB device probe in a new thread");
99
90/* cycle leds on hubs that aren't blinking for attention */ 100/* cycle leds on hubs that aren't blinking for attention */
91static int blinkenlights = 0; 101static int blinkenlights = 0;
92module_param (blinkenlights, bool, S_IRUGO); 102module_param (blinkenlights, bool, S_IRUGO);
@@ -1238,29 +1248,17 @@ static inline void show_string(struct usb_device *udev, char *id, char *string)
1238static int __usb_port_suspend(struct usb_device *, int port1); 1248static int __usb_port_suspend(struct usb_device *, int port1);
1239#endif 1249#endif
1240 1250
1241/** 1251static int __usb_new_device(void *void_data)
1242 * usb_new_device - perform initial device setup (usbcore-internal)
1243 * @udev: newly addressed device (in ADDRESS state)
1244 *
1245 * This is called with devices which have been enumerated, but not yet
1246 * configured. The device descriptor is available, but not descriptors
1247 * for any device configuration. The caller must have locked either
1248 * the parent hub (if udev is a normal device) or else the
1249 * usb_bus_list_lock (if udev is a root hub). The parent's pointer to
1250 * udev has already been installed, but udev is not yet visible through
1251 * sysfs or other filesystem code.
1252 *
1253 * Returns 0 for success (device is configured and listed, with its
1254 * interfaces, in sysfs); else a negative errno value.
1255 *
1256 * This call is synchronous, and may not be used in an interrupt context.
1257 *
1258 * Only the hub driver or root-hub registrar should ever call this.
1259 */
1260int usb_new_device(struct usb_device *udev)
1261{ 1252{
1253 struct usb_device *udev = void_data;
1262 int err; 1254 int err;
1263 1255
1256 /* Lock ourself into memory in order to keep a probe sequence
1257 * sleeping in a new thread from allowing us to be unloaded.
1258 */
1259 if (!try_module_get(THIS_MODULE))
1260 return -EINVAL;
1261
1264 err = usb_get_configuration(udev); 1262 err = usb_get_configuration(udev);
1265 if (err < 0) { 1263 if (err < 0) {
1266 dev_err(&udev->dev, "can't read configurations, error %d\n", 1264 dev_err(&udev->dev, "can't read configurations, error %d\n",
@@ -1356,13 +1354,52 @@ int usb_new_device(struct usb_device *udev)
1356 goto fail; 1354 goto fail;
1357 } 1355 }
1358 1356
1359 return 0; 1357exit:
1358 module_put(THIS_MODULE);
1359 return err;
1360 1360
1361fail: 1361fail:
1362 usb_set_device_state(udev, USB_STATE_NOTATTACHED); 1362 usb_set_device_state(udev, USB_STATE_NOTATTACHED);
1363 return err; 1363 goto exit;
1364} 1364}
1365 1365
1366/**
1367 * usb_new_device - perform initial device setup (usbcore-internal)
1368 * @udev: newly addressed device (in ADDRESS state)
1369 *
1370 * This is called with devices which have been enumerated, but not yet
1371 * configured. The device descriptor is available, but not descriptors
1372 * for any device configuration. The caller must have locked either
1373 * the parent hub (if udev is a normal device) or else the
1374 * usb_bus_list_lock (if udev is a root hub). The parent's pointer to
1375 * udev has already been installed, but udev is not yet visible through
1376 * sysfs or other filesystem code.
1377 *
1378 * The return value for this function depends on if the
1379 * multithread_probe variable is set or not. If it's set, it will
1380 * return a if the probe thread was successfully created or not. If the
1381 * variable is not set, it will return if the device is configured
1382 * properly or not. interfaces, in sysfs); else a negative errno value.
1383 *
1384 * This call is synchronous, and may not be used in an interrupt context.
1385 *
1386 * Only the hub driver or root-hub registrar should ever call this.
1387 */
1388int usb_new_device(struct usb_device *udev)
1389{
1390 struct task_struct *probe_task;
1391 int ret = 0;
1392
1393 if (multithread_probe) {
1394 probe_task = kthread_run(__usb_new_device, udev,
1395 "usb-probe-%s", udev->devnum);
1396 if (IS_ERR(probe_task))
1397 ret = PTR_ERR(probe_task);
1398 } else
1399 ret = __usb_new_device(udev);
1400
1401 return ret;
1402}
1366 1403
1367static int hub_port_status(struct usb_hub *hub, int port1, 1404static int hub_port_status(struct usb_hub *hub, int port1,
1368 u16 *status, u16 *change) 1405 u16 *status, u16 *change)