USB: hub_for_each_child should skip unconnected ports
authorAlan Stern <stern@rowland.harvard.edu>
Fri, 19 Oct 2012 15:03:02 +0000 (11:03 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 24 Oct 2012 21:51:21 +0000 (14:51 -0700)
This patch (as1619) improves the interface to the "hub_for_each_child"
macro.  The name clearly suggests that the macro iterates over child
devices; it does not suggest that the loop will also iterate over
unnconnected ports.

The patch changes the macro so that it will skip over unconnected
ports and iterate only the actual child devices.  The two existing
call sites are updated to avoid testing for a NULL child pointer,
which is now unnecessary.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/core/devices.c
drivers/usb/host/r8a66597-hcd.c
include/linux/usb.h

index f460de31aceee80200ff9e91f514917bae9f7adc..cbacea933b18cbc9c6287acec62f465495569b1e 100644 (file)
@@ -591,16 +591,14 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes,
 
        /* Now look at all of this device's children. */
        usb_hub_for_each_child(usbdev, chix, childdev) {
-               if (childdev) {
-                       usb_lock_device(childdev);
-                       ret = usb_device_dump(buffer, nbytes, skip_bytes,
-                                             file_offset, childdev, bus,
-                                             level + 1, chix - 1, ++cnt);
-                       usb_unlock_device(childdev);
-                       if (ret == -EFAULT)
-                               return total_written;
-                       total_written += ret;
-               }
+               usb_lock_device(childdev);
+               ret = usb_device_dump(buffer, nbytes, skip_bytes,
+                                     file_offset, childdev, bus,
+                                     level + 1, chix - 1, ++cnt);
+               usb_unlock_device(childdev);
+               if (ret == -EFAULT)
+                       return total_written;
+               total_written += ret;
        }
        return total_written;
 }
index fcc09e5ec0addc9cd9661086b1e18165bd5f8ba4..b3eea0ba97a936b9743245971d0a94a1e6b2e45e 100644 (file)
@@ -2036,10 +2036,8 @@ static void collect_usb_address_map(struct usb_device *udev, unsigned long *map)
            udev->parent->descriptor.bDeviceClass == USB_CLASS_HUB)
                map[udev->devnum/32] |= (1 << (udev->devnum % 32));
 
-       usb_hub_for_each_child(udev, chix, childdev) {
-               if (childdev)
-                       collect_usb_address_map(childdev, map);
-       }
+       usb_hub_for_each_child(udev, chix, childdev)
+               collect_usb_address_map(childdev, map);
 }
 
 /* this function must be called with interrupt disabled */
index f92cdf0c1457e4b56096343f0a7827e86daec15d..5df7c87b277f09b2e4e44e80985ab1e5587cea0a 100644 (file)
@@ -588,8 +588,9 @@ extern struct usb_device *usb_hub_find_child(struct usb_device *hdev,
  */
 #define usb_hub_for_each_child(hdev, port1, child) \
        for (port1 = 1, child = usb_hub_find_child(hdev, port1); \
-               port1 <= hdev->maxchild; \
-               child = usb_hub_find_child(hdev, ++port1))
+                       port1 <= hdev->maxchild; \
+                       child = usb_hub_find_child(hdev, ++port1)) \
+               if (!child) continue; else
 
 /* USB device locking */
 #define usb_lock_device(udev)          device_lock(&(udev)->dev)