usb: Create link files between child device and usb port device.
authorLan Tianyu <tianyu.lan@intel.com>
Sat, 19 Jan 2013 17:53:33 +0000 (01:53 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 21 Jan 2013 00:10:46 +0000 (16:10 -0800)
To show the relationship between usb port and child device,
add link file "port" under usb device's sysfs directoy and
"device" under usb port device's sysfs directory. They are linked
to each other.

Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Lan Tianyu <tianyu.lan@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/core/hub.c

index f6ff1302f343b6425931d3ea74547091fa47f2da..cfdd4eecc5a91827eef449c9ff62d3e4006e5d41 100644 (file)
@@ -1989,6 +1989,14 @@ void usb_disconnect(struct usb_device **pdev)
        usb_disable_device(udev, 0);
        usb_hcd_synchronize_unlinks(udev);
 
+       if (udev->parent) {
+               struct usb_port *port_dev =
+                       hdev_to_hub(udev->parent)->ports[udev->portnum - 1];
+
+               sysfs_remove_link(&udev->dev.kobj, "port");
+               sysfs_remove_link(&port_dev->dev.kobj, "device");
+       }
+
        usb_remove_ep_devs(&udev->ep0);
        usb_unlock_device(udev);
 
@@ -2281,6 +2289,24 @@ int usb_new_device(struct usb_device *udev)
                goto fail;
        }
 
+       /* Create link files between child device and usb port device. */
+       if (udev->parent) {
+               struct usb_port *port_dev =
+                       hdev_to_hub(udev->parent)->ports[udev->portnum - 1];
+
+               err = sysfs_create_link(&udev->dev.kobj,
+                               &port_dev->dev.kobj, "port");
+               if (err)
+                       goto fail;
+
+               err = sysfs_create_link(&port_dev->dev.kobj,
+                               &udev->dev.kobj, "device");
+               if (err) {
+                       sysfs_remove_link(&udev->dev.kobj, "port");
+                       goto fail;
+               }
+       }
+
        (void) usb_create_ep_devs(&udev->dev, &udev->ep0, udev);
        usb_mark_last_busy(udev);
        pm_runtime_put_sync_autosuspend(&udev->dev);