diff options
author | Jiri Kosina <jkosina@suse.cz> | 2009-03-30 09:14:53 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2009-03-30 09:14:53 -0400 |
commit | 621de593081524da2f0f7b060f5951b4155eb4a2 (patch) | |
tree | dcb1777094498496a3036b0e49546887e72d6a06 /drivers | |
parent | afa5eb7c68689ced4284f01c96feed44a2d0a127 (diff) | |
parent | 6d77976800c3f29a0337fadcc9ddd79050fa5620 (diff) |
Merge branch 'autosuspend' into for-next
Conflicts:
drivers/hid/hid-core.c
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/hid/hid-core.c | 16 | ||||
-rw-r--r-- | drivers/hid/hidraw.c | 17 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-core.c | 472 | ||||
-rw-r--r-- | drivers/hid/usbhid/hiddev.c | 17 | ||||
-rw-r--r-- | drivers/hid/usbhid/usbhid.h | 14 |
5 files changed, 422 insertions, 114 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index e56f8d5d3a50..5746a5903bce 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -1819,6 +1819,22 @@ void hid_unregister_driver(struct hid_driver *hdrv) | |||
1819 | } | 1819 | } |
1820 | EXPORT_SYMBOL_GPL(hid_unregister_driver); | 1820 | EXPORT_SYMBOL_GPL(hid_unregister_driver); |
1821 | 1821 | ||
1822 | int hid_check_keys_pressed(struct hid_device *hid) | ||
1823 | { | ||
1824 | struct hid_input *hidinput; | ||
1825 | int i; | ||
1826 | |||
1827 | list_for_each_entry(hidinput, &hid->inputs, list) { | ||
1828 | for (i = 0; i < BITS_TO_LONGS(KEY_MAX); i++) | ||
1829 | if (hidinput->input->key[i]) | ||
1830 | return 1; | ||
1831 | } | ||
1832 | |||
1833 | return 0; | ||
1834 | } | ||
1835 | |||
1836 | EXPORT_SYMBOL_GPL(hid_check_keys_pressed); | ||
1837 | |||
1822 | static int __init hid_init(void) | 1838 | static int __init hid_init(void) |
1823 | { | 1839 | { |
1824 | int ret; | 1840 | int ret; |
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index 02b19db5442e..e263d4731179 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c | |||
@@ -181,9 +181,17 @@ static int hidraw_open(struct inode *inode, struct file *file) | |||
181 | 181 | ||
182 | dev = hidraw_table[minor]; | 182 | dev = hidraw_table[minor]; |
183 | if (!dev->open++) { | 183 | if (!dev->open++) { |
184 | if (dev->hid->ll_driver->power) { | ||
185 | err = dev->hid->ll_driver->power(dev->hid, PM_HINT_FULLON); | ||
186 | if (err < 0) | ||
187 | goto out_unlock; | ||
188 | } | ||
184 | err = dev->hid->ll_driver->open(dev->hid); | 189 | err = dev->hid->ll_driver->open(dev->hid); |
185 | if (err < 0) | 190 | if (err < 0) { |
191 | if (dev->hid->ll_driver->power) | ||
192 | dev->hid->ll_driver->power(dev->hid, PM_HINT_NORMAL); | ||
186 | dev->open--; | 193 | dev->open--; |
194 | } | ||
187 | } | 195 | } |
188 | 196 | ||
189 | out_unlock: | 197 | out_unlock: |
@@ -209,10 +217,13 @@ static int hidraw_release(struct inode * inode, struct file * file) | |||
209 | list_del(&list->node); | 217 | list_del(&list->node); |
210 | dev = hidraw_table[minor]; | 218 | dev = hidraw_table[minor]; |
211 | if (!--dev->open) { | 219 | if (!--dev->open) { |
212 | if (list->hidraw->exist) | 220 | if (list->hidraw->exist) { |
221 | if (dev->hid->ll_driver->power) | ||
222 | dev->hid->ll_driver->power(dev->hid, PM_HINT_NORMAL); | ||
213 | dev->hid->ll_driver->close(dev->hid); | 223 | dev->hid->ll_driver->close(dev->hid); |
214 | else | 224 | } else { |
215 | kfree(list->hidraw); | 225 | kfree(list->hidraw); |
226 | } | ||
216 | } | 227 | } |
217 | 228 | ||
218 | kfree(list); | 229 | kfree(list); |
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index eed05a3017e5..4306cb1b8ce5 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c | |||
@@ -5,6 +5,7 @@ | |||
5 | * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> | 5 | * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> |
6 | * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc | 6 | * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc |
7 | * Copyright (c) 2006-2008 Jiri Kosina | 7 | * Copyright (c) 2006-2008 Jiri Kosina |
8 | * Copyright (c) 2007-2008 Oliver Neukum | ||
8 | */ | 9 | */ |
9 | 10 | ||
10 | /* | 11 | /* |
@@ -27,6 +28,7 @@ | |||
27 | #include <asm/byteorder.h> | 28 | #include <asm/byteorder.h> |
28 | #include <linux/input.h> | 29 | #include <linux/input.h> |
29 | #include <linux/wait.h> | 30 | #include <linux/wait.h> |
31 | #include <linux/workqueue.h> | ||
30 | 32 | ||
31 | #include <linux/usb.h> | 33 | #include <linux/usb.h> |
32 | 34 | ||
@@ -53,6 +55,10 @@ static unsigned int hid_mousepoll_interval; | |||
53 | module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644); | 55 | module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644); |
54 | MODULE_PARM_DESC(mousepoll, "Polling interval of mice"); | 56 | MODULE_PARM_DESC(mousepoll, "Polling interval of mice"); |
55 | 57 | ||
58 | static unsigned int ignoreled; | ||
59 | module_param_named(ignoreled, ignoreled, uint, 0644); | ||
60 | MODULE_PARM_DESC(ignoreled, "Autosuspend with active leds"); | ||
61 | |||
56 | /* Quirks specified at module load time */ | 62 | /* Quirks specified at module load time */ |
57 | static char *quirks_param[MAX_USBHID_BOOT_QUIRKS] = { [ 0 ... (MAX_USBHID_BOOT_QUIRKS - 1) ] = NULL }; | 63 | static char *quirks_param[MAX_USBHID_BOOT_QUIRKS] = { [ 0 ... (MAX_USBHID_BOOT_QUIRKS - 1) ] = NULL }; |
58 | module_param_array_named(quirks, quirks_param, charp, NULL, 0444); | 64 | module_param_array_named(quirks, quirks_param, charp, NULL, 0444); |
@@ -63,8 +69,13 @@ MODULE_PARM_DESC(quirks, "Add/modify USB HID quirks by specifying " | |||
63 | /* | 69 | /* |
64 | * Input submission and I/O error handler. | 70 | * Input submission and I/O error handler. |
65 | */ | 71 | */ |
72 | static DEFINE_MUTEX(hid_open_mut); | ||
73 | static struct workqueue_struct *resumption_waker; | ||
66 | 74 | ||
67 | static void hid_io_error(struct hid_device *hid); | 75 | static void hid_io_error(struct hid_device *hid); |
76 | static int hid_submit_out(struct hid_device *hid); | ||
77 | static int hid_submit_ctrl(struct hid_device *hid); | ||
78 | static void hid_cancel_delayed_stuff(struct usbhid_device *usbhid); | ||
68 | 79 | ||
69 | /* Start up the input URB */ | 80 | /* Start up the input URB */ |
70 | static int hid_start_in(struct hid_device *hid) | 81 | static int hid_start_in(struct hid_device *hid) |
@@ -73,15 +84,16 @@ static int hid_start_in(struct hid_device *hid) | |||
73 | int rc = 0; | 84 | int rc = 0; |
74 | struct usbhid_device *usbhid = hid->driver_data; | 85 | struct usbhid_device *usbhid = hid->driver_data; |
75 | 86 | ||
76 | spin_lock_irqsave(&usbhid->inlock, flags); | 87 | spin_lock_irqsave(&usbhid->lock, flags); |
77 | if (hid->open > 0 && !test_bit(HID_SUSPENDED, &usbhid->iofl) && | 88 | if (hid->open > 0 && |
78 | !test_bit(HID_DISCONNECTED, &usbhid->iofl) && | 89 | !test_bit(HID_DISCONNECTED, &usbhid->iofl) && |
90 | !test_bit(HID_REPORTED_IDLE, &usbhid->iofl) && | ||
79 | !test_and_set_bit(HID_IN_RUNNING, &usbhid->iofl)) { | 91 | !test_and_set_bit(HID_IN_RUNNING, &usbhid->iofl)) { |
80 | rc = usb_submit_urb(usbhid->urbin, GFP_ATOMIC); | 92 | rc = usb_submit_urb(usbhid->urbin, GFP_ATOMIC); |
81 | if (rc != 0) | 93 | if (rc != 0) |
82 | clear_bit(HID_IN_RUNNING, &usbhid->iofl); | 94 | clear_bit(HID_IN_RUNNING, &usbhid->iofl); |
83 | } | 95 | } |
84 | spin_unlock_irqrestore(&usbhid->inlock, flags); | 96 | spin_unlock_irqrestore(&usbhid->lock, flags); |
85 | return rc; | 97 | return rc; |
86 | } | 98 | } |
87 | 99 | ||
@@ -145,7 +157,7 @@ static void hid_io_error(struct hid_device *hid) | |||
145 | unsigned long flags; | 157 | unsigned long flags; |
146 | struct usbhid_device *usbhid = hid->driver_data; | 158 | struct usbhid_device *usbhid = hid->driver_data; |
147 | 159 | ||
148 | spin_lock_irqsave(&usbhid->inlock, flags); | 160 | spin_lock_irqsave(&usbhid->lock, flags); |
149 | 161 | ||
150 | /* Stop when disconnected */ | 162 | /* Stop when disconnected */ |
151 | if (test_bit(HID_DISCONNECTED, &usbhid->iofl)) | 163 | if (test_bit(HID_DISCONNECTED, &usbhid->iofl)) |
@@ -175,7 +187,51 @@ static void hid_io_error(struct hid_device *hid) | |||
175 | mod_timer(&usbhid->io_retry, | 187 | mod_timer(&usbhid->io_retry, |
176 | jiffies + msecs_to_jiffies(usbhid->retry_delay)); | 188 | jiffies + msecs_to_jiffies(usbhid->retry_delay)); |
177 | done: | 189 | done: |
178 | spin_unlock_irqrestore(&usbhid->inlock, flags); | 190 | spin_unlock_irqrestore(&usbhid->lock, flags); |
191 | } | ||
192 | |||
193 | static void usbhid_mark_busy(struct usbhid_device *usbhid) | ||
194 | { | ||
195 | struct usb_interface *intf = usbhid->intf; | ||
196 | |||
197 | usb_mark_last_busy(interface_to_usbdev(intf)); | ||
198 | } | ||
199 | |||
200 | static int usbhid_restart_out_queue(struct usbhid_device *usbhid) | ||
201 | { | ||
202 | struct hid_device *hid = usb_get_intfdata(usbhid->intf); | ||
203 | int kicked; | ||
204 | |||
205 | if (!hid) | ||
206 | return 0; | ||
207 | |||
208 | if ((kicked = (usbhid->outhead != usbhid->outtail))) { | ||
209 | dbg("Kicking head %d tail %d", usbhid->outhead, usbhid->outtail); | ||
210 | if (hid_submit_out(hid)) { | ||
211 | clear_bit(HID_OUT_RUNNING, &usbhid->iofl); | ||
212 | wake_up(&usbhid->wait); | ||
213 | } | ||
214 | } | ||
215 | return kicked; | ||
216 | } | ||
217 | |||
218 | static int usbhid_restart_ctrl_queue(struct usbhid_device *usbhid) | ||
219 | { | ||
220 | struct hid_device *hid = usb_get_intfdata(usbhid->intf); | ||
221 | int kicked; | ||
222 | |||
223 | WARN_ON(hid == NULL); | ||
224 | if (!hid) | ||
225 | return 0; | ||
226 | |||
227 | if ((kicked = (usbhid->ctrlhead != usbhid->ctrltail))) { | ||
228 | dbg("Kicking head %d tail %d", usbhid->ctrlhead, usbhid->ctrltail); | ||
229 | if (hid_submit_ctrl(hid)) { | ||
230 | clear_bit(HID_CTRL_RUNNING, &usbhid->iofl); | ||
231 | wake_up(&usbhid->wait); | ||
232 | } | ||
233 | } | ||
234 | return kicked; | ||
179 | } | 235 | } |
180 | 236 | ||
181 | /* | 237 | /* |
@@ -190,12 +246,23 @@ static void hid_irq_in(struct urb *urb) | |||
190 | 246 | ||
191 | switch (urb->status) { | 247 | switch (urb->status) { |
192 | case 0: /* success */ | 248 | case 0: /* success */ |
249 | usbhid_mark_busy(usbhid); | ||
193 | usbhid->retry_delay = 0; | 250 | usbhid->retry_delay = 0; |
194 | hid_input_report(urb->context, HID_INPUT_REPORT, | 251 | hid_input_report(urb->context, HID_INPUT_REPORT, |
195 | urb->transfer_buffer, | 252 | urb->transfer_buffer, |
196 | urb->actual_length, 1); | 253 | urb->actual_length, 1); |
254 | /* | ||
255 | * autosuspend refused while keys are pressed | ||
256 | * because most keyboards don't wake up when | ||
257 | * a key is released | ||
258 | */ | ||
259 | if (hid_check_keys_pressed(hid)) | ||
260 | set_bit(HID_KEYS_PRESSED, &usbhid->iofl); | ||
261 | else | ||
262 | clear_bit(HID_KEYS_PRESSED, &usbhid->iofl); | ||
197 | break; | 263 | break; |
198 | case -EPIPE: /* stall */ | 264 | case -EPIPE: /* stall */ |
265 | usbhid_mark_busy(usbhid); | ||
199 | clear_bit(HID_IN_RUNNING, &usbhid->iofl); | 266 | clear_bit(HID_IN_RUNNING, &usbhid->iofl); |
200 | set_bit(HID_CLEAR_HALT, &usbhid->iofl); | 267 | set_bit(HID_CLEAR_HALT, &usbhid->iofl); |
201 | schedule_work(&usbhid->reset_work); | 268 | schedule_work(&usbhid->reset_work); |
@@ -209,6 +276,7 @@ static void hid_irq_in(struct urb *urb) | |||
209 | case -EPROTO: /* protocol error or unplug */ | 276 | case -EPROTO: /* protocol error or unplug */ |
210 | case -ETIME: /* protocol error or unplug */ | 277 | case -ETIME: /* protocol error or unplug */ |
211 | case -ETIMEDOUT: /* Should never happen, but... */ | 278 | case -ETIMEDOUT: /* Should never happen, but... */ |
279 | usbhid_mark_busy(usbhid); | ||
212 | clear_bit(HID_IN_RUNNING, &usbhid->iofl); | 280 | clear_bit(HID_IN_RUNNING, &usbhid->iofl); |
213 | hid_io_error(hid); | 281 | hid_io_error(hid); |
214 | return; | 282 | return; |
@@ -239,16 +307,25 @@ static int hid_submit_out(struct hid_device *hid) | |||
239 | report = usbhid->out[usbhid->outtail].report; | 307 | report = usbhid->out[usbhid->outtail].report; |
240 | raw_report = usbhid->out[usbhid->outtail].raw_report; | 308 | raw_report = usbhid->out[usbhid->outtail].raw_report; |
241 | 309 | ||
242 | usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0); | 310 | if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) { |
243 | usbhid->urbout->dev = hid_to_usb_dev(hid); | 311 | usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0); |
244 | memcpy(usbhid->outbuf, raw_report, usbhid->urbout->transfer_buffer_length); | 312 | usbhid->urbout->dev = hid_to_usb_dev(hid); |
245 | kfree(raw_report); | 313 | memcpy(usbhid->outbuf, raw_report, usbhid->urbout->transfer_buffer_length); |
314 | kfree(raw_report); | ||
246 | 315 | ||
247 | dbg_hid("submitting out urb\n"); | 316 | dbg_hid("submitting out urb\n"); |
248 | 317 | ||
249 | if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) { | 318 | if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) { |
250 | err_hid("usb_submit_urb(out) failed"); | 319 | err_hid("usb_submit_urb(out) failed"); |
251 | return -1; | 320 | return -1; |
321 | } | ||
322 | } else { | ||
323 | /* | ||
324 | * queue work to wake up the device. | ||
325 | * as the work queue is freezeable, this is safe | ||
326 | * with respect to STD and STR | ||
327 | */ | ||
328 | queue_work(resumption_waker, &usbhid->restart_work); | ||
252 | } | 329 | } |
253 | 330 | ||
254 | return 0; | 331 | return 0; |
@@ -266,41 +343,50 @@ static int hid_submit_ctrl(struct hid_device *hid) | |||
266 | raw_report = usbhid->ctrl[usbhid->ctrltail].raw_report; | 343 | raw_report = usbhid->ctrl[usbhid->ctrltail].raw_report; |
267 | dir = usbhid->ctrl[usbhid->ctrltail].dir; | 344 | dir = usbhid->ctrl[usbhid->ctrltail].dir; |
268 | 345 | ||
269 | len = ((report->size - 1) >> 3) + 1 + (report->id > 0); | 346 | if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) { |
270 | if (dir == USB_DIR_OUT) { | 347 | len = ((report->size - 1) >> 3) + 1 + (report->id > 0); |
271 | usbhid->urbctrl->pipe = usb_sndctrlpipe(hid_to_usb_dev(hid), 0); | 348 | if (dir == USB_DIR_OUT) { |
272 | usbhid->urbctrl->transfer_buffer_length = len; | 349 | usbhid->urbctrl->pipe = usb_sndctrlpipe(hid_to_usb_dev(hid), 0); |
273 | memcpy(usbhid->ctrlbuf, raw_report, len); | 350 | usbhid->urbctrl->transfer_buffer_length = len; |
274 | kfree(raw_report); | 351 | memcpy(usbhid->ctrlbuf, raw_report, len); |
275 | } else { | 352 | kfree(raw_report); |
276 | int maxpacket, padlen; | 353 | } else { |
277 | 354 | int maxpacket, padlen; | |
278 | usbhid->urbctrl->pipe = usb_rcvctrlpipe(hid_to_usb_dev(hid), 0); | 355 | |
279 | maxpacket = usb_maxpacket(hid_to_usb_dev(hid), usbhid->urbctrl->pipe, 0); | 356 | usbhid->urbctrl->pipe = usb_rcvctrlpipe(hid_to_usb_dev(hid), 0); |
280 | if (maxpacket > 0) { | 357 | maxpacket = usb_maxpacket(hid_to_usb_dev(hid), usbhid->urbctrl->pipe, 0); |
281 | padlen = DIV_ROUND_UP(len, maxpacket); | 358 | if (maxpacket > 0) { |
282 | padlen *= maxpacket; | 359 | padlen = DIV_ROUND_UP(len, maxpacket); |
283 | if (padlen > usbhid->bufsize) | 360 | padlen *= maxpacket; |
284 | padlen = usbhid->bufsize; | 361 | if (padlen > usbhid->bufsize) |
285 | } else | 362 | padlen = usbhid->bufsize; |
286 | padlen = 0; | 363 | } else |
287 | usbhid->urbctrl->transfer_buffer_length = padlen; | 364 | padlen = 0; |
288 | } | 365 | usbhid->urbctrl->transfer_buffer_length = padlen; |
289 | usbhid->urbctrl->dev = hid_to_usb_dev(hid); | 366 | } |
367 | usbhid->urbctrl->dev = hid_to_usb_dev(hid); | ||
290 | 368 | ||
291 | usbhid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir; | 369 | usbhid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir; |
292 | usbhid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT; | 370 | usbhid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT; |
293 | usbhid->cr->wValue = cpu_to_le16(((report->type + 1) << 8) | report->id); | 371 | usbhid->cr->wValue = cpu_to_le16(((report->type + 1) << 8) | report->id); |
294 | usbhid->cr->wIndex = cpu_to_le16(usbhid->ifnum); | 372 | usbhid->cr->wIndex = cpu_to_le16(usbhid->ifnum); |
295 | usbhid->cr->wLength = cpu_to_le16(len); | 373 | usbhid->cr->wLength = cpu_to_le16(len); |
296 | 374 | ||
297 | dbg_hid("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u\n", | 375 | dbg_hid("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u\n", |
298 | usbhid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report", | 376 | usbhid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report", |
299 | usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength); | 377 | usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength); |
300 | 378 | ||
301 | if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) { | 379 | if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) { |
302 | err_hid("usb_submit_urb(ctrl) failed"); | 380 | err_hid("usb_submit_urb(ctrl) failed"); |
303 | return -1; | 381 | return -1; |
382 | } | ||
383 | } else { | ||
384 | /* | ||
385 | * queue work to wake up the device. | ||
386 | * as the work queue is freezeable, this is safe | ||
387 | * with respect to STD and STR | ||
388 | */ | ||
389 | queue_work(resumption_waker, &usbhid->restart_work); | ||
304 | } | 390 | } |
305 | 391 | ||
306 | return 0; | 392 | return 0; |
@@ -332,7 +418,7 @@ static void hid_irq_out(struct urb *urb) | |||
332 | "received\n", urb->status); | 418 | "received\n", urb->status); |
333 | } | 419 | } |
334 | 420 | ||
335 | spin_lock_irqsave(&usbhid->outlock, flags); | 421 | spin_lock_irqsave(&usbhid->lock, flags); |
336 | 422 | ||
337 | if (unplug) | 423 | if (unplug) |
338 | usbhid->outtail = usbhid->outhead; | 424 | usbhid->outtail = usbhid->outhead; |
@@ -344,12 +430,12 @@ static void hid_irq_out(struct urb *urb) | |||
344 | clear_bit(HID_OUT_RUNNING, &usbhid->iofl); | 430 | clear_bit(HID_OUT_RUNNING, &usbhid->iofl); |
345 | wake_up(&usbhid->wait); | 431 | wake_up(&usbhid->wait); |
346 | } | 432 | } |
347 | spin_unlock_irqrestore(&usbhid->outlock, flags); | 433 | spin_unlock_irqrestore(&usbhid->lock, flags); |
348 | return; | 434 | return; |
349 | } | 435 | } |
350 | 436 | ||
351 | clear_bit(HID_OUT_RUNNING, &usbhid->iofl); | 437 | clear_bit(HID_OUT_RUNNING, &usbhid->iofl); |
352 | spin_unlock_irqrestore(&usbhid->outlock, flags); | 438 | spin_unlock_irqrestore(&usbhid->lock, flags); |
353 | wake_up(&usbhid->wait); | 439 | wake_up(&usbhid->wait); |
354 | } | 440 | } |
355 | 441 | ||
@@ -361,12 +447,11 @@ static void hid_ctrl(struct urb *urb) | |||
361 | { | 447 | { |
362 | struct hid_device *hid = urb->context; | 448 | struct hid_device *hid = urb->context; |
363 | struct usbhid_device *usbhid = hid->driver_data; | 449 | struct usbhid_device *usbhid = hid->driver_data; |
364 | unsigned long flags; | 450 | int unplug = 0, status = urb->status; |
365 | int unplug = 0; | ||
366 | 451 | ||
367 | spin_lock_irqsave(&usbhid->ctrllock, flags); | 452 | spin_lock(&usbhid->lock); |
368 | 453 | ||
369 | switch (urb->status) { | 454 | switch (status) { |
370 | case 0: /* success */ | 455 | case 0: /* success */ |
371 | if (usbhid->ctrl[usbhid->ctrltail].dir == USB_DIR_IN) | 456 | if (usbhid->ctrl[usbhid->ctrltail].dir == USB_DIR_IN) |
372 | hid_input_report(urb->context, | 457 | hid_input_report(urb->context, |
@@ -383,7 +468,7 @@ static void hid_ctrl(struct urb *urb) | |||
383 | break; | 468 | break; |
384 | default: /* error */ | 469 | default: /* error */ |
385 | dev_warn(&urb->dev->dev, "ctrl urb status %d " | 470 | dev_warn(&urb->dev->dev, "ctrl urb status %d " |
386 | "received\n", urb->status); | 471 | "received\n", status); |
387 | } | 472 | } |
388 | 473 | ||
389 | if (unplug) | 474 | if (unplug) |
@@ -396,19 +481,18 @@ static void hid_ctrl(struct urb *urb) | |||
396 | clear_bit(HID_CTRL_RUNNING, &usbhid->iofl); | 481 | clear_bit(HID_CTRL_RUNNING, &usbhid->iofl); |
397 | wake_up(&usbhid->wait); | 482 | wake_up(&usbhid->wait); |
398 | } | 483 | } |
399 | spin_unlock_irqrestore(&usbhid->ctrllock, flags); | 484 | spin_unlock(&usbhid->lock); |
400 | return; | 485 | return; |
401 | } | 486 | } |
402 | 487 | ||
403 | clear_bit(HID_CTRL_RUNNING, &usbhid->iofl); | 488 | clear_bit(HID_CTRL_RUNNING, &usbhid->iofl); |
404 | spin_unlock_irqrestore(&usbhid->ctrllock, flags); | 489 | spin_unlock(&usbhid->lock); |
405 | wake_up(&usbhid->wait); | 490 | wake_up(&usbhid->wait); |
406 | } | 491 | } |
407 | 492 | ||
408 | void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir) | 493 | void __usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir) |
409 | { | 494 | { |
410 | int head; | 495 | int head; |
411 | unsigned long flags; | ||
412 | struct usbhid_device *usbhid = hid->driver_data; | 496 | struct usbhid_device *usbhid = hid->driver_data; |
413 | int len = ((report->size - 1) >> 3) + 1 + (report->id > 0); | 497 | int len = ((report->size - 1) >> 3) + 1 + (report->id > 0); |
414 | 498 | ||
@@ -416,18 +500,13 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns | |||
416 | return; | 500 | return; |
417 | 501 | ||
418 | if (usbhid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) { | 502 | if (usbhid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) { |
419 | |||
420 | spin_lock_irqsave(&usbhid->outlock, flags); | ||
421 | |||
422 | if ((head = (usbhid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == usbhid->outtail) { | 503 | if ((head = (usbhid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == usbhid->outtail) { |
423 | spin_unlock_irqrestore(&usbhid->outlock, flags); | ||
424 | dev_warn(&hid->dev, "output queue full\n"); | 504 | dev_warn(&hid->dev, "output queue full\n"); |
425 | return; | 505 | return; |
426 | } | 506 | } |
427 | 507 | ||
428 | usbhid->out[usbhid->outhead].raw_report = kmalloc(len, GFP_ATOMIC); | 508 | usbhid->out[usbhid->outhead].raw_report = kmalloc(len, GFP_ATOMIC); |
429 | if (!usbhid->out[usbhid->outhead].raw_report) { | 509 | if (!usbhid->out[usbhid->outhead].raw_report) { |
430 | spin_unlock_irqrestore(&usbhid->outlock, flags); | ||
431 | dev_warn(&hid->dev, "output queueing failed\n"); | 510 | dev_warn(&hid->dev, "output queueing failed\n"); |
432 | return; | 511 | return; |
433 | } | 512 | } |
@@ -438,15 +517,10 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns | |||
438 | if (!test_and_set_bit(HID_OUT_RUNNING, &usbhid->iofl)) | 517 | if (!test_and_set_bit(HID_OUT_RUNNING, &usbhid->iofl)) |
439 | if (hid_submit_out(hid)) | 518 | if (hid_submit_out(hid)) |
440 | clear_bit(HID_OUT_RUNNING, &usbhid->iofl); | 519 | clear_bit(HID_OUT_RUNNING, &usbhid->iofl); |
441 | |||
442 | spin_unlock_irqrestore(&usbhid->outlock, flags); | ||
443 | return; | 520 | return; |
444 | } | 521 | } |
445 | 522 | ||
446 | spin_lock_irqsave(&usbhid->ctrllock, flags); | ||
447 | |||
448 | if ((head = (usbhid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == usbhid->ctrltail) { | 523 | if ((head = (usbhid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == usbhid->ctrltail) { |
449 | spin_unlock_irqrestore(&usbhid->ctrllock, flags); | ||
450 | dev_warn(&hid->dev, "control queue full\n"); | 524 | dev_warn(&hid->dev, "control queue full\n"); |
451 | return; | 525 | return; |
452 | } | 526 | } |
@@ -454,7 +528,6 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns | |||
454 | if (dir == USB_DIR_OUT) { | 528 | if (dir == USB_DIR_OUT) { |
455 | usbhid->ctrl[usbhid->ctrlhead].raw_report = kmalloc(len, GFP_ATOMIC); | 529 | usbhid->ctrl[usbhid->ctrlhead].raw_report = kmalloc(len, GFP_ATOMIC); |
456 | if (!usbhid->ctrl[usbhid->ctrlhead].raw_report) { | 530 | if (!usbhid->ctrl[usbhid->ctrlhead].raw_report) { |
457 | spin_unlock_irqrestore(&usbhid->ctrllock, flags); | ||
458 | dev_warn(&hid->dev, "control queueing failed\n"); | 531 | dev_warn(&hid->dev, "control queueing failed\n"); |
459 | return; | 532 | return; |
460 | } | 533 | } |
@@ -467,15 +540,25 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns | |||
467 | if (!test_and_set_bit(HID_CTRL_RUNNING, &usbhid->iofl)) | 540 | if (!test_and_set_bit(HID_CTRL_RUNNING, &usbhid->iofl)) |
468 | if (hid_submit_ctrl(hid)) | 541 | if (hid_submit_ctrl(hid)) |
469 | clear_bit(HID_CTRL_RUNNING, &usbhid->iofl); | 542 | clear_bit(HID_CTRL_RUNNING, &usbhid->iofl); |
543 | } | ||
544 | |||
545 | void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir) | ||
546 | { | ||
547 | struct usbhid_device *usbhid = hid->driver_data; | ||
548 | unsigned long flags; | ||
470 | 549 | ||
471 | spin_unlock_irqrestore(&usbhid->ctrllock, flags); | 550 | spin_lock_irqsave(&usbhid->lock, flags); |
551 | __usbhid_submit_report(hid, report, dir); | ||
552 | spin_unlock_irqrestore(&usbhid->lock, flags); | ||
472 | } | 553 | } |
473 | EXPORT_SYMBOL_GPL(usbhid_submit_report); | 554 | EXPORT_SYMBOL_GPL(usbhid_submit_report); |
474 | 555 | ||
475 | static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) | 556 | static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) |
476 | { | 557 | { |
477 | struct hid_device *hid = input_get_drvdata(dev); | 558 | struct hid_device *hid = input_get_drvdata(dev); |
559 | struct usbhid_device *usbhid = hid->driver_data; | ||
478 | struct hid_field *field; | 560 | struct hid_field *field; |
561 | unsigned long flags; | ||
479 | int offset; | 562 | int offset; |
480 | 563 | ||
481 | if (type == EV_FF) | 564 | if (type == EV_FF) |
@@ -490,6 +573,15 @@ static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, un | |||
490 | } | 573 | } |
491 | 574 | ||
492 | hid_set_field(field, offset, value); | 575 | hid_set_field(field, offset, value); |
576 | if (value) { | ||
577 | spin_lock_irqsave(&usbhid->lock, flags); | ||
578 | usbhid->ledcount++; | ||
579 | spin_unlock_irqrestore(&usbhid->lock, flags); | ||
580 | } else { | ||
581 | spin_lock_irqsave(&usbhid->lock, flags); | ||
582 | usbhid->ledcount--; | ||
583 | spin_unlock_irqrestore(&usbhid->lock, flags); | ||
584 | } | ||
493 | usbhid_submit_report(hid, field->report, USB_DIR_OUT); | 585 | usbhid_submit_report(hid, field->report, USB_DIR_OUT); |
494 | 586 | ||
495 | return 0; | 587 | return 0; |
@@ -538,15 +630,22 @@ int usbhid_open(struct hid_device *hid) | |||
538 | struct usbhid_device *usbhid = hid->driver_data; | 630 | struct usbhid_device *usbhid = hid->driver_data; |
539 | int res; | 631 | int res; |
540 | 632 | ||
633 | mutex_lock(&hid_open_mut); | ||
541 | if (!hid->open++) { | 634 | if (!hid->open++) { |
542 | res = usb_autopm_get_interface(usbhid->intf); | 635 | res = usb_autopm_get_interface(usbhid->intf); |
636 | /* the device must be awake to reliable request remote wakeup */ | ||
543 | if (res < 0) { | 637 | if (res < 0) { |
544 | hid->open--; | 638 | hid->open--; |
639 | mutex_unlock(&hid_open_mut); | ||
545 | return -EIO; | 640 | return -EIO; |
546 | } | 641 | } |
642 | usbhid->intf->needs_remote_wakeup = 1; | ||
643 | if (hid_start_in(hid)) | ||
644 | hid_io_error(hid); | ||
645 | |||
646 | usb_autopm_put_interface(usbhid->intf); | ||
547 | } | 647 | } |
548 | if (hid_start_in(hid)) | 648 | mutex_unlock(&hid_open_mut); |
549 | hid_io_error(hid); | ||
550 | return 0; | 649 | return 0; |
551 | } | 650 | } |
552 | 651 | ||
@@ -554,10 +653,22 @@ void usbhid_close(struct hid_device *hid) | |||
554 | { | 653 | { |
555 | struct usbhid_device *usbhid = hid->driver_data; | 654 | struct usbhid_device *usbhid = hid->driver_data; |
556 | 655 | ||
656 | mutex_lock(&hid_open_mut); | ||
657 | |||
658 | /* protecting hid->open to make sure we don't restart | ||
659 | * data acquistion due to a resumption we no longer | ||
660 | * care about | ||
661 | */ | ||
662 | spin_lock_irq(&usbhid->lock); | ||
557 | if (!--hid->open) { | 663 | if (!--hid->open) { |
664 | spin_unlock_irq(&usbhid->lock); | ||
558 | usb_kill_urb(usbhid->urbin); | 665 | usb_kill_urb(usbhid->urbin); |
559 | usb_autopm_put_interface(usbhid->intf); | 666 | flush_scheduled_work(); |
667 | usbhid->intf->needs_remote_wakeup = 0; | ||
668 | } else { | ||
669 | spin_unlock_irq(&usbhid->lock); | ||
560 | } | 670 | } |
671 | mutex_unlock(&hid_open_mut); | ||
561 | } | 672 | } |
562 | 673 | ||
563 | /* | 674 | /* |
@@ -687,6 +798,25 @@ static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t co | |||
687 | return ret; | 798 | return ret; |
688 | } | 799 | } |
689 | 800 | ||
801 | static void usbhid_restart_queues(struct usbhid_device *usbhid) | ||
802 | { | ||
803 | if (usbhid->urbout) | ||
804 | usbhid_restart_out_queue(usbhid); | ||
805 | usbhid_restart_ctrl_queue(usbhid); | ||
806 | } | ||
807 | |||
808 | static void __usbhid_restart_queues(struct work_struct *work) | ||
809 | { | ||
810 | struct usbhid_device *usbhid = | ||
811 | container_of(work, struct usbhid_device, restart_work); | ||
812 | int r; | ||
813 | |||
814 | r = usb_autopm_get_interface(usbhid->intf); | ||
815 | if (r < 0) | ||
816 | return; | ||
817 | usb_autopm_put_interface(usbhid->intf); | ||
818 | } | ||
819 | |||
690 | static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid) | 820 | static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid) |
691 | { | 821 | { |
692 | struct usbhid_device *usbhid = hid->driver_data; | 822 | struct usbhid_device *usbhid = hid->driver_data; |
@@ -853,11 +983,11 @@ static int usbhid_start(struct hid_device *hid) | |||
853 | 983 | ||
854 | init_waitqueue_head(&usbhid->wait); | 984 | init_waitqueue_head(&usbhid->wait); |
855 | INIT_WORK(&usbhid->reset_work, hid_reset); | 985 | INIT_WORK(&usbhid->reset_work, hid_reset); |
986 | INIT_WORK(&usbhid->restart_work, __usbhid_restart_queues); | ||
856 | setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid); | 987 | setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid); |
857 | 988 | ||
858 | spin_lock_init(&usbhid->inlock); | 989 | spin_lock_init(&usbhid->lock); |
859 | spin_lock_init(&usbhid->outlock); | 990 | spin_lock_init(&usbhid->lock); |
860 | spin_lock_init(&usbhid->ctrllock); | ||
861 | 991 | ||
862 | usbhid->intf = intf; | 992 | usbhid->intf = intf; |
863 | usbhid->ifnum = interface->desc.bInterfaceNumber; | 993 | usbhid->ifnum = interface->desc.bInterfaceNumber; |
@@ -909,15 +1039,14 @@ static void usbhid_stop(struct hid_device *hid) | |||
909 | return; | 1039 | return; |
910 | 1040 | ||
911 | clear_bit(HID_STARTED, &usbhid->iofl); | 1041 | clear_bit(HID_STARTED, &usbhid->iofl); |
912 | spin_lock_irq(&usbhid->inlock); /* Sync with error handler */ | 1042 | spin_lock_irq(&usbhid->lock); /* Sync with error handler */ |
913 | set_bit(HID_DISCONNECTED, &usbhid->iofl); | 1043 | set_bit(HID_DISCONNECTED, &usbhid->iofl); |
914 | spin_unlock_irq(&usbhid->inlock); | 1044 | spin_unlock_irq(&usbhid->lock); |
915 | usb_kill_urb(usbhid->urbin); | 1045 | usb_kill_urb(usbhid->urbin); |
916 | usb_kill_urb(usbhid->urbout); | 1046 | usb_kill_urb(usbhid->urbout); |
917 | usb_kill_urb(usbhid->urbctrl); | 1047 | usb_kill_urb(usbhid->urbctrl); |
918 | 1048 | ||
919 | del_timer_sync(&usbhid->io_retry); | 1049 | hid_cancel_delayed_stuff(usbhid); |
920 | cancel_work_sync(&usbhid->reset_work); | ||
921 | 1050 | ||
922 | if (hid->claimed & HID_CLAIMED_INPUT) | 1051 | if (hid->claimed & HID_CLAIMED_INPUT) |
923 | hidinput_disconnect(hid); | 1052 | hidinput_disconnect(hid); |
@@ -938,12 +1067,28 @@ static void usbhid_stop(struct hid_device *hid) | |||
938 | hid_free_buffers(hid_to_usb_dev(hid), hid); | 1067 | hid_free_buffers(hid_to_usb_dev(hid), hid); |
939 | } | 1068 | } |
940 | 1069 | ||
1070 | static int usbhid_power(struct hid_device *hid, int lvl) | ||
1071 | { | ||
1072 | int r = 0; | ||
1073 | |||
1074 | switch (lvl) { | ||
1075 | case PM_HINT_FULLON: | ||
1076 | r = usbhid_get_power(hid); | ||
1077 | break; | ||
1078 | case PM_HINT_NORMAL: | ||
1079 | usbhid_put_power(hid); | ||
1080 | break; | ||
1081 | } | ||
1082 | return r; | ||
1083 | } | ||
1084 | |||
941 | static struct hid_ll_driver usb_hid_driver = { | 1085 | static struct hid_ll_driver usb_hid_driver = { |
942 | .parse = usbhid_parse, | 1086 | .parse = usbhid_parse, |
943 | .start = usbhid_start, | 1087 | .start = usbhid_start, |
944 | .stop = usbhid_stop, | 1088 | .stop = usbhid_stop, |
945 | .open = usbhid_open, | 1089 | .open = usbhid_open, |
946 | .close = usbhid_close, | 1090 | .close = usbhid_close, |
1091 | .power = usbhid_power, | ||
947 | .hidinput_input_event = usb_hidinput_input_event, | 1092 | .hidinput_input_event = usb_hidinput_input_event, |
948 | }; | 1093 | }; |
949 | 1094 | ||
@@ -1052,19 +1197,126 @@ static void hid_disconnect(struct usb_interface *intf) | |||
1052 | kfree(usbhid); | 1197 | kfree(usbhid); |
1053 | } | 1198 | } |
1054 | 1199 | ||
1200 | static void hid_cancel_delayed_stuff(struct usbhid_device *usbhid) | ||
1201 | { | ||
1202 | del_timer_sync(&usbhid->io_retry); | ||
1203 | cancel_work_sync(&usbhid->restart_work); | ||
1204 | cancel_work_sync(&usbhid->reset_work); | ||
1205 | } | ||
1206 | |||
1207 | static void hid_cease_io(struct usbhid_device *usbhid) | ||
1208 | { | ||
1209 | del_timer(&usbhid->io_retry); | ||
1210 | usb_kill_urb(usbhid->urbin); | ||
1211 | usb_kill_urb(usbhid->urbctrl); | ||
1212 | usb_kill_urb(usbhid->urbout); | ||
1213 | } | ||
1214 | |||
1215 | /* Treat USB reset pretty much the same as suspend/resume */ | ||
1216 | static int hid_pre_reset(struct usb_interface *intf) | ||
1217 | { | ||
1218 | struct hid_device *hid = usb_get_intfdata(intf); | ||
1219 | struct usbhid_device *usbhid = hid->driver_data; | ||
1220 | |||
1221 | spin_lock_irq(&usbhid->lock); | ||
1222 | set_bit(HID_RESET_PENDING, &usbhid->iofl); | ||
1223 | spin_unlock_irq(&usbhid->lock); | ||
1224 | cancel_work_sync(&usbhid->restart_work); | ||
1225 | hid_cease_io(usbhid); | ||
1226 | |||
1227 | return 0; | ||
1228 | } | ||
1229 | |||
1230 | /* Same routine used for post_reset and reset_resume */ | ||
1231 | static int hid_post_reset(struct usb_interface *intf) | ||
1232 | { | ||
1233 | struct usb_device *dev = interface_to_usbdev (intf); | ||
1234 | struct hid_device *hid = usb_get_intfdata(intf); | ||
1235 | struct usbhid_device *usbhid = hid->driver_data; | ||
1236 | int status; | ||
1237 | |||
1238 | spin_lock_irq(&usbhid->lock); | ||
1239 | clear_bit(HID_RESET_PENDING, &usbhid->iofl); | ||
1240 | spin_unlock_irq(&usbhid->lock); | ||
1241 | hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0); | ||
1242 | /* FIXME: Any more reinitialization needed? */ | ||
1243 | status = hid_start_in(hid); | ||
1244 | if (status < 0) | ||
1245 | hid_io_error(hid); | ||
1246 | usbhid_restart_queues(usbhid); | ||
1247 | |||
1248 | return 0; | ||
1249 | } | ||
1250 | |||
1251 | int usbhid_get_power(struct hid_device *hid) | ||
1252 | { | ||
1253 | struct usbhid_device *usbhid = hid->driver_data; | ||
1254 | |||
1255 | return usb_autopm_get_interface(usbhid->intf); | ||
1256 | } | ||
1257 | |||
1258 | void usbhid_put_power(struct hid_device *hid) | ||
1259 | { | ||
1260 | struct usbhid_device *usbhid = hid->driver_data; | ||
1261 | |||
1262 | usb_autopm_put_interface(usbhid->intf); | ||
1263 | } | ||
1264 | |||
1265 | |||
1266 | #ifdef CONFIG_PM | ||
1055 | static int hid_suspend(struct usb_interface *intf, pm_message_t message) | 1267 | static int hid_suspend(struct usb_interface *intf, pm_message_t message) |
1056 | { | 1268 | { |
1057 | struct hid_device *hid = usb_get_intfdata (intf); | 1269 | struct hid_device *hid = usb_get_intfdata(intf); |
1058 | struct usbhid_device *usbhid = hid->driver_data; | 1270 | struct usbhid_device *usbhid = hid->driver_data; |
1271 | struct usb_device *udev = interface_to_usbdev(intf); | ||
1272 | int status; | ||
1059 | 1273 | ||
1060 | if (!test_bit(HID_STARTED, &usbhid->iofl)) | 1274 | if (udev->auto_pm) { |
1061 | return 0; | 1275 | spin_lock_irq(&usbhid->lock); /* Sync with error handler */ |
1276 | if (!test_bit(HID_RESET_PENDING, &usbhid->iofl) | ||
1277 | && !test_bit(HID_CLEAR_HALT, &usbhid->iofl) | ||
1278 | && !test_bit(HID_OUT_RUNNING, &usbhid->iofl) | ||
1279 | && !test_bit(HID_CTRL_RUNNING, &usbhid->iofl) | ||
1280 | && !test_bit(HID_KEYS_PRESSED, &usbhid->iofl) | ||
1281 | && (!usbhid->ledcount || ignoreled)) | ||
1282 | { | ||
1283 | set_bit(HID_REPORTED_IDLE, &usbhid->iofl); | ||
1284 | spin_unlock_irq(&usbhid->lock); | ||
1285 | } else { | ||
1286 | usbhid_mark_busy(usbhid); | ||
1287 | spin_unlock_irq(&usbhid->lock); | ||
1288 | return -EBUSY; | ||
1289 | } | ||
1062 | 1290 | ||
1063 | spin_lock_irq(&usbhid->inlock); /* Sync with error handler */ | 1291 | } else { |
1064 | set_bit(HID_SUSPENDED, &usbhid->iofl); | 1292 | spin_lock_irq(&usbhid->lock); |
1065 | spin_unlock_irq(&usbhid->inlock); | 1293 | set_bit(HID_REPORTED_IDLE, &usbhid->iofl); |
1066 | del_timer_sync(&usbhid->io_retry); | 1294 | spin_unlock_irq(&usbhid->lock); |
1067 | usb_kill_urb(usbhid->urbin); | 1295 | if (usbhid_wait_io(hid) < 0) |
1296 | return -EIO; | ||
1297 | } | ||
1298 | |||
1299 | if (!ignoreled && udev->auto_pm) { | ||
1300 | spin_lock_irq(&usbhid->lock); | ||
1301 | if (test_bit(HID_LED_ON, &usbhid->iofl)) { | ||
1302 | spin_unlock_irq(&usbhid->lock); | ||
1303 | usbhid_mark_busy(usbhid); | ||
1304 | return -EBUSY; | ||
1305 | } | ||
1306 | spin_unlock_irq(&usbhid->lock); | ||
1307 | } | ||
1308 | |||
1309 | hid_cancel_delayed_stuff(usbhid); | ||
1310 | hid_cease_io(usbhid); | ||
1311 | |||
1312 | if (udev->auto_pm && test_bit(HID_KEYS_PRESSED, &usbhid->iofl)) { | ||
1313 | /* lost race against keypresses */ | ||
1314 | status = hid_start_in(hid); | ||
1315 | if (status < 0) | ||
1316 | hid_io_error(hid); | ||
1317 | usbhid_mark_busy(usbhid); | ||
1318 | return -EBUSY; | ||
1319 | } | ||
1068 | dev_dbg(&intf->dev, "suspend\n"); | 1320 | dev_dbg(&intf->dev, "suspend\n"); |
1069 | return 0; | 1321 | return 0; |
1070 | } | 1322 | } |
@@ -1078,32 +1330,33 @@ static int hid_resume(struct usb_interface *intf) | |||
1078 | if (!test_bit(HID_STARTED, &usbhid->iofl)) | 1330 | if (!test_bit(HID_STARTED, &usbhid->iofl)) |
1079 | return 0; | 1331 | return 0; |
1080 | 1332 | ||
1081 | clear_bit(HID_SUSPENDED, &usbhid->iofl); | 1333 | clear_bit(HID_REPORTED_IDLE, &usbhid->iofl); |
1334 | usbhid_mark_busy(usbhid); | ||
1335 | |||
1336 | if (test_bit(HID_CLEAR_HALT, &usbhid->iofl) || | ||
1337 | test_bit(HID_RESET_PENDING, &usbhid->iofl)) | ||
1338 | schedule_work(&usbhid->reset_work); | ||
1082 | usbhid->retry_delay = 0; | 1339 | usbhid->retry_delay = 0; |
1083 | status = hid_start_in(hid); | 1340 | status = hid_start_in(hid); |
1084 | dev_dbg(&intf->dev, "resume status %d\n", status); | 1341 | if (status < 0) |
1085 | return status; | 1342 | hid_io_error(hid); |
1086 | } | 1343 | usbhid_restart_queues(usbhid); |
1087 | 1344 | ||
1088 | /* Treat USB reset pretty much the same as suspend/resume */ | 1345 | dev_dbg(&intf->dev, "resume status %d\n", status); |
1089 | static int hid_pre_reset(struct usb_interface *intf) | ||
1090 | { | ||
1091 | /* FIXME: What if the interface is already suspended? */ | ||
1092 | hid_suspend(intf, PMSG_ON); | ||
1093 | return 0; | 1346 | return 0; |
1094 | } | 1347 | } |
1095 | 1348 | ||
1096 | /* Same routine used for post_reset and reset_resume */ | 1349 | static int hid_reset_resume(struct usb_interface *intf) |
1097 | static int hid_post_reset(struct usb_interface *intf) | ||
1098 | { | 1350 | { |
1099 | struct usb_device *dev = interface_to_usbdev (intf); | 1351 | struct hid_device *hid = usb_get_intfdata(intf); |
1100 | 1352 | struct usbhid_device *usbhid = hid->driver_data; | |
1101 | hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0); | ||
1102 | /* FIXME: Any more reinitialization needed? */ | ||
1103 | 1353 | ||
1104 | return hid_resume(intf); | 1354 | clear_bit(HID_REPORTED_IDLE, &usbhid->iofl); |
1355 | return hid_post_reset(intf); | ||
1105 | } | 1356 | } |
1106 | 1357 | ||
1358 | #endif /* CONFIG_PM */ | ||
1359 | |||
1107 | static struct usb_device_id hid_usb_ids [] = { | 1360 | static struct usb_device_id hid_usb_ids [] = { |
1108 | { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, | 1361 | { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, |
1109 | .bInterfaceClass = USB_INTERFACE_CLASS_HID }, | 1362 | .bInterfaceClass = USB_INTERFACE_CLASS_HID }, |
@@ -1116,9 +1369,11 @@ static struct usb_driver hid_driver = { | |||
1116 | .name = "usbhid", | 1369 | .name = "usbhid", |
1117 | .probe = hid_probe, | 1370 | .probe = hid_probe, |
1118 | .disconnect = hid_disconnect, | 1371 | .disconnect = hid_disconnect, |
1372 | #ifdef CONFIG_PM | ||
1119 | .suspend = hid_suspend, | 1373 | .suspend = hid_suspend, |
1120 | .resume = hid_resume, | 1374 | .resume = hid_resume, |
1121 | .reset_resume = hid_post_reset, | 1375 | .reset_resume = hid_reset_resume, |
1376 | #endif | ||
1122 | .pre_reset = hid_pre_reset, | 1377 | .pre_reset = hid_pre_reset, |
1123 | .post_reset = hid_post_reset, | 1378 | .post_reset = hid_post_reset, |
1124 | .id_table = hid_usb_ids, | 1379 | .id_table = hid_usb_ids, |
@@ -1137,7 +1392,11 @@ static struct hid_driver hid_usb_driver = { | |||
1137 | 1392 | ||
1138 | static int __init hid_init(void) | 1393 | static int __init hid_init(void) |
1139 | { | 1394 | { |
1140 | int retval; | 1395 | int retval = -ENOMEM; |
1396 | |||
1397 | resumption_waker = create_freezeable_workqueue("usbhid_resumer"); | ||
1398 | if (!resumption_waker) | ||
1399 | goto no_queue; | ||
1141 | retval = hid_register_driver(&hid_usb_driver); | 1400 | retval = hid_register_driver(&hid_usb_driver); |
1142 | if (retval) | 1401 | if (retval) |
1143 | goto hid_register_fail; | 1402 | goto hid_register_fail; |
@@ -1161,6 +1420,8 @@ hiddev_init_fail: | |||
1161 | usbhid_quirks_init_fail: | 1420 | usbhid_quirks_init_fail: |
1162 | hid_unregister_driver(&hid_usb_driver); | 1421 | hid_unregister_driver(&hid_usb_driver); |
1163 | hid_register_fail: | 1422 | hid_register_fail: |
1423 | destroy_workqueue(resumption_waker); | ||
1424 | no_queue: | ||
1164 | return retval; | 1425 | return retval; |
1165 | } | 1426 | } |
1166 | 1427 | ||
@@ -1170,6 +1431,7 @@ static void __exit hid_exit(void) | |||
1170 | hiddev_exit(); | 1431 | hiddev_exit(); |
1171 | usbhid_quirks_exit(); | 1432 | usbhid_quirks_exit(); |
1172 | hid_unregister_driver(&hid_usb_driver); | 1433 | hid_unregister_driver(&hid_usb_driver); |
1434 | destroy_workqueue(resumption_waker); | ||
1173 | } | 1435 | } |
1174 | 1436 | ||
1175 | module_init(hid_init); | 1437 | module_init(hid_init); |
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index 93dcb7e29102..e9b436d2d944 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c | |||
@@ -246,10 +246,12 @@ static int hiddev_release(struct inode * inode, struct file * file) | |||
246 | spin_unlock_irqrestore(&list->hiddev->list_lock, flags); | 246 | spin_unlock_irqrestore(&list->hiddev->list_lock, flags); |
247 | 247 | ||
248 | if (!--list->hiddev->open) { | 248 | if (!--list->hiddev->open) { |
249 | if (list->hiddev->exist) | 249 | if (list->hiddev->exist) { |
250 | usbhid_close(list->hiddev->hid); | 250 | usbhid_close(list->hiddev->hid); |
251 | else | 251 | usbhid_put_power(list->hiddev->hid); |
252 | } else { | ||
252 | kfree(list->hiddev); | 253 | kfree(list->hiddev); |
254 | } | ||
253 | } | 255 | } |
254 | 256 | ||
255 | kfree(list); | 257 | kfree(list); |
@@ -300,6 +302,17 @@ static int hiddev_open(struct inode *inode, struct file *file) | |||
300 | list_add_tail(&list->node, &hiddev_table[i]->list); | 302 | list_add_tail(&list->node, &hiddev_table[i]->list); |
301 | spin_unlock_irq(&list->hiddev->list_lock); | 303 | spin_unlock_irq(&list->hiddev->list_lock); |
302 | 304 | ||
305 | if (!list->hiddev->open++) | ||
306 | if (list->hiddev->exist) { | ||
307 | struct hid_device *hid = hiddev_table[i]->hid; | ||
308 | res = usbhid_get_power(hid); | ||
309 | if (res < 0) { | ||
310 | res = -EIO; | ||
311 | goto bail; | ||
312 | } | ||
313 | usbhid_open(hid); | ||
314 | } | ||
315 | |||
303 | return 0; | 316 | return 0; |
304 | bail: | 317 | bail: |
305 | file->private_data = NULL; | 318 | file->private_data = NULL; |
diff --git a/drivers/hid/usbhid/usbhid.h b/drivers/hid/usbhid/usbhid.h index 9eb30564be9c..08f505ca2e3d 100644 --- a/drivers/hid/usbhid/usbhid.h +++ b/drivers/hid/usbhid/usbhid.h | |||
@@ -38,7 +38,10 @@ int usbhid_wait_io(struct hid_device* hid); | |||
38 | void usbhid_close(struct hid_device *hid); | 38 | void usbhid_close(struct hid_device *hid); |
39 | int usbhid_open(struct hid_device *hid); | 39 | int usbhid_open(struct hid_device *hid); |
40 | void usbhid_init_reports(struct hid_device *hid); | 40 | void usbhid_init_reports(struct hid_device *hid); |
41 | void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir); | 41 | void usbhid_submit_report |
42 | (struct hid_device *hid, struct hid_report *report, unsigned char dir); | ||
43 | int usbhid_get_power(struct hid_device *hid); | ||
44 | void usbhid_put_power(struct hid_device *hid); | ||
42 | 45 | ||
43 | /* iofl flags */ | 46 | /* iofl flags */ |
44 | #define HID_CTRL_RUNNING 1 | 47 | #define HID_CTRL_RUNNING 1 |
@@ -49,6 +52,9 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns | |||
49 | #define HID_CLEAR_HALT 6 | 52 | #define HID_CLEAR_HALT 6 |
50 | #define HID_DISCONNECTED 7 | 53 | #define HID_DISCONNECTED 7 |
51 | #define HID_STARTED 8 | 54 | #define HID_STARTED 8 |
55 | #define HID_REPORTED_IDLE 9 | ||
56 | #define HID_KEYS_PRESSED 10 | ||
57 | #define HID_LED_ON 11 | ||
52 | 58 | ||
53 | /* | 59 | /* |
54 | * USB-specific HID struct, to be pointed to | 60 | * USB-specific HID struct, to be pointed to |
@@ -66,7 +72,6 @@ struct usbhid_device { | |||
66 | struct urb *urbin; /* Input URB */ | 72 | struct urb *urbin; /* Input URB */ |
67 | char *inbuf; /* Input buffer */ | 73 | char *inbuf; /* Input buffer */ |
68 | dma_addr_t inbuf_dma; /* Input buffer dma */ | 74 | dma_addr_t inbuf_dma; /* Input buffer dma */ |
69 | spinlock_t inlock; /* Input fifo spinlock */ | ||
70 | 75 | ||
71 | struct urb *urbctrl; /* Control URB */ | 76 | struct urb *urbctrl; /* Control URB */ |
72 | struct usb_ctrlrequest *cr; /* Control request struct */ | 77 | struct usb_ctrlrequest *cr; /* Control request struct */ |
@@ -75,21 +80,22 @@ struct usbhid_device { | |||
75 | unsigned char ctrlhead, ctrltail; /* Control fifo head & tail */ | 80 | unsigned char ctrlhead, ctrltail; /* Control fifo head & tail */ |
76 | char *ctrlbuf; /* Control buffer */ | 81 | char *ctrlbuf; /* Control buffer */ |
77 | dma_addr_t ctrlbuf_dma; /* Control buffer dma */ | 82 | dma_addr_t ctrlbuf_dma; /* Control buffer dma */ |
78 | spinlock_t ctrllock; /* Control fifo spinlock */ | ||
79 | 83 | ||
80 | struct urb *urbout; /* Output URB */ | 84 | struct urb *urbout; /* Output URB */ |
81 | struct hid_output_fifo out[HID_CONTROL_FIFO_SIZE]; /* Output pipe fifo */ | 85 | struct hid_output_fifo out[HID_CONTROL_FIFO_SIZE]; /* Output pipe fifo */ |
82 | unsigned char outhead, outtail; /* Output pipe fifo head & tail */ | 86 | unsigned char outhead, outtail; /* Output pipe fifo head & tail */ |
83 | char *outbuf; /* Output buffer */ | 87 | char *outbuf; /* Output buffer */ |
84 | dma_addr_t outbuf_dma; /* Output buffer dma */ | 88 | dma_addr_t outbuf_dma; /* Output buffer dma */ |
85 | spinlock_t outlock; /* Output fifo spinlock */ | ||
86 | 89 | ||
90 | spinlock_t lock; /* fifo spinlock */ | ||
87 | unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */ | 91 | unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */ |
88 | struct timer_list io_retry; /* Retry timer */ | 92 | struct timer_list io_retry; /* Retry timer */ |
89 | unsigned long stop_retry; /* Time to give up, in jiffies */ | 93 | unsigned long stop_retry; /* Time to give up, in jiffies */ |
90 | unsigned int retry_delay; /* Delay length in ms */ | 94 | unsigned int retry_delay; /* Delay length in ms */ |
91 | struct work_struct reset_work; /* Task context for resets */ | 95 | struct work_struct reset_work; /* Task context for resets */ |
96 | struct work_struct restart_work; /* waking up for output to be done in a task */ | ||
92 | wait_queue_head_t wait; /* For sleeping */ | 97 | wait_queue_head_t wait; /* For sleeping */ |
98 | int ledcount; /* counting the number of active leds */ | ||
93 | }; | 99 | }; |
94 | 100 | ||
95 | #define hid_to_usb_dev(hid_dev) \ | 101 | #define hid_to_usb_dev(hid_dev) \ |