aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2016-08-05 11:49:45 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-08-09 09:45:59 -0400
commitca5cbc8b02f9b21cc8cd1ab36668763ec34f9ee8 (patch)
tree0976c55e7e133a4f70eca694e3e86eb493745f10 /drivers/usb
parent6bb47e8ab98accb1319bd43c64966340ba3bba9a (diff)
USB: hub: fix up early-exit pathway in hub_activate
The early-exit pathway in hub_activate, added by commit e50293ef9775 ("USB: fix invalid memory access in hub_activate()") needs improvement. It duplicates code that is already present at the end of the subroutine, and it neglects to undo the effect of a usb_autopm_get_interface_no_resume() call. This patch fixes both problems by making the early-exit pathway jump directly to the end of the subroutine. It simplifies the code at the end by merging two conditionals that actually test the same condition although they appear different: If type < HUB_INIT3 then type must be either HUB_INIT2 or HUB_INIT, and it can't be HUB_INIT because in that case the subroutine would have exited earlier. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> CC: <stable@vger.kernel.org> #4.4+ Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/core/hub.c15
1 files changed, 6 insertions, 9 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 3ccffac0f647..bb69d262b6f9 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1055,11 +1055,8 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
1055 device_lock(hub->intfdev); 1055 device_lock(hub->intfdev);
1056 1056
1057 /* Was the hub disconnected while we were waiting? */ 1057 /* Was the hub disconnected while we were waiting? */
1058 if (hub->disconnected) { 1058 if (hub->disconnected)
1059 device_unlock(hub->intfdev); 1059 goto disconnected;
1060 kref_put(&hub->kref, hub_release);
1061 return;
1062 }
1063 if (type == HUB_INIT2) 1060 if (type == HUB_INIT2)
1064 goto init2; 1061 goto init2;
1065 goto init3; 1062 goto init3;
@@ -1281,12 +1278,12 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
1281 /* Scan all ports that need attention */ 1278 /* Scan all ports that need attention */
1282 kick_hub_wq(hub); 1279 kick_hub_wq(hub);
1283 1280
1284 /* Allow autosuspend if it was suppressed */ 1281 if (type == HUB_INIT2 || type == HUB_INIT3) {
1285 if (type <= HUB_INIT3) 1282 /* Allow autosuspend if it was suppressed */
1283 disconnected:
1286 usb_autopm_put_interface_async(to_usb_interface(hub->intfdev)); 1284 usb_autopm_put_interface_async(to_usb_interface(hub->intfdev));
1287
1288 if (type == HUB_INIT2 || type == HUB_INIT3)
1289 device_unlock(hub->intfdev); 1285 device_unlock(hub->intfdev);
1286 }
1290 1287
1291 kref_put(&hub->kref, hub_release); 1288 kref_put(&hub->kref, hub_release);
1292} 1289}