Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

usb: move children to struct usb_port

The usb_device structure contains an array of usb_device "children".
This array is only valid if the usb_device is a hub, so it makes no
sense to store it there. Instead, store the usb_device child
in its parent usb_port structure.

Since usb_port is an internal USB core structure, add a new function to
get the USB device child, usb_hub_find_child(). Add a new macro,
usb_hub_get_each_child(), to iterate over all the children attached to a
particular USB hub.

Remove the printing the USB children array pointer from the usb-ip
driver, since it's really not necessary.

Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Lan Tianyu <tianyu.lan@intel.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Lan Tianyu and committed by
Greg Kroah-Hartman
ff823c79 fa2a9566

+68 -35
+1 -2
drivers/staging/usbip/usbip_common.c
··· 157 157 dev_dbg(dev, "have_langid %d, string_langid %d\n", 158 158 udev->have_langid, udev->string_langid); 159 159 160 - dev_dbg(dev, "maxchild %d, children %p\n", 161 - udev->maxchild, udev->children); 160 + dev_dbg(dev, "maxchild %d\n", udev->maxchild); 162 161 } 163 162 164 163 static void usbip_dump_request_type(__u8 rt)
+3 -4
drivers/usb/core/devices.c
··· 496 496 char *pages_start, *data_end, *speed; 497 497 unsigned int length; 498 498 ssize_t total_written = 0; 499 + struct usb_device *childdev = NULL; 499 500 500 501 /* don't bother with anything else if we're not writing any data */ 501 502 if (*nbytes <= 0) ··· 590 589 free_pages((unsigned long)pages_start, 1); 591 590 592 591 /* Now look at all of this device's children. */ 593 - for (chix = 0; chix < usbdev->maxchild; chix++) { 594 - struct usb_device *childdev = usbdev->children[chix]; 595 - 592 + usb_hub_for_each_child(usbdev, chix, childdev) { 596 593 if (childdev) { 597 594 usb_lock_device(childdev); 598 595 ret = usb_device_dump(buffer, nbytes, skip_bytes, 599 596 file_offset, childdev, bus, 600 - level + 1, chix, ++cnt); 597 + level + 1, chix - 1, ++cnt); 601 598 usb_unlock_device(childdev); 602 599 if (ret == -EFAULT) 603 600 return total_written;
+49 -24
drivers/usb/core/hub.c
··· 40 40 #endif 41 41 42 42 struct usb_port { 43 + struct usb_device *child; 43 44 struct device dev; 44 45 struct dev_state *port_owner; 45 46 }; ··· 182 181 /* Note that hdev or one of its children must be locked! */ 183 182 static struct usb_hub *hdev_to_hub(struct usb_device *hdev) 184 183 { 185 - if (!hdev || !hdev->actconfig) 184 + if (!hdev || !hdev->actconfig || !hdev->maxchild) 186 185 return NULL; 187 186 return usb_get_intfdata(hdev->actconfig->interface[0]); 188 187 } ··· 877 876 struct usb_device *hdev = hub->hdev; 878 877 int ret = 0; 879 878 880 - if (hdev->children[port1-1] && set_state) 881 - usb_set_device_state(hdev->children[port1-1], 879 + if (hub->ports[port1 - 1]->child && set_state) 880 + usb_set_device_state(hub->ports[port1 - 1]->child, 882 881 USB_STATE_NOTATTACHED); 883 882 if (!hub->error && !hub_is_superspeed(hub->hdev)) 884 883 ret = clear_port_feature(hdev, port1, USB_PORT_FEAT_ENABLE); ··· 1034 1033 * which ports need attention. 1035 1034 */ 1036 1035 for (port1 = 1; port1 <= hdev->maxchild; ++port1) { 1037 - struct usb_device *udev = hdev->children[port1-1]; 1036 + struct usb_device *udev = hub->ports[port1 - 1]->child; 1038 1037 u16 portstatus, portchange; 1039 1038 1040 1039 portstatus = portchange = 0; ··· 1199 1198 if (type != HUB_SUSPEND) { 1200 1199 /* Disconnect all the children */ 1201 1200 for (i = 0; i < hdev->maxchild; ++i) { 1202 - if (hdev->children[i]) 1203 - usb_disconnect(&hdev->children[i]); 1201 + if (hub->ports[i]->child) 1202 + usb_disconnect(&hub->ports[i]->child); 1204 1203 } 1205 1204 } 1206 1205 ··· 1325 1324 dev_info (hub_dev, "%d port%s detected\n", hdev->maxchild, 1326 1325 (hdev->maxchild == 1) ? "" : "s"); 1327 1326 1328 - hdev->children = kzalloc(hdev->maxchild * 1329 - sizeof(struct usb_device *), GFP_KERNEL); 1330 1327 hub->ports = kzalloc(hdev->maxchild * sizeof(struct usb_port *), 1331 1328 GFP_KERNEL); 1332 - if (!hdev->children || !hub->ports) { 1329 + if (!hub->ports) { 1333 1330 ret = -ENOMEM; 1334 1331 goto fail; 1335 1332 } ··· 1590 1591 highspeed_hubs--; 1591 1592 1592 1593 usb_free_urb(hub->urb); 1593 - kfree(hdev->children); 1594 1594 kfree(hub->ports); 1595 1595 kfree(hub->descriptor); 1596 1596 kfree(hub->status); ··· 1677 1679 hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data) 1678 1680 { 1679 1681 struct usb_device *hdev = interface_to_usbdev (intf); 1682 + struct usb_hub *hub = hdev_to_hub(hdev); 1680 1683 1681 1684 /* assert ifno == 0 (part of hub spec) */ 1682 1685 switch (code) { ··· 1691 1692 else { 1692 1693 info->nports = hdev->maxchild; 1693 1694 for (i = 0; i < info->nports; i++) { 1694 - if (hdev->children[i] == NULL) 1695 + if (hub->ports[i]->child == NULL) 1695 1696 info->port[i] = 0; 1696 1697 else 1697 1698 info->port[i] = 1698 - hdev->children[i]->devnum; 1699 + hub->ports[i]->child->devnum; 1699 1700 } 1700 1701 } 1701 1702 spin_unlock_irq(&device_state_lock); ··· 1783 1784 1784 1785 static void recursively_mark_NOTATTACHED(struct usb_device *udev) 1785 1786 { 1787 + struct usb_hub *hub = hdev_to_hub(udev); 1786 1788 int i; 1787 1789 1788 1790 for (i = 0; i < udev->maxchild; ++i) { 1789 - if (udev->children[i]) 1790 - recursively_mark_NOTATTACHED(udev->children[i]); 1791 + if (hub->ports[i]->child) 1792 + recursively_mark_NOTATTACHED(hub->ports[i]->child); 1791 1793 } 1792 1794 if (udev->state == USB_STATE_SUSPENDED) 1793 1795 udev->active_duration -= jiffies; ··· 1952 1952 void usb_disconnect(struct usb_device **pdev) 1953 1953 { 1954 1954 struct usb_device *udev = *pdev; 1955 + struct usb_hub *hub = hdev_to_hub(udev); 1955 1956 int i; 1956 1957 1957 1958 /* mark the device as inactive, so any further urb submissions for ··· 1967 1966 1968 1967 /* Free up all the children before we remove this device */ 1969 1968 for (i = 0; i < udev->maxchild; i++) { 1970 - if (udev->children[i]) 1971 - usb_disconnect(&udev->children[i]); 1969 + if (hub->ports[i]->child) 1970 + usb_disconnect(&hub->ports[i]->child); 1972 1971 } 1973 1972 1974 1973 /* deallocate hcd/hardware state ... nuking all pending urbs and ··· 3132 3131 for (port1 = 1; port1 <= hdev->maxchild; port1++) { 3133 3132 struct usb_device *udev; 3134 3133 3135 - udev = hdev->children [port1-1]; 3134 + udev = hub->ports[port1 - 1]->child; 3136 3135 if (udev && udev->can_submit) { 3137 3136 dev_warn(&intf->dev, "port %d nyet suspended\n", port1); 3138 3137 if (PMSG_IS_AUTO(msg)) ··· 4059 4058 4060 4059 remaining = hdev->bus_mA - hub->descriptor->bHubContrCurrent; 4061 4060 for (port1 = 1; port1 <= hdev->maxchild; ++port1) { 4062 - struct usb_device *udev = hdev->children[port1 - 1]; 4061 + struct usb_device *udev = hub->ports[port1 - 1]->child; 4063 4062 int delta; 4064 4063 4065 4064 if (!udev) ··· 4123 4122 #endif 4124 4123 4125 4124 /* Try to resuscitate an existing device */ 4126 - udev = hdev->children[port1-1]; 4125 + udev = hub->ports[port1 - 1]->child; 4127 4126 if ((portstatus & USB_PORT_STAT_CONNECTION) && udev && 4128 4127 udev->state != USB_STATE_NOTATTACHED) { 4129 4128 usb_lock_device(udev); ··· 4152 4151 4153 4152 /* Disconnect any existing devices under this port */ 4154 4153 if (udev) 4155 - usb_disconnect(&hdev->children[port1-1]); 4154 + usb_disconnect(&hub->ports[port1 - 1]->child); 4156 4155 clear_bit(port1, hub->change_bits); 4157 4156 4158 4157 /* We can forget about a "removed" device when there's a physical ··· 4288 4287 if (hdev->state == USB_STATE_NOTATTACHED) 4289 4288 status = -ENOTCONN; 4290 4289 else 4291 - hdev->children[port1-1] = udev; 4290 + hub->ports[port1 - 1]->child = udev; 4292 4291 spin_unlock_irq(&device_state_lock); 4293 4292 4294 4293 /* Run it through the hoops (find a driver, etc) */ ··· 4296 4295 status = usb_new_device(udev); 4297 4296 if (status) { 4298 4297 spin_lock_irq(&device_state_lock); 4299 - hdev->children[port1-1] = NULL; 4298 + hub->ports[port1 - 1]->child = NULL; 4300 4299 spin_unlock_irq(&device_state_lock); 4301 4300 } 4302 4301 } ··· 4342 4341 int ret; 4343 4342 4344 4343 hdev = hub->hdev; 4345 - udev = hdev->children[port-1]; 4344 + udev = hub->ports[port - 1]->child; 4346 4345 if (!hub_is_superspeed(hdev)) { 4347 4346 if (!(portchange & USB_PORT_STAT_C_SUSPEND)) 4348 4347 return 0; ··· 4496 4495 */ 4497 4496 if (!(portstatus & USB_PORT_STAT_ENABLE) 4498 4497 && !connect_change 4499 - && hdev->children[i-1]) { 4498 + && hub->ports[i - 1]->child) { 4500 4499 dev_err (hub_dev, 4501 4500 "port %i " 4502 4501 "disabled by hub (EMI?), " ··· 5053 5052 schedule_work(&iface->reset_ws); 5054 5053 } 5055 5054 EXPORT_SYMBOL_GPL(usb_queue_reset_device); 5055 + 5056 + /** 5057 + * usb_hub_find_child - Get the pointer of child device 5058 + * attached to the port which is specified by @port1. 5059 + * @hdev: USB device belonging to the usb hub 5060 + * @port1: port num to indicate which port the child device 5061 + * is attached to. 5062 + * 5063 + * USB drivers call this function to get hub's child device 5064 + * pointer. 5065 + * 5066 + * Return NULL if input param is invalid and 5067 + * child's usb_device pointer if non-NULL. 5068 + */ 5069 + struct usb_device *usb_hub_find_child(struct usb_device *hdev, 5070 + int port1) 5071 + { 5072 + struct usb_hub *hub = hdev_to_hub(hdev); 5073 + 5074 + if (port1 < 1 || port1 > hdev->maxchild) 5075 + return NULL; 5076 + return hub->ports[port1 - 1]->child; 5077 + } 5078 + EXPORT_SYMBOL_GPL(usb_hub_find_child);
+2 -3
drivers/usb/host/r8a66597-hcd.c
··· 2029 2029 static void collect_usb_address_map(struct usb_device *udev, unsigned long *map) 2030 2030 { 2031 2031 int chix; 2032 + struct usb_device *childdev; 2032 2033 2033 2034 if (udev->state == USB_STATE_CONFIGURED && 2034 2035 udev->parent && udev->parent->devnum > 1 && 2035 2036 udev->parent->descriptor.bDeviceClass == USB_CLASS_HUB) 2036 2037 map[udev->devnum/32] |= (1 << (udev->devnum % 32)); 2037 2038 2038 - for (chix = 0; chix < udev->maxchild; chix++) { 2039 - struct usb_device *childdev = udev->children[chix]; 2040 - 2039 + usb_hub_for_each_child(udev, chix, childdev) { 2041 2040 if (childdev) 2042 2041 collect_usb_address_map(childdev, map); 2043 2042 }
+13 -2
include/linux/usb.h
··· 469 469 * access from userspace 470 470 * @usbfs_dentry: usbfs dentry entry for the device 471 471 * @maxchild: number of ports if hub 472 - * @children: child devices - USB devices that are attached to this hub 473 472 * @quirks: quirks of the whole device 474 473 * @urbnum: number of URBs submitted for the whole device 475 474 * @active_duration: total time device is not suspended ··· 542 543 struct list_head filelist; 543 544 544 545 int maxchild; 545 - struct usb_device **children; 546 546 547 547 u32 quirks; 548 548 atomic_t urbnum; ··· 570 572 571 573 extern struct usb_device *usb_get_dev(struct usb_device *dev); 572 574 extern void usb_put_dev(struct usb_device *dev); 575 + extern struct usb_device *usb_hub_find_child(struct usb_device *hdev, 576 + int port1); 577 + 578 + /** 579 + * usb_hub_for_each_child - iterate over all child devices on the hub 580 + * @hdev: USB device belonging to the usb hub 581 + * @port1: portnum associated with child device 582 + * @child: child device pointer 583 + */ 584 + #define usb_hub_for_each_child(hdev, port1, child) \ 585 + for (port1 = 1, child = usb_hub_find_child(hdev, port1); \ 586 + port1 <= hdev->maxchild; \ 587 + child = usb_hub_find_child(hdev, ++port1)) 573 588 574 589 /* USB device locking */ 575 590 #define usb_lock_device(udev) device_lock(&(udev)->dev)