aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLan Tianyu <tianyu.lan@intel.com>2012-05-11 04:08:30 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-05-11 20:08:41 -0400
commitbebc56d58dc780539777d2b1ca80df5566e2ad87 (patch)
treee24d45842809c559c98abb6fb6b2db1445264220
parentf397d7c4c5e8a1eb93f2ed15808a509318ccf1dd (diff)
usb: move struct usb_device->children to struct usb_hub_port->child
Move child's pointer to the struct usb_hub_port since the child device is directly associated with the port. Provide usb_get_hub_child_device() to get child's pointer. Signed-off-by: Lan Tianyu <tianyu.lan@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/staging/usbip/usbip_common.c3
-rw-r--r--drivers/usb/core/devices.c3
-rw-r--r--drivers/usb/core/hub.c67
-rw-r--r--drivers/usb/host/r8a66597-hcd.c3
-rw-r--r--include/linux/usb.h4
5 files changed, 47 insertions, 33 deletions
diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/staging/usbip/usbip_common.c
index 70f230269329..95beb76497d6 100644
--- a/drivers/staging/usbip/usbip_common.c
+++ b/drivers/staging/usbip/usbip_common.c
@@ -157,8 +157,7 @@ static void usbip_dump_usb_device(struct usb_device *udev)
157 dev_dbg(dev, "have_langid %d, string_langid %d\n", 157 dev_dbg(dev, "have_langid %d, string_langid %d\n",
158 udev->have_langid, udev->string_langid); 158 udev->have_langid, udev->string_langid);
159 159
160 dev_dbg(dev, "maxchild %d, children %p\n", 160 dev_dbg(dev, "maxchild %d\n", udev->maxchild);
161 udev->maxchild, udev->children);
162} 161}
163 162
164static void usbip_dump_request_type(__u8 rt) 163static void usbip_dump_request_type(__u8 rt)
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c
index d95696584762..a83962b1ccee 100644
--- a/drivers/usb/core/devices.c
+++ b/drivers/usb/core/devices.c
@@ -590,7 +590,8 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes,
590 590
591 /* Now look at all of this device's children. */ 591 /* Now look at all of this device's children. */
592 for (chix = 0; chix < usbdev->maxchild; chix++) { 592 for (chix = 0; chix < usbdev->maxchild; chix++) {
593 struct usb_device *childdev = usbdev->children[chix]; 593 struct usb_device *childdev =
594 usb_get_hub_child_device(usbdev, chix + 1);
594 595
595 if (childdev) { 596 if (childdev) {
596 usb_lock_device(childdev); 597 usb_lock_device(childdev);
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 0c17d5a91d79..6bf7124fdf96 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -39,6 +39,7 @@
39 39
40struct usb_hub_port { 40struct usb_hub_port {
41 void *port_owner; 41 void *port_owner;
42 struct usb_device *child;
42}; 43};
43 44
44struct usb_hub { 45struct usb_hub {
@@ -93,7 +94,7 @@ static inline int hub_is_superspeed(struct usb_device *hdev)
93 return (hdev->descriptor.bDeviceProtocol == USB_HUB_PR_SS); 94 return (hdev->descriptor.bDeviceProtocol == USB_HUB_PR_SS);
94} 95}
95 96
96/* Protect struct usb_device->state and ->children members 97/* Protect struct usb_device->state and struct usb_hub_port->child members
97 * Note: Both are also protected by ->dev.sem, except that ->state can 98 * Note: Both are also protected by ->dev.sem, except that ->state can
98 * change to USB_STATE_NOTATTACHED even when the semaphore isn't held. */ 99 * change to USB_STATE_NOTATTACHED even when the semaphore isn't held. */
99static DEFINE_SPINLOCK(device_state_lock); 100static DEFINE_SPINLOCK(device_state_lock);
@@ -176,7 +177,7 @@ static inline char *portspeed(struct usb_hub *hub, int portstatus)
176/* Note that hdev or one of its children must be locked! */ 177/* Note that hdev or one of its children must be locked! */
177static struct usb_hub *hdev_to_hub(struct usb_device *hdev) 178static struct usb_hub *hdev_to_hub(struct usb_device *hdev)
178{ 179{
179 if (!hdev || !hdev->actconfig) 180 if (!hdev || !hdev->actconfig || !hdev->maxchild)
180 return NULL; 181 return NULL;
181 return usb_get_intfdata(hdev->actconfig->interface[0]); 182 return usb_get_intfdata(hdev->actconfig->interface[0]);
182} 183}
@@ -649,8 +650,8 @@ static int hub_port_disable(struct usb_hub *hub, int port1, int set_state)
649 struct usb_device *hdev = hub->hdev; 650 struct usb_device *hdev = hub->hdev;
650 int ret = 0; 651 int ret = 0;
651 652
652 if (hdev->children[port1-1] && set_state) 653 if (hub->port_data[port1-1].child && set_state)
653 usb_set_device_state(hdev->children[port1-1], 654 usb_set_device_state(hub->port_data[port1-1].child,
654 USB_STATE_NOTATTACHED); 655 USB_STATE_NOTATTACHED);
655 if (!hub->error && !hub_is_superspeed(hub->hdev)) 656 if (!hub->error && !hub_is_superspeed(hub->hdev))
656 ret = clear_port_feature(hdev, port1, USB_PORT_FEAT_ENABLE); 657 ret = clear_port_feature(hdev, port1, USB_PORT_FEAT_ENABLE);
@@ -806,7 +807,7 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
806 * which ports need attention. 807 * which ports need attention.
807 */ 808 */
808 for (port1 = 1; port1 <= hdev->maxchild; ++port1) { 809 for (port1 = 1; port1 <= hdev->maxchild; ++port1) {
809 struct usb_device *udev = hdev->children[port1-1]; 810 struct usb_device *udev = hub->port_data[port1-1].child;
810 u16 portstatus, portchange; 811 u16 portstatus, portchange;
811 812
812 portstatus = portchange = 0; 813 portstatus = portchange = 0;
@@ -971,8 +972,8 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type)
971 if (type != HUB_SUSPEND) { 972 if (type != HUB_SUSPEND) {
972 /* Disconnect all the children */ 973 /* Disconnect all the children */
973 for (i = 0; i < hdev->maxchild; ++i) { 974 for (i = 0; i < hdev->maxchild; ++i) {
974 if (hdev->children[i]) 975 if (hub->port_data[i].child)
975 usb_disconnect(&hdev->children[i]); 976 usb_disconnect(&hub->port_data[i].child);
976 } 977 }
977 } 978 }
978 979
@@ -1051,11 +1052,9 @@ static int hub_configure(struct usb_hub *hub,
1051 dev_info (hub_dev, "%d port%s detected\n", hdev->maxchild, 1052 dev_info (hub_dev, "%d port%s detected\n", hdev->maxchild,
1052 (hdev->maxchild == 1) ? "" : "s"); 1053 (hdev->maxchild == 1) ? "" : "s");
1053 1054
1054 hdev->children = kzalloc(hdev->maxchild *
1055 sizeof(struct usb_device *), GFP_KERNEL);
1056 hub->port_data = kzalloc(hdev->maxchild * sizeof(struct usb_hub_port), 1055 hub->port_data = kzalloc(hdev->maxchild * sizeof(struct usb_hub_port),
1057 GFP_KERNEL); 1056 GFP_KERNEL);
1058 if (!hub->port_data || !hdev->children) { 1057 if (!hub->port_data) {
1059 ret = -ENOMEM; 1058 ret = -ENOMEM;
1060 goto fail; 1059 goto fail;
1061 } 1060 }
@@ -1287,7 +1286,6 @@ static unsigned highspeed_hubs;
1287static void hub_disconnect(struct usb_interface *intf) 1286static void hub_disconnect(struct usb_interface *intf)
1288{ 1287{
1289 struct usb_hub *hub = usb_get_intfdata(intf); 1288 struct usb_hub *hub = usb_get_intfdata(intf);
1290 struct usb_device *hdev = interface_to_usbdev(intf);
1291 1289
1292 /* Take the hub off the event list and don't let it be added again */ 1290 /* Take the hub off the event list and don't let it be added again */
1293 spin_lock_irq(&hub_event_lock); 1291 spin_lock_irq(&hub_event_lock);
@@ -1309,7 +1307,6 @@ static void hub_disconnect(struct usb_interface *intf)
1309 highspeed_hubs--; 1307 highspeed_hubs--;
1310 1308
1311 usb_free_urb(hub->urb); 1309 usb_free_urb(hub->urb);
1312 kfree(hdev->children);
1313 kfree(hub->port_data); 1310 kfree(hub->port_data);
1314 kfree(hub->descriptor); 1311 kfree(hub->descriptor);
1315 kfree(hub->status); 1312 kfree(hub->status);
@@ -1397,6 +1394,7 @@ static int
1397hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data) 1394hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data)
1398{ 1395{
1399 struct usb_device *hdev = interface_to_usbdev (intf); 1396 struct usb_device *hdev = interface_to_usbdev (intf);
1397 struct usb_hub *hub = usb_get_intfdata(intf);
1400 1398
1401 /* assert ifno == 0 (part of hub spec) */ 1399 /* assert ifno == 0 (part of hub spec) */
1402 switch (code) { 1400 switch (code) {
@@ -1410,11 +1408,11 @@ hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data)
1410 else { 1408 else {
1411 info->nports = hdev->maxchild; 1409 info->nports = hdev->maxchild;
1412 for (i = 0; i < info->nports; i++) { 1410 for (i = 0; i < info->nports; i++) {
1413 if (hdev->children[i] == NULL) 1411 if (hub->port_data[i].child == NULL)
1414 info->port[i] = 0; 1412 info->port[i] = 0;
1415 else 1413 else
1416 info->port[i] = 1414 info->port[i] =
1417 hdev->children[i]->devnum; 1415 hub->port_data[i].child->devnum;
1418 } 1416 }
1419 } 1417 }
1420 spin_unlock_irq(&device_state_lock); 1418 spin_unlock_irq(&device_state_lock);
@@ -1501,11 +1499,13 @@ bool usb_device_is_owned(struct usb_device *udev)
1501 1499
1502static void recursively_mark_NOTATTACHED(struct usb_device *udev) 1500static void recursively_mark_NOTATTACHED(struct usb_device *udev)
1503{ 1501{
1502 struct usb_hub *hub = hdev_to_hub(udev);
1504 int i; 1503 int i;
1505 1504
1506 for (i = 0; i < udev->maxchild; ++i) { 1505 for (i = 0; i < udev->maxchild; ++i) {
1507 if (udev->children[i]) 1506 if (hub->port_data[i].child)
1508 recursively_mark_NOTATTACHED(udev->children[i]); 1507 recursively_mark_NOTATTACHED(
1508 hub->port_data[i].child);
1509 } 1509 }
1510 if (udev->state == USB_STATE_SUSPENDED) 1510 if (udev->state == USB_STATE_SUSPENDED)
1511 udev->active_duration -= jiffies; 1511 udev->active_duration -= jiffies;
@@ -1669,6 +1669,7 @@ static void hub_free_dev(struct usb_device *udev)
1669void usb_disconnect(struct usb_device **pdev) 1669void usb_disconnect(struct usb_device **pdev)
1670{ 1670{
1671 struct usb_device *udev = *pdev; 1671 struct usb_device *udev = *pdev;
1672 struct usb_hub *hub = hdev_to_hub(udev);
1672 int i; 1673 int i;
1673 1674
1674 /* mark the device as inactive, so any further urb submissions for 1675 /* mark the device as inactive, so any further urb submissions for
@@ -1683,8 +1684,8 @@ void usb_disconnect(struct usb_device **pdev)
1683 1684
1684 /* Free up all the children before we remove this device */ 1685 /* Free up all the children before we remove this device */
1685 for (i = 0; i < udev->maxchild; i++) { 1686 for (i = 0; i < udev->maxchild; i++) {
1686 if (udev->children[i]) 1687 if (hub->port_data[i].child)
1687 usb_disconnect(&udev->children[i]); 1688 usb_disconnect(&hub->port_data[i].child);
1688 } 1689 }
1689 1690
1690 /* deallocate hcd/hardware state ... nuking all pending urbs and 1691 /* deallocate hcd/hardware state ... nuking all pending urbs and
@@ -2765,7 +2766,7 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
2765 for (port1 = 1; port1 <= hdev->maxchild; port1++) { 2766 for (port1 = 1; port1 <= hdev->maxchild; port1++) {
2766 struct usb_device *udev; 2767 struct usb_device *udev;
2767 2768
2768 udev = hdev->children [port1-1]; 2769 udev = hub->port_data[port1-1].child;
2769 if (udev && udev->can_submit) { 2770 if (udev && udev->can_submit) {
2770 dev_warn(&intf->dev, "port %d nyet suspended\n", port1); 2771 dev_warn(&intf->dev, "port %d nyet suspended\n", port1);
2771 if (PMSG_IS_AUTO(msg)) 2772 if (PMSG_IS_AUTO(msg))
@@ -3266,7 +3267,7 @@ hub_power_remaining (struct usb_hub *hub)
3266 3267
3267 remaining = hdev->bus_mA - hub->descriptor->bHubContrCurrent; 3268 remaining = hdev->bus_mA - hub->descriptor->bHubContrCurrent;
3268 for (port1 = 1; port1 <= hdev->maxchild; ++port1) { 3269 for (port1 = 1; port1 <= hdev->maxchild; ++port1) {
3269 struct usb_device *udev = hdev->children[port1 - 1]; 3270 struct usb_device *udev = hub->port_data[port1 - 1].child;
3270 int delta; 3271 int delta;
3271 3272
3272 if (!udev) 3273 if (!udev)
@@ -3330,7 +3331,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
3330#endif 3331#endif
3331 3332
3332 /* Try to resuscitate an existing device */ 3333 /* Try to resuscitate an existing device */
3333 udev = hdev->children[port1-1]; 3334 udev = hub->port_data[port1-1].child;
3334 if ((portstatus & USB_PORT_STAT_CONNECTION) && udev && 3335 if ((portstatus & USB_PORT_STAT_CONNECTION) && udev &&
3335 udev->state != USB_STATE_NOTATTACHED) { 3336 udev->state != USB_STATE_NOTATTACHED) {
3336 usb_lock_device(udev); 3337 usb_lock_device(udev);
@@ -3359,7 +3360,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
3359 3360
3360 /* Disconnect any existing devices under this port */ 3361 /* Disconnect any existing devices under this port */
3361 if (udev) 3362 if (udev)
3362 usb_disconnect(&hdev->children[port1-1]); 3363 usb_disconnect(&hub->port_data[port1-1].child);
3363 clear_bit(port1, hub->change_bits); 3364 clear_bit(port1, hub->change_bits);
3364 3365
3365 /* We can forget about a "removed" device when there's a physical 3366 /* We can forget about a "removed" device when there's a physical
@@ -3474,7 +3475,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
3474 && highspeed_hubs != 0) 3475 && highspeed_hubs != 0)
3475 check_highspeed (hub, udev, port1); 3476 check_highspeed (hub, udev, port1);
3476 3477
3477 /* Store the parent's children[] pointer. At this point 3478 /* Store the hub port's child pointer. At this point
3478 * udev becomes globally accessible, although presumably 3479 * udev becomes globally accessible, although presumably
3479 * no one will look at it until hdev is unlocked. 3480 * no one will look at it until hdev is unlocked.
3480 */ 3481 */
@@ -3488,7 +3489,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
3488 if (hdev->state == USB_STATE_NOTATTACHED) 3489 if (hdev->state == USB_STATE_NOTATTACHED)
3489 status = -ENOTCONN; 3490 status = -ENOTCONN;
3490 else 3491 else
3491 hdev->children[port1-1] = udev; 3492 hub->port_data[port1-1].child = udev;
3492 spin_unlock_irq(&device_state_lock); 3493 spin_unlock_irq(&device_state_lock);
3493 3494
3494 /* Run it through the hoops (find a driver, etc) */ 3495 /* Run it through the hoops (find a driver, etc) */
@@ -3496,7 +3497,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
3496 status = usb_new_device(udev); 3497 status = usb_new_device(udev);
3497 if (status) { 3498 if (status) {
3498 spin_lock_irq(&device_state_lock); 3499 spin_lock_irq(&device_state_lock);
3499 hdev->children[port1-1] = NULL; 3500 hub->port_data[port1-1].child = NULL;
3500 spin_unlock_irq(&device_state_lock); 3501 spin_unlock_irq(&device_state_lock);
3501 } 3502 }
3502 } 3503 }
@@ -3542,7 +3543,7 @@ static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port,
3542 int ret; 3543 int ret;
3543 3544
3544 hdev = hub->hdev; 3545 hdev = hub->hdev;
3545 udev = hdev->children[port-1]; 3546 udev = hub->port_data[port - 1].child;
3546 if (!hub_is_superspeed(hdev)) { 3547 if (!hub_is_superspeed(hdev)) {
3547 if (!(portchange & USB_PORT_STAT_C_SUSPEND)) 3548 if (!(portchange & USB_PORT_STAT_C_SUSPEND))
3548 return 0; 3549 return 0;
@@ -3696,7 +3697,7 @@ static void hub_events(void)
3696 */ 3697 */
3697 if (!(portstatus & USB_PORT_STAT_ENABLE) 3698 if (!(portstatus & USB_PORT_STAT_ENABLE)
3698 && !connect_change 3699 && !connect_change
3699 && hdev->children[i-1]) { 3700 && hub->port_data[i-1].child) {
3700 dev_err (hub_dev, 3701 dev_err (hub_dev,
3701 "port %i " 3702 "port %i "
3702 "disabled by hub (EMI?), " 3703 "disabled by hub (EMI?), "
@@ -4234,3 +4235,15 @@ void usb_queue_reset_device(struct usb_interface *iface)
4234 schedule_work(&iface->reset_ws); 4235 schedule_work(&iface->reset_ws);
4235} 4236}
4236EXPORT_SYMBOL_GPL(usb_queue_reset_device); 4237EXPORT_SYMBOL_GPL(usb_queue_reset_device);
4238
4239struct usb_device *usb_get_hub_child_device(struct usb_device *hdev,
4240 int port1)
4241{
4242 struct usb_hub *hub = hdev_to_hub(hdev);
4243
4244 if (!hub || port1 > hdev->maxchild || port1 < 1)
4245 return NULL;
4246 return hub->port_data[port1 - 1].child;
4247}
4248EXPORT_SYMBOL_GPL(usb_get_hub_child_device);
4249
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index c868be65e763..4c82fdf5494f 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -2040,7 +2040,8 @@ static void collect_usb_address_map(struct usb_device *udev, unsigned long *map)
2040 map[udev->devnum/32] |= (1 << (udev->devnum % 32)); 2040 map[udev->devnum/32] |= (1 << (udev->devnum % 32));
2041 2041
2042 for (chix = 0; chix < udev->maxchild; chix++) { 2042 for (chix = 0; chix < udev->maxchild; chix++) {
2043 struct usb_device *childdev = udev->children[chix]; 2043 struct usb_device *childdev =
2044 usb_get_hub_child_device(udev, chix + 1);
2044 2045
2045 if (childdev) 2046 if (childdev)
2046 collect_usb_address_map(childdev, map); 2047 collect_usb_address_map(childdev, map);
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 5483cd70390b..69163a0abe91 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -424,7 +424,6 @@ enum usb_device_removable {
424 * access from userspace 424 * access from userspace
425 * @usbfs_dentry: usbfs dentry entry for the device 425 * @usbfs_dentry: usbfs dentry entry for the device
426 * @maxchild: number of ports if hub 426 * @maxchild: number of ports if hub
427 * @children: child devices - USB devices that are attached to this hub
428 * @quirks: quirks of the whole device 427 * @quirks: quirks of the whole device
429 * @urbnum: number of URBs submitted for the whole device 428 * @urbnum: number of URBs submitted for the whole device
430 * @active_duration: total time device is not suspended 429 * @active_duration: total time device is not suspended
@@ -491,7 +490,6 @@ struct usb_device {
491 struct list_head filelist; 490 struct list_head filelist;
492 491
493 int maxchild; 492 int maxchild;
494 struct usb_device **children;
495 493
496 u32 quirks; 494 u32 quirks;
497 atomic_t urbnum; 495 atomic_t urbnum;
@@ -517,6 +515,8 @@ static inline struct usb_device *interface_to_usbdev(struct usb_interface *intf)
517 515
518extern struct usb_device *usb_get_dev(struct usb_device *dev); 516extern struct usb_device *usb_get_dev(struct usb_device *dev);
519extern void usb_put_dev(struct usb_device *dev); 517extern void usb_put_dev(struct usb_device *dev);
518extern struct usb_device *usb_get_hub_child_device(struct usb_device *hdev,
519 int port1);
520 520
521/* USB device locking */ 521/* USB device locking */
522#define usb_lock_device(udev) device_lock(&(udev)->dev) 522#define usb_lock_device(udev) device_lock(&(udev)->dev)