aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/hub.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/core/hub.c')
-rw-r--r--drivers/usb/core/hub.c70
1 files changed, 29 insertions, 41 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 590ec82d0515..bde29ab2b504 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -44,6 +44,7 @@ struct usb_hub {
44 struct usb_hub_status hub; 44 struct usb_hub_status hub;
45 struct usb_port_status port; 45 struct usb_port_status port;
46 } *status; /* buffer for status reports */ 46 } *status; /* buffer for status reports */
47 struct mutex status_mutex; /* for the status buffer */
47 48
48 int error; /* last reported error */ 49 int error; /* last reported error */
49 int nerrors; /* track consecutive errors */ 50 int nerrors; /* track consecutive errors */
@@ -118,8 +119,7 @@ MODULE_PARM_DESC(use_both_schemes,
118 "first one fails"); 119 "first one fails");
119 120
120 121
121#ifdef DEBUG 122static inline char *portspeed(int portstatus)
122static inline char *portspeed (int portstatus)
123{ 123{
124 if (portstatus & (1 << USB_PORT_FEAT_HIGHSPEED)) 124 if (portstatus & (1 << USB_PORT_FEAT_HIGHSPEED))
125 return "480 Mb/s"; 125 return "480 Mb/s";
@@ -128,7 +128,6 @@ static inline char *portspeed (int portstatus)
128 else 128 else
129 return "12 Mb/s"; 129 return "12 Mb/s";
130} 130}
131#endif
132 131
133/* Note that hdev or one of its children must be locked! */ 132/* Note that hdev or one of its children must be locked! */
134static inline struct usb_hub *hdev_to_hub(struct usb_device *hdev) 133static inline struct usb_hub *hdev_to_hub(struct usb_device *hdev)
@@ -535,6 +534,7 @@ static int hub_hub_status(struct usb_hub *hub,
535{ 534{
536 int ret; 535 int ret;
537 536
537 mutex_lock(&hub->status_mutex);
538 ret = get_hub_status(hub->hdev, &hub->status->hub); 538 ret = get_hub_status(hub->hdev, &hub->status->hub);
539 if (ret < 0) 539 if (ret < 0)
540 dev_err (hub->intfdev, 540 dev_err (hub->intfdev,
@@ -544,6 +544,7 @@ static int hub_hub_status(struct usb_hub *hub,
544 *change = le16_to_cpu(hub->status->hub.wHubChange); 544 *change = le16_to_cpu(hub->status->hub.wHubChange);
545 ret = 0; 545 ret = 0;
546 } 546 }
547 mutex_unlock(&hub->status_mutex);
547 return ret; 548 return ret;
548} 549}
549 550
@@ -617,6 +618,7 @@ static int hub_configure(struct usb_hub *hub,
617 ret = -ENOMEM; 618 ret = -ENOMEM;
618 goto fail; 619 goto fail;
619 } 620 }
621 mutex_init(&hub->status_mutex);
620 622
621 hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL); 623 hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL);
622 if (!hub->descriptor) { 624 if (!hub->descriptor) {
@@ -1277,11 +1279,8 @@ int usb_new_device(struct usb_device *udev)
1277{ 1279{
1278 int err; 1280 int err;
1279 1281
1280 /* Lock ourself into memory in order to keep a probe sequence 1282 /* Determine quirks */
1281 * sleeping in a new thread from allowing us to be unloaded. 1283 usb_detect_quirks(udev);
1282 */
1283 if (!try_module_get(THIS_MODULE))
1284 return -EINVAL;
1285 1284
1286 err = usb_get_configuration(udev); 1285 err = usb_get_configuration(udev);
1287 if (err < 0) { 1286 if (err < 0) {
@@ -1368,11 +1367,15 @@ int usb_new_device(struct usb_device *udev)
1368 } 1367 }
1369#endif 1368#endif
1370 1369
1370 /* export the usbdev device-node for libusb */
1371 udev->dev.devt = MKDEV(USB_DEVICE_MAJOR,
1372 (((udev->bus->busnum-1) * 128) + (udev->devnum-1)));
1373
1371 /* Register the device. The device driver is responsible 1374 /* Register the device. The device driver is responsible
1372 * for adding the device files to usbfs and sysfs and for 1375 * for adding the device files to sysfs and for configuring
1373 * configuring the device. 1376 * the device.
1374 */ 1377 */
1375 err = device_add (&udev->dev); 1378 err = device_add(&udev->dev);
1376 if (err) { 1379 if (err) {
1377 dev_err(&udev->dev, "can't device_add, error %d\n", err); 1380 dev_err(&udev->dev, "can't device_add, error %d\n", err);
1378 goto fail; 1381 goto fail;
@@ -1383,7 +1386,6 @@ int usb_new_device(struct usb_device *udev)
1383 usb_autoresume_device(udev->parent); 1386 usb_autoresume_device(udev->parent);
1384 1387
1385exit: 1388exit:
1386 module_put(THIS_MODULE);
1387 return err; 1389 return err;
1388 1390
1389fail: 1391fail:
@@ -1396,6 +1398,7 @@ static int hub_port_status(struct usb_hub *hub, int port1,
1396{ 1398{
1397 int ret; 1399 int ret;
1398 1400
1401 mutex_lock(&hub->status_mutex);
1399 ret = get_port_status(hub->hdev, port1, &hub->status->port); 1402 ret = get_port_status(hub->hdev, port1, &hub->status->port);
1400 if (ret < 4) { 1403 if (ret < 4) {
1401 dev_err (hub->intfdev, 1404 dev_err (hub->intfdev,
@@ -1407,6 +1410,7 @@ static int hub_port_status(struct usb_hub *hub, int port1,
1407 *change = le16_to_cpu(hub->status->port.wPortChange); 1410 *change = le16_to_cpu(hub->status->port.wPortChange);
1408 ret = 0; 1411 ret = 0;
1409 } 1412 }
1413 mutex_unlock(&hub->status_mutex);
1410 return ret; 1414 return ret;
1411} 1415}
1412 1416
@@ -1855,12 +1859,8 @@ static int remote_wakeup(struct usb_device *udev)
1855 usb_lock_device(udev); 1859 usb_lock_device(udev);
1856 if (udev->state == USB_STATE_SUSPENDED) { 1860 if (udev->state == USB_STATE_SUSPENDED) {
1857 dev_dbg(&udev->dev, "usb %sresume\n", "wakeup-"); 1861 dev_dbg(&udev->dev, "usb %sresume\n", "wakeup-");
1858 status = usb_autoresume_device(udev); 1862 usb_mark_last_busy(udev);
1859 1863 status = usb_external_resume_device(udev);
1860 /* Give the interface drivers a chance to do something,
1861 * then autosuspend the device again. */
1862 if (status == 0)
1863 usb_autosuspend_device(udev);
1864 } 1864 }
1865 usb_unlock_device(udev); 1865 usb_unlock_device(udev);
1866 return status; 1866 return status;
@@ -1904,6 +1904,7 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
1904 struct usb_hub *hub = usb_get_intfdata (intf); 1904 struct usb_hub *hub = usb_get_intfdata (intf);
1905 struct usb_device *hdev = hub->hdev; 1905 struct usb_device *hdev = hub->hdev;
1906 unsigned port1; 1906 unsigned port1;
1907 int status = 0;
1907 1908
1908 /* fail if children aren't already suspended */ 1909 /* fail if children aren't already suspended */
1909 for (port1 = 1; port1 <= hdev->maxchild; port1++) { 1910 for (port1 = 1; port1 <= hdev->maxchild; port1++) {
@@ -1927,24 +1928,18 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
1927 1928
1928 dev_dbg(&intf->dev, "%s\n", __FUNCTION__); 1929 dev_dbg(&intf->dev, "%s\n", __FUNCTION__);
1929 1930
1931 /* stop khubd and related activity */
1932 hub_quiesce(hub);
1933
1930 /* "global suspend" of the downstream HC-to-USB interface */ 1934 /* "global suspend" of the downstream HC-to-USB interface */
1931 if (!hdev->parent) { 1935 if (!hdev->parent) {
1932 struct usb_bus *bus = hdev->bus; 1936 status = hcd_bus_suspend(hdev->bus);
1933 if (bus) { 1937 if (status != 0) {
1934 int status = hcd_bus_suspend (bus); 1938 dev_dbg(&hdev->dev, "'global' suspend %d\n", status);
1935 1939 hub_activate(hub);
1936 if (status != 0) { 1940 }
1937 dev_dbg(&hdev->dev, "'global' suspend %d\n",
1938 status);
1939 return status;
1940 }
1941 } else
1942 return -EOPNOTSUPP;
1943 } 1941 }
1944 1942 return status;
1945 /* stop khubd and related activity */
1946 hub_quiesce(hub);
1947 return 0;
1948} 1943}
1949 1944
1950static int hub_resume(struct usb_interface *intf) 1945static int hub_resume(struct usb_interface *intf)
@@ -1989,13 +1984,6 @@ static inline int remote_wakeup(struct usb_device *udev)
1989#define hub_resume NULL 1984#define hub_resume NULL
1990#endif 1985#endif
1991 1986
1992void usb_resume_root_hub(struct usb_device *hdev)
1993{
1994 struct usb_hub *hub = hdev_to_hub(hdev);
1995
1996 kick_khubd(hub);
1997}
1998
1999 1987
2000/* USB 2.0 spec, 7.1.7.3 / fig 7-29: 1988/* USB 2.0 spec, 7.1.7.3 / fig 7-29:
2001 * 1989 *
@@ -2439,7 +2427,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
2439 2427
2440 if (portchange & USB_PORT_STAT_C_CONNECTION) { 2428 if (portchange & USB_PORT_STAT_C_CONNECTION) {
2441 status = hub_port_debounce(hub, port1); 2429 status = hub_port_debounce(hub, port1);
2442 if (status < 0) { 2430 if (status < 0 && printk_ratelimit()) {
2443 dev_err (hub_dev, 2431 dev_err (hub_dev,
2444 "connect-debounce failed, port %d disabled\n", 2432 "connect-debounce failed, port %d disabled\n",
2445 port1); 2433 port1);