Skip to content

Commit eb6e292

Browse files
pmladekgregkh
authored andcommitted
usb: hub: rename hub_events() to hub_event() and handle only one event there
We would like to convert khubd kthread to a workqueue. As a result hub_events() will handle only one event per call. In fact, we could do this already now because there is another cycle in hub_thread(). It calls hub_events() until hub_event_list is empty. This patch renames the function to hub_event(), removes the while cycle, and renames the goto targets from loop* to out*. When touching the code, it fixes also formatting of dev_err() and dev_dbg() calls to make checkpatch.pl happy :-) Signed-off-by: Petr Mladek <[email protected]> Acked-by: Alan Stern <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 5d14f32 commit eb6e292

File tree

1 file changed

+111
-125
lines changed

1 file changed

+111
-125
lines changed

drivers/usb/core/hub.c

Lines changed: 111 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -4996,8 +4996,7 @@ static void port_event(struct usb_hub *hub, int port1)
49964996
hub_port_connect_change(hub, port1, portstatus, portchange);
49974997
}
49984998

4999-
5000-
static void hub_events(void)
4999+
static void hub_event(void)
50015000
{
50025001
struct list_head *tmp;
50035002
struct usb_device *hdev;
@@ -5008,144 +5007,131 @@ static void hub_events(void)
50085007
u16 hubchange;
50095008
int i, ret;
50105009

5011-
/*
5012-
* We restart the list every time to avoid a deadlock with
5013-
* deleting hubs downstream from this one. This should be
5014-
* safe since we delete the hub from the event list.
5015-
* Not the most efficient, but avoids deadlocks.
5016-
*/
5017-
while (1) {
5010+
/* Grab the first entry at the beginning of the list */
5011+
spin_lock_irq(&hub_event_lock);
5012+
if (list_empty(&hub_event_list)) {
5013+
spin_unlock_irq(&hub_event_lock);
5014+
return;
5015+
}
50185016

5019-
/* Grab the first entry at the beginning of the list */
5020-
spin_lock_irq(&hub_event_lock);
5021-
if (list_empty(&hub_event_list)) {
5022-
spin_unlock_irq(&hub_event_lock);
5023-
break;
5024-
}
5017+
tmp = hub_event_list.next;
5018+
list_del_init(tmp);
50255019

5026-
tmp = hub_event_list.next;
5027-
list_del_init(tmp);
5020+
hub = list_entry(tmp, struct usb_hub, event_list);
5021+
kref_get(&hub->kref);
5022+
spin_unlock_irq(&hub_event_lock);
50285023

5029-
hub = list_entry(tmp, struct usb_hub, event_list);
5030-
kref_get(&hub->kref);
5031-
spin_unlock_irq(&hub_event_lock);
5024+
hdev = hub->hdev;
5025+
hub_dev = hub->intfdev;
5026+
intf = to_usb_interface(hub_dev);
5027+
dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x\n",
5028+
hdev->state, hdev->maxchild,
5029+
/* NOTE: expects max 15 ports... */
5030+
(u16) hub->change_bits[0],
5031+
(u16) hub->event_bits[0]);
5032+
5033+
/* Lock the device, then check to see if we were
5034+
* disconnected while waiting for the lock to succeed. */
5035+
usb_lock_device(hdev);
5036+
if (unlikely(hub->disconnected))
5037+
goto out_disconnected;
5038+
5039+
/* If the hub has died, clean up after it */
5040+
if (hdev->state == USB_STATE_NOTATTACHED) {
5041+
hub->error = -ENODEV;
5042+
hub_quiesce(hub, HUB_DISCONNECT);
5043+
goto out;
5044+
}
5045+
5046+
/* Autoresume */
5047+
ret = usb_autopm_get_interface(intf);
5048+
if (ret) {
5049+
dev_dbg(hub_dev, "Can't autoresume: %d\n", ret);
5050+
goto out;
5051+
}
50325052

5033-
hdev = hub->hdev;
5034-
hub_dev = hub->intfdev;
5035-
intf = to_usb_interface(hub_dev);
5036-
dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x\n",
5037-
hdev->state, hdev->maxchild,
5038-
/* NOTE: expects max 15 ports... */
5039-
(u16) hub->change_bits[0],
5040-
(u16) hub->event_bits[0]);
5041-
5042-
/* Lock the device, then check to see if we were
5043-
* disconnected while waiting for the lock to succeed. */
5044-
usb_lock_device(hdev);
5045-
if (unlikely(hub->disconnected))
5046-
goto loop_disconnected;
5047-
5048-
/* If the hub has died, clean up after it */
5049-
if (hdev->state == USB_STATE_NOTATTACHED) {
5050-
hub->error = -ENODEV;
5051-
hub_quiesce(hub, HUB_DISCONNECT);
5052-
goto loop;
5053-
}
5053+
/* If this is an inactive hub, do nothing */
5054+
if (hub->quiescing)
5055+
goto out_autopm;
5056+
5057+
if (hub->error) {
5058+
dev_dbg(hub_dev, "resetting for error %d\n", hub->error);
50545059

5055-
/* Autoresume */
5056-
ret = usb_autopm_get_interface(intf);
5060+
ret = usb_reset_device(hdev);
50575061
if (ret) {
5058-
dev_dbg(hub_dev, "Can't autoresume: %d\n", ret);
5059-
goto loop;
5062+
dev_dbg(hub_dev, "error resetting hub: %d\n", ret);
5063+
goto out_autopm;
50605064
}
50615065

5062-
/* If this is an inactive hub, do nothing */
5063-
if (hub->quiescing)
5064-
goto loop_autopm;
5066+
hub->nerrors = 0;
5067+
hub->error = 0;
5068+
}
50655069

5066-
if (hub->error) {
5067-
dev_dbg (hub_dev, "resetting for error %d\n",
5068-
hub->error);
5070+
/* deal with port status changes */
5071+
for (i = 1; i <= hdev->maxchild; i++) {
5072+
struct usb_port *port_dev = hub->ports[i - 1];
50695073

5070-
ret = usb_reset_device(hdev);
5071-
if (ret) {
5072-
dev_dbg (hub_dev,
5073-
"error resetting hub: %d\n", ret);
5074-
goto loop_autopm;
5075-
}
5076-
5077-
hub->nerrors = 0;
5078-
hub->error = 0;
5074+
if (test_bit(i, hub->event_bits)
5075+
|| test_bit(i, hub->change_bits)
5076+
|| test_bit(i, hub->wakeup_bits)) {
5077+
/*
5078+
* The get_noresume and barrier ensure that if
5079+
* the port was in the process of resuming, we
5080+
* flush that work and keep the port active for
5081+
* the duration of the port_event(). However,
5082+
* if the port is runtime pm suspended
5083+
* (powered-off), we leave it in that state, run
5084+
* an abbreviated port_event(), and move on.
5085+
*/
5086+
pm_runtime_get_noresume(&port_dev->dev);
5087+
pm_runtime_barrier(&port_dev->dev);
5088+
usb_lock_port(port_dev);
5089+
port_event(hub, i);
5090+
usb_unlock_port(port_dev);
5091+
pm_runtime_put_sync(&port_dev->dev);
50795092
}
5093+
}
50805094

5081-
/* deal with port status changes */
5082-
for (i = 1; i <= hdev->maxchild; i++) {
5083-
struct usb_port *port_dev = hub->ports[i - 1];
5084-
5085-
if (test_bit(i, hub->event_bits)
5086-
|| test_bit(i, hub->change_bits)
5087-
|| test_bit(i, hub->wakeup_bits)) {
5088-
/*
5089-
* The get_noresume and barrier ensure that if
5090-
* the port was in the process of resuming, we
5091-
* flush that work and keep the port active for
5092-
* the duration of the port_event(). However,
5093-
* if the port is runtime pm suspended
5094-
* (powered-off), we leave it in that state, run
5095-
* an abbreviated port_event(), and move on.
5096-
*/
5097-
pm_runtime_get_noresume(&port_dev->dev);
5098-
pm_runtime_barrier(&port_dev->dev);
5099-
usb_lock_port(port_dev);
5100-
port_event(hub, i);
5101-
usb_unlock_port(port_dev);
5102-
pm_runtime_put_sync(&port_dev->dev);
5103-
}
5095+
/* deal with hub status changes */
5096+
if (test_and_clear_bit(0, hub->event_bits) == 0)
5097+
; /* do nothing */
5098+
else if (hub_hub_status(hub, &hubstatus, &hubchange) < 0)
5099+
dev_err(hub_dev, "get_hub_status failed\n");
5100+
else {
5101+
if (hubchange & HUB_CHANGE_LOCAL_POWER) {
5102+
dev_dbg(hub_dev, "power change\n");
5103+
clear_hub_feature(hdev, C_HUB_LOCAL_POWER);
5104+
if (hubstatus & HUB_STATUS_LOCAL_POWER)
5105+
/* FIXME: Is this always true? */
5106+
hub->limited_power = 1;
5107+
else
5108+
hub->limited_power = 0;
51045109
}
5110+
if (hubchange & HUB_CHANGE_OVERCURRENT) {
5111+
u16 status = 0;
5112+
u16 unused;
51055113

5106-
/* deal with hub status changes */
5107-
if (test_and_clear_bit(0, hub->event_bits) == 0)
5108-
; /* do nothing */
5109-
else if (hub_hub_status(hub, &hubstatus, &hubchange) < 0)
5110-
dev_err (hub_dev, "get_hub_status failed\n");
5111-
else {
5112-
if (hubchange & HUB_CHANGE_LOCAL_POWER) {
5113-
dev_dbg (hub_dev, "power change\n");
5114-
clear_hub_feature(hdev, C_HUB_LOCAL_POWER);
5115-
if (hubstatus & HUB_STATUS_LOCAL_POWER)
5116-
/* FIXME: Is this always true? */
5117-
hub->limited_power = 1;
5118-
else
5119-
hub->limited_power = 0;
5120-
}
5121-
if (hubchange & HUB_CHANGE_OVERCURRENT) {
5122-
u16 status = 0;
5123-
u16 unused;
5124-
5125-
dev_dbg(hub_dev, "over-current change\n");
5126-
clear_hub_feature(hdev, C_HUB_OVER_CURRENT);
5127-
msleep(500); /* Cool down */
5128-
hub_power_on(hub, true);
5129-
hub_hub_status(hub, &status, &unused);
5130-
if (status & HUB_STATUS_OVERCURRENT)
5131-
dev_err(hub_dev, "over-current "
5132-
"condition\n");
5133-
}
5114+
dev_dbg(hub_dev, "over-current change\n");
5115+
clear_hub_feature(hdev, C_HUB_OVER_CURRENT);
5116+
msleep(500); /* Cool down */
5117+
hub_power_on(hub, true);
5118+
hub_hub_status(hub, &status, &unused);
5119+
if (status & HUB_STATUS_OVERCURRENT)
5120+
dev_err(hub_dev, "over-current condition\n");
51345121
}
5122+
}
51355123

5136-
loop_autopm:
5137-
/* Balance the usb_autopm_get_interface() above */
5138-
usb_autopm_put_interface_no_suspend(intf);
5139-
loop:
5140-
/* Balance the usb_autopm_get_interface_no_resume() in
5141-
* kick_khubd() and allow autosuspend.
5142-
*/
5143-
usb_autopm_put_interface(intf);
5144-
loop_disconnected:
5145-
usb_unlock_device(hdev);
5146-
kref_put(&hub->kref, hub_release);
5147-
5148-
} /* end while (1) */
5124+
out_autopm:
5125+
/* Balance the usb_autopm_get_interface() above */
5126+
usb_autopm_put_interface_no_suspend(intf);
5127+
out:
5128+
/* Balance the usb_autopm_get_interface_no_resume() in
5129+
* kick_khubd() and allow autosuspend.
5130+
*/
5131+
usb_autopm_put_interface(intf);
5132+
out_disconnected:
5133+
usb_unlock_device(hdev);
5134+
kref_put(&hub->kref, hub_release);
51495135
}
51505136

51515137
static int hub_thread(void *__unused)
@@ -5158,7 +5144,7 @@ static int hub_thread(void *__unused)
51585144
set_freezable();
51595145

51605146
do {
5161-
hub_events();
5147+
hub_event();
51625148
wait_event_freezable(khubd_wait,
51635149
!list_empty(&hub_event_list) ||
51645150
kthread_should_stop());

0 commit comments

Comments
 (0)