aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/hub.c
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/hub.c
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/hub.c')
-rw-r--r--drivers/usb/core/hub.c81
1 files changed, 59 insertions, 22 deletions
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)