Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <pmladek@suse.cz>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Petr Mladek and committed by
Greg Kroah-Hartman
eb6e2924 5d14f323

+111 -125
+111 -125
drivers/usb/core/hub.c
··· 4996 4996 hub_port_connect_change(hub, port1, portstatus, portchange); 4997 4997 } 4998 4998 4999 - 5000 - static void hub_events(void) 4999 + static void hub_event(void) 5001 5000 { 5002 5001 struct list_head *tmp; 5003 5002 struct usb_device *hdev; ··· 5007 5008 u16 hubchange; 5008 5009 int i, ret; 5009 5010 5010 - /* 5011 - * We restart the list every time to avoid a deadlock with 5012 - * deleting hubs downstream from this one. This should be 5013 - * safe since we delete the hub from the event list. 5014 - * Not the most efficient, but avoids deadlocks. 5015 - */ 5016 - while (1) { 5017 - 5018 - /* Grab the first entry at the beginning of the list */ 5019 - spin_lock_irq(&hub_event_lock); 5020 - if (list_empty(&hub_event_list)) { 5021 - spin_unlock_irq(&hub_event_lock); 5022 - break; 5023 - } 5024 - 5025 - tmp = hub_event_list.next; 5026 - list_del_init(tmp); 5027 - 5028 - hub = list_entry(tmp, struct usb_hub, event_list); 5029 - kref_get(&hub->kref); 5011 + /* Grab the first entry at the beginning of the list */ 5012 + spin_lock_irq(&hub_event_lock); 5013 + if (list_empty(&hub_event_list)) { 5030 5014 spin_unlock_irq(&hub_event_lock); 5015 + return; 5016 + } 5031 5017 5032 - hdev = hub->hdev; 5033 - hub_dev = hub->intfdev; 5034 - intf = to_usb_interface(hub_dev); 5035 - dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x\n", 5036 - hdev->state, hdev->maxchild, 5037 - /* NOTE: expects max 15 ports... */ 5038 - (u16) hub->change_bits[0], 5039 - (u16) hub->event_bits[0]); 5018 + tmp = hub_event_list.next; 5019 + list_del_init(tmp); 5040 5020 5041 - /* Lock the device, then check to see if we were 5042 - * disconnected while waiting for the lock to succeed. */ 5043 - usb_lock_device(hdev); 5044 - if (unlikely(hub->disconnected)) 5045 - goto loop_disconnected; 5021 + hub = list_entry(tmp, struct usb_hub, event_list); 5022 + kref_get(&hub->kref); 5023 + spin_unlock_irq(&hub_event_lock); 5046 5024 5047 - /* If the hub has died, clean up after it */ 5048 - if (hdev->state == USB_STATE_NOTATTACHED) { 5049 - hub->error = -ENODEV; 5050 - hub_quiesce(hub, HUB_DISCONNECT); 5051 - goto loop; 5052 - } 5025 + hdev = hub->hdev; 5026 + hub_dev = hub->intfdev; 5027 + intf = to_usb_interface(hub_dev); 5028 + dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x\n", 5029 + hdev->state, hdev->maxchild, 5030 + /* NOTE: expects max 15 ports... */ 5031 + (u16) hub->change_bits[0], 5032 + (u16) hub->event_bits[0]); 5053 5033 5054 - /* Autoresume */ 5055 - ret = usb_autopm_get_interface(intf); 5034 + /* Lock the device, then check to see if we were 5035 + * disconnected while waiting for the lock to succeed. */ 5036 + usb_lock_device(hdev); 5037 + if (unlikely(hub->disconnected)) 5038 + goto out_disconnected; 5039 + 5040 + /* If the hub has died, clean up after it */ 5041 + if (hdev->state == USB_STATE_NOTATTACHED) { 5042 + hub->error = -ENODEV; 5043 + hub_quiesce(hub, HUB_DISCONNECT); 5044 + goto out; 5045 + } 5046 + 5047 + /* Autoresume */ 5048 + ret = usb_autopm_get_interface(intf); 5049 + if (ret) { 5050 + dev_dbg(hub_dev, "Can't autoresume: %d\n", ret); 5051 + goto out; 5052 + } 5053 + 5054 + /* If this is an inactive hub, do nothing */ 5055 + if (hub->quiescing) 5056 + goto out_autopm; 5057 + 5058 + if (hub->error) { 5059 + dev_dbg(hub_dev, "resetting for error %d\n", hub->error); 5060 + 5061 + ret = usb_reset_device(hdev); 5056 5062 if (ret) { 5057 - dev_dbg(hub_dev, "Can't autoresume: %d\n", ret); 5058 - goto loop; 5063 + dev_dbg(hub_dev, "error resetting hub: %d\n", ret); 5064 + goto out_autopm; 5059 5065 } 5060 5066 5061 - /* If this is an inactive hub, do nothing */ 5062 - if (hub->quiescing) 5063 - goto loop_autopm; 5067 + hub->nerrors = 0; 5068 + hub->error = 0; 5069 + } 5064 5070 5065 - if (hub->error) { 5066 - dev_dbg (hub_dev, "resetting for error %d\n", 5067 - hub->error); 5071 + /* deal with port status changes */ 5072 + for (i = 1; i <= hdev->maxchild; i++) { 5073 + struct usb_port *port_dev = hub->ports[i - 1]; 5068 5074 5069 - ret = usb_reset_device(hdev); 5070 - if (ret) { 5071 - dev_dbg (hub_dev, 5072 - "error resetting hub: %d\n", ret); 5073 - goto loop_autopm; 5074 - } 5075 - 5076 - hub->nerrors = 0; 5077 - hub->error = 0; 5075 + if (test_bit(i, hub->event_bits) 5076 + || test_bit(i, hub->change_bits) 5077 + || test_bit(i, hub->wakeup_bits)) { 5078 + /* 5079 + * The get_noresume and barrier ensure that if 5080 + * the port was in the process of resuming, we 5081 + * flush that work and keep the port active for 5082 + * the duration of the port_event(). However, 5083 + * if the port is runtime pm suspended 5084 + * (powered-off), we leave it in that state, run 5085 + * an abbreviated port_event(), and move on. 5086 + */ 5087 + pm_runtime_get_noresume(&port_dev->dev); 5088 + pm_runtime_barrier(&port_dev->dev); 5089 + usb_lock_port(port_dev); 5090 + port_event(hub, i); 5091 + usb_unlock_port(port_dev); 5092 + pm_runtime_put_sync(&port_dev->dev); 5078 5093 } 5094 + } 5079 5095 5080 - /* deal with port status changes */ 5081 - for (i = 1; i <= hdev->maxchild; i++) { 5082 - struct usb_port *port_dev = hub->ports[i - 1]; 5083 - 5084 - if (test_bit(i, hub->event_bits) 5085 - || test_bit(i, hub->change_bits) 5086 - || test_bit(i, hub->wakeup_bits)) { 5087 - /* 5088 - * The get_noresume and barrier ensure that if 5089 - * the port was in the process of resuming, we 5090 - * flush that work and keep the port active for 5091 - * the duration of the port_event(). However, 5092 - * if the port is runtime pm suspended 5093 - * (powered-off), we leave it in that state, run 5094 - * an abbreviated port_event(), and move on. 5095 - */ 5096 - pm_runtime_get_noresume(&port_dev->dev); 5097 - pm_runtime_barrier(&port_dev->dev); 5098 - usb_lock_port(port_dev); 5099 - port_event(hub, i); 5100 - usb_unlock_port(port_dev); 5101 - pm_runtime_put_sync(&port_dev->dev); 5102 - } 5096 + /* deal with hub status changes */ 5097 + if (test_and_clear_bit(0, hub->event_bits) == 0) 5098 + ; /* do nothing */ 5099 + else if (hub_hub_status(hub, &hubstatus, &hubchange) < 0) 5100 + dev_err(hub_dev, "get_hub_status failed\n"); 5101 + else { 5102 + if (hubchange & HUB_CHANGE_LOCAL_POWER) { 5103 + dev_dbg(hub_dev, "power change\n"); 5104 + clear_hub_feature(hdev, C_HUB_LOCAL_POWER); 5105 + if (hubstatus & HUB_STATUS_LOCAL_POWER) 5106 + /* FIXME: Is this always true? */ 5107 + hub->limited_power = 1; 5108 + else 5109 + hub->limited_power = 0; 5103 5110 } 5111 + if (hubchange & HUB_CHANGE_OVERCURRENT) { 5112 + u16 status = 0; 5113 + u16 unused; 5104 5114 5105 - /* deal with hub status changes */ 5106 - if (test_and_clear_bit(0, hub->event_bits) == 0) 5107 - ; /* do nothing */ 5108 - else if (hub_hub_status(hub, &hubstatus, &hubchange) < 0) 5109 - dev_err (hub_dev, "get_hub_status failed\n"); 5110 - else { 5111 - if (hubchange & HUB_CHANGE_LOCAL_POWER) { 5112 - dev_dbg (hub_dev, "power change\n"); 5113 - clear_hub_feature(hdev, C_HUB_LOCAL_POWER); 5114 - if (hubstatus & HUB_STATUS_LOCAL_POWER) 5115 - /* FIXME: Is this always true? */ 5116 - hub->limited_power = 1; 5117 - else 5118 - hub->limited_power = 0; 5119 - } 5120 - if (hubchange & HUB_CHANGE_OVERCURRENT) { 5121 - u16 status = 0; 5122 - u16 unused; 5123 - 5124 - dev_dbg(hub_dev, "over-current change\n"); 5125 - clear_hub_feature(hdev, C_HUB_OVER_CURRENT); 5126 - msleep(500); /* Cool down */ 5127 - hub_power_on(hub, true); 5128 - hub_hub_status(hub, &status, &unused); 5129 - if (status & HUB_STATUS_OVERCURRENT) 5130 - dev_err(hub_dev, "over-current " 5131 - "condition\n"); 5132 - } 5115 + dev_dbg(hub_dev, "over-current change\n"); 5116 + clear_hub_feature(hdev, C_HUB_OVER_CURRENT); 5117 + msleep(500); /* Cool down */ 5118 + hub_power_on(hub, true); 5119 + hub_hub_status(hub, &status, &unused); 5120 + if (status & HUB_STATUS_OVERCURRENT) 5121 + dev_err(hub_dev, "over-current condition\n"); 5133 5122 } 5123 + } 5134 5124 5135 - loop_autopm: 5136 - /* Balance the usb_autopm_get_interface() above */ 5137 - usb_autopm_put_interface_no_suspend(intf); 5138 - loop: 5139 - /* Balance the usb_autopm_get_interface_no_resume() in 5140 - * kick_khubd() and allow autosuspend. 5141 - */ 5142 - usb_autopm_put_interface(intf); 5143 - loop_disconnected: 5144 - usb_unlock_device(hdev); 5145 - kref_put(&hub->kref, hub_release); 5146 - 5147 - } /* end while (1) */ 5125 + out_autopm: 5126 + /* Balance the usb_autopm_get_interface() above */ 5127 + usb_autopm_put_interface_no_suspend(intf); 5128 + out: 5129 + /* Balance the usb_autopm_get_interface_no_resume() in 5130 + * kick_khubd() and allow autosuspend. 5131 + */ 5132 + usb_autopm_put_interface(intf); 5133 + out_disconnected: 5134 + usb_unlock_device(hdev); 5135 + kref_put(&hub->kref, hub_release); 5148 5136 } 5149 5137 5150 5138 static int hub_thread(void *__unused) ··· 5144 5158 set_freezable(); 5145 5159 5146 5160 do { 5147 - hub_events(); 5161 + hub_event(); 5148 5162 wait_event_freezable(khubd_wait, 5149 5163 !list_empty(&hub_event_list) || 5150 5164 kthread_should_stop());