aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorMathias Nyman <mathias.nyman@linux.intel.com>2013-06-18 10:28:48 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-06-18 14:02:04 -0400
commit41341261aa1707b49f937ba2c20d1a0daa5afac3 (patch)
tree7f7e80ab0396c7b0381013461d94ef9af852168a /drivers/usb
parent025f880cb2e4d7218d0422d4b07bea1a68959c38 (diff)
usb: check usb_hub_to_struct_hub() return value
usb_hub_to_struct_hub() can return NULL in some unlikely cases. Add checks where appropriate, or pass the hub pointer as an additional argument if it's known to be valid. The places it makes sense to check usb_hub_to_struct_hub() are picked based on feedback from Alan Stern. Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> Acked-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/core/hub.c23
-rw-r--r--drivers/usb/core/hub.h2
-rw-r--r--drivers/usb/core/port.c4
3 files changed, 19 insertions, 10 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index feef9351463d..4191db32f12c 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -718,18 +718,18 @@ static void hub_tt_work(struct work_struct *work)
718 718
719/** 719/**
720 * usb_hub_set_port_power - control hub port's power state 720 * usb_hub_set_port_power - control hub port's power state
721 * @hdev: target hub 721 * @hdev: USB device belonging to the usb hub
722 * @hub: target hub
722 * @port1: port index 723 * @port1: port index
723 * @set: expected status 724 * @set: expected status
724 * 725 *
725 * call this function to control port's power via setting or 726 * call this function to control port's power via setting or
726 * clearing the port's PORT_POWER feature. 727 * clearing the port's PORT_POWER feature.
727 */ 728 */
728int usb_hub_set_port_power(struct usb_device *hdev, int port1, 729int usb_hub_set_port_power(struct usb_device *hdev, struct usb_hub *hub,
729 bool set) 730 int port1, bool set)
730{ 731{
731 int ret; 732 int ret;
732 struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
733 struct usb_port *port_dev = hub->ports[port1 - 1]; 733 struct usb_port *port_dev = hub->ports[port1 - 1];
734 734
735 if (set) 735 if (set)
@@ -1769,15 +1769,17 @@ hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data)
1769static int find_port_owner(struct usb_device *hdev, unsigned port1, 1769static int find_port_owner(struct usb_device *hdev, unsigned port1,
1770 struct dev_state ***ppowner) 1770 struct dev_state ***ppowner)
1771{ 1771{
1772 struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
1773
1772 if (hdev->state == USB_STATE_NOTATTACHED) 1774 if (hdev->state == USB_STATE_NOTATTACHED)
1773 return -ENODEV; 1775 return -ENODEV;
1774 if (port1 == 0 || port1 > hdev->maxchild) 1776 if (port1 == 0 || port1 > hdev->maxchild)
1775 return -EINVAL; 1777 return -EINVAL;
1776 1778
1777 /* This assumes that devices not managed by the hub driver 1779 /* Devices not managed by the hub driver
1778 * will always have maxchild equal to 0. 1780 * will always have maxchild equal to 0.
1779 */ 1781 */
1780 *ppowner = &(usb_hub_to_struct_hub(hdev)->ports[port1 - 1]->port_owner); 1782 *ppowner = &(hub->ports[port1 - 1]->port_owner);
1781 return 0; 1783 return 0;
1782} 1784}
1783 1785
@@ -5323,7 +5325,8 @@ void usb_set_hub_port_connect_type(struct usb_device *hdev, int port1,
5323{ 5325{
5324 struct usb_hub *hub = usb_hub_to_struct_hub(hdev); 5326 struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
5325 5327
5326 hub->ports[port1 - 1]->connect_type = type; 5328 if (hub)
5329 hub->ports[port1 - 1]->connect_type = type;
5327} 5330}
5328 5331
5329/** 5332/**
@@ -5339,6 +5342,9 @@ usb_get_hub_port_connect_type(struct usb_device *hdev, int port1)
5339{ 5342{
5340 struct usb_hub *hub = usb_hub_to_struct_hub(hdev); 5343 struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
5341 5344
5345 if (!hub)
5346 return USB_PORT_CONNECT_TYPE_UNKNOWN;
5347
5342 return hub->ports[port1 - 1]->connect_type; 5348 return hub->ports[port1 - 1]->connect_type;
5343} 5349}
5344 5350
@@ -5397,6 +5403,9 @@ acpi_handle usb_get_hub_port_acpi_handle(struct usb_device *hdev,
5397{ 5403{
5398 struct usb_hub *hub = usb_hub_to_struct_hub(hdev); 5404 struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
5399 5405
5406 if (!hub)
5407 return NULL;
5408
5400 return DEVICE_ACPI_HANDLE(&hub->ports[port1 - 1]->dev); 5409 return DEVICE_ACPI_HANDLE(&hub->ports[port1 - 1]->dev);
5401} 5410}
5402#endif 5411#endif
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h
index 80ab9ee07017..6508e02b3dac 100644
--- a/drivers/usb/core/hub.h
+++ b/drivers/usb/core/hub.h
@@ -100,7 +100,7 @@ extern int usb_hub_create_port_device(struct usb_hub *hub,
100 int port1); 100 int port1);
101extern void usb_hub_remove_port_device(struct usb_hub *hub, 101extern void usb_hub_remove_port_device(struct usb_hub *hub,
102 int port1); 102 int port1);
103extern int usb_hub_set_port_power(struct usb_device *hdev, 103extern int usb_hub_set_port_power(struct usb_device *hdev, struct usb_hub *hub,
104 int port1, bool set); 104 int port1, bool set);
105extern struct usb_hub *usb_hub_to_struct_hub(struct usb_device *hdev); 105extern struct usb_hub *usb_hub_to_struct_hub(struct usb_device *hdev);
106extern int hub_port_debounce(struct usb_hub *hub, int port1, 106extern int hub_port_debounce(struct usb_hub *hub, int port1,
diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index b8bad294eeb8..5fd3fee58f8b 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -86,7 +86,7 @@ static int usb_port_runtime_resume(struct device *dev)
86 usb_autopm_get_interface(intf); 86 usb_autopm_get_interface(intf);
87 set_bit(port1, hub->busy_bits); 87 set_bit(port1, hub->busy_bits);
88 88
89 retval = usb_hub_set_port_power(hdev, port1, true); 89 retval = usb_hub_set_port_power(hdev, hub, port1, true);
90 if (port_dev->child && !retval) { 90 if (port_dev->child && !retval) {
91 /* 91 /*
92 * Wait for usb hub port to be reconnected in order to make 92 * Wait for usb hub port to be reconnected in order to make
@@ -128,7 +128,7 @@ static int usb_port_runtime_suspend(struct device *dev)
128 128
129 usb_autopm_get_interface(intf); 129 usb_autopm_get_interface(intf);
130 set_bit(port1, hub->busy_bits); 130 set_bit(port1, hub->busy_bits);
131 retval = usb_hub_set_port_power(hdev, port1, false); 131 retval = usb_hub_set_port_power(hdev, hub, port1, false);
132 usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_CONNECTION); 132 usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_CONNECTION);
133 usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_ENABLE); 133 usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_ENABLE);
134 clear_bit(port1, hub->busy_bits); 134 clear_bit(port1, hub->busy_bits);