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>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
fa2a956625
commit
ff823c79a5
@@ -40,6 +40,7 @@
|
||||
#endif
|
||||
|
||||
struct usb_port {
|
||||
struct usb_device *child;
|
||||
struct device dev;
|
||||
struct dev_state *port_owner;
|
||||
};
|
||||
@@ -181,7 +182,7 @@ static inline char *portspeed(struct usb_hub *hub, int portstatus)
|
||||
/* Note that hdev or one of its children must be locked! */
|
||||
static struct usb_hub *hdev_to_hub(struct usb_device *hdev)
|
||||
{
|
||||
if (!hdev || !hdev->actconfig)
|
||||
if (!hdev || !hdev->actconfig || !hdev->maxchild)
|
||||
return NULL;
|
||||
return usb_get_intfdata(hdev->actconfig->interface[0]);
|
||||
}
|
||||
@@ -876,8 +877,8 @@ static int hub_port_disable(struct usb_hub *hub, int port1, int set_state)
|
||||
struct usb_device *hdev = hub->hdev;
|
||||
int ret = 0;
|
||||
|
||||
if (hdev->children[port1-1] && set_state)
|
||||
usb_set_device_state(hdev->children[port1-1],
|
||||
if (hub->ports[port1 - 1]->child && set_state)
|
||||
usb_set_device_state(hub->ports[port1 - 1]->child,
|
||||
USB_STATE_NOTATTACHED);
|
||||
if (!hub->error && !hub_is_superspeed(hub->hdev))
|
||||
ret = clear_port_feature(hdev, port1, USB_PORT_FEAT_ENABLE);
|
||||
@@ -1033,7 +1034,7 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
|
||||
* which ports need attention.
|
||||
*/
|
||||
for (port1 = 1; port1 <= hdev->maxchild; ++port1) {
|
||||
struct usb_device *udev = hdev->children[port1-1];
|
||||
struct usb_device *udev = hub->ports[port1 - 1]->child;
|
||||
u16 portstatus, portchange;
|
||||
|
||||
portstatus = portchange = 0;
|
||||
@@ -1198,8 +1199,8 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type)
|
||||
if (type != HUB_SUSPEND) {
|
||||
/* Disconnect all the children */
|
||||
for (i = 0; i < hdev->maxchild; ++i) {
|
||||
if (hdev->children[i])
|
||||
usb_disconnect(&hdev->children[i]);
|
||||
if (hub->ports[i]->child)
|
||||
usb_disconnect(&hub->ports[i]->child);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1324,11 +1325,9 @@ static int hub_configure(struct usb_hub *hub,
|
||||
dev_info (hub_dev, "%d port%s detected\n", hdev->maxchild,
|
||||
(hdev->maxchild == 1) ? "" : "s");
|
||||
|
||||
hdev->children = kzalloc(hdev->maxchild *
|
||||
sizeof(struct usb_device *), GFP_KERNEL);
|
||||
hub->ports = kzalloc(hdev->maxchild * sizeof(struct usb_port *),
|
||||
GFP_KERNEL);
|
||||
if (!hdev->children || !hub->ports) {
|
||||
if (!hub->ports) {
|
||||
ret = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
@@ -1591,7 +1590,6 @@ static void hub_disconnect(struct usb_interface *intf)
|
||||
highspeed_hubs--;
|
||||
|
||||
usb_free_urb(hub->urb);
|
||||
kfree(hdev->children);
|
||||
kfree(hub->ports);
|
||||
kfree(hub->descriptor);
|
||||
kfree(hub->status);
|
||||
@@ -1679,6 +1677,7 @@ static int
|
||||
hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data)
|
||||
{
|
||||
struct usb_device *hdev = interface_to_usbdev (intf);
|
||||
struct usb_hub *hub = hdev_to_hub(hdev);
|
||||
|
||||
/* assert ifno == 0 (part of hub spec) */
|
||||
switch (code) {
|
||||
@@ -1692,11 +1691,11 @@ hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data)
|
||||
else {
|
||||
info->nports = hdev->maxchild;
|
||||
for (i = 0; i < info->nports; i++) {
|
||||
if (hdev->children[i] == NULL)
|
||||
if (hub->ports[i]->child == NULL)
|
||||
info->port[i] = 0;
|
||||
else
|
||||
info->port[i] =
|
||||
hdev->children[i]->devnum;
|
||||
hub->ports[i]->child->devnum;
|
||||
}
|
||||
}
|
||||
spin_unlock_irq(&device_state_lock);
|
||||
@@ -1784,11 +1783,12 @@ bool usb_device_is_owned(struct usb_device *udev)
|
||||
|
||||
static void recursively_mark_NOTATTACHED(struct usb_device *udev)
|
||||
{
|
||||
struct usb_hub *hub = hdev_to_hub(udev);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < udev->maxchild; ++i) {
|
||||
if (udev->children[i])
|
||||
recursively_mark_NOTATTACHED(udev->children[i]);
|
||||
if (hub->ports[i]->child)
|
||||
recursively_mark_NOTATTACHED(hub->ports[i]->child);
|
||||
}
|
||||
if (udev->state == USB_STATE_SUSPENDED)
|
||||
udev->active_duration -= jiffies;
|
||||
@@ -1952,6 +1952,7 @@ static void hub_free_dev(struct usb_device *udev)
|
||||
void usb_disconnect(struct usb_device **pdev)
|
||||
{
|
||||
struct usb_device *udev = *pdev;
|
||||
struct usb_hub *hub = hdev_to_hub(udev);
|
||||
int i;
|
||||
|
||||
/* mark the device as inactive, so any further urb submissions for
|
||||
@@ -1966,8 +1967,8 @@ void usb_disconnect(struct usb_device **pdev)
|
||||
|
||||
/* Free up all the children before we remove this device */
|
||||
for (i = 0; i < udev->maxchild; i++) {
|
||||
if (udev->children[i])
|
||||
usb_disconnect(&udev->children[i]);
|
||||
if (hub->ports[i]->child)
|
||||
usb_disconnect(&hub->ports[i]->child);
|
||||
}
|
||||
|
||||
/* deallocate hcd/hardware state ... nuking all pending urbs and
|
||||
@@ -3131,7 +3132,7 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
|
||||
for (port1 = 1; port1 <= hdev->maxchild; port1++) {
|
||||
struct usb_device *udev;
|
||||
|
||||
udev = hdev->children [port1-1];
|
||||
udev = hub->ports[port1 - 1]->child;
|
||||
if (udev && udev->can_submit) {
|
||||
dev_warn(&intf->dev, "port %d nyet suspended\n", port1);
|
||||
if (PMSG_IS_AUTO(msg))
|
||||
@@ -4058,7 +4059,7 @@ hub_power_remaining (struct usb_hub *hub)
|
||||
|
||||
remaining = hdev->bus_mA - hub->descriptor->bHubContrCurrent;
|
||||
for (port1 = 1; port1 <= hdev->maxchild; ++port1) {
|
||||
struct usb_device *udev = hdev->children[port1 - 1];
|
||||
struct usb_device *udev = hub->ports[port1 - 1]->child;
|
||||
int delta;
|
||||
|
||||
if (!udev)
|
||||
@@ -4122,7 +4123,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
|
||||
#endif
|
||||
|
||||
/* Try to resuscitate an existing device */
|
||||
udev = hdev->children[port1-1];
|
||||
udev = hub->ports[port1 - 1]->child;
|
||||
if ((portstatus & USB_PORT_STAT_CONNECTION) && udev &&
|
||||
udev->state != USB_STATE_NOTATTACHED) {
|
||||
usb_lock_device(udev);
|
||||
@@ -4151,7 +4152,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
|
||||
|
||||
/* Disconnect any existing devices under this port */
|
||||
if (udev)
|
||||
usb_disconnect(&hdev->children[port1-1]);
|
||||
usb_disconnect(&hub->ports[port1 - 1]->child);
|
||||
clear_bit(port1, hub->change_bits);
|
||||
|
||||
/* We can forget about a "removed" device when there's a physical
|
||||
@@ -4287,7 +4288,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
|
||||
if (hdev->state == USB_STATE_NOTATTACHED)
|
||||
status = -ENOTCONN;
|
||||
else
|
||||
hdev->children[port1-1] = udev;
|
||||
hub->ports[port1 - 1]->child = udev;
|
||||
spin_unlock_irq(&device_state_lock);
|
||||
|
||||
/* Run it through the hoops (find a driver, etc) */
|
||||
@@ -4295,7 +4296,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
|
||||
status = usb_new_device(udev);
|
||||
if (status) {
|
||||
spin_lock_irq(&device_state_lock);
|
||||
hdev->children[port1-1] = NULL;
|
||||
hub->ports[port1 - 1]->child = NULL;
|
||||
spin_unlock_irq(&device_state_lock);
|
||||
}
|
||||
}
|
||||
@@ -4341,7 +4342,7 @@ static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port,
|
||||
int ret;
|
||||
|
||||
hdev = hub->hdev;
|
||||
udev = hdev->children[port-1];
|
||||
udev = hub->ports[port - 1]->child;
|
||||
if (!hub_is_superspeed(hdev)) {
|
||||
if (!(portchange & USB_PORT_STAT_C_SUSPEND))
|
||||
return 0;
|
||||
@@ -4495,7 +4496,7 @@ static void hub_events(void)
|
||||
*/
|
||||
if (!(portstatus & USB_PORT_STAT_ENABLE)
|
||||
&& !connect_change
|
||||
&& hdev->children[i-1]) {
|
||||
&& hub->ports[i - 1]->child) {
|
||||
dev_err (hub_dev,
|
||||
"port %i "
|
||||
"disabled by hub (EMI?), "
|
||||
@@ -5052,3 +5053,27 @@ void usb_queue_reset_device(struct usb_interface *iface)
|
||||
schedule_work(&iface->reset_ws);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_queue_reset_device);
|
||||
|
||||
/**
|
||||
* usb_hub_find_child - Get the pointer of child device
|
||||
* attached to the port which is specified by @port1.
|
||||
* @hdev: USB device belonging to the usb hub
|
||||
* @port1: port num to indicate which port the child device
|
||||
* is attached to.
|
||||
*
|
||||
* USB drivers call this function to get hub's child device
|
||||
* pointer.
|
||||
*
|
||||
* Return NULL if input param is invalid and
|
||||
* child's usb_device pointer if non-NULL.
|
||||
*/
|
||||
struct usb_device *usb_hub_find_child(struct usb_device *hdev,
|
||||
int port1)
|
||||
{
|
||||
struct usb_hub *hub = hdev_to_hub(hdev);
|
||||
|
||||
if (port1 < 1 || port1 > hdev->maxchild)
|
||||
return NULL;
|
||||
return hub->ports[port1 - 1]->child;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_hub_find_child);
|
||||
|
||||
Reference in New Issue
Block a user