diff options
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 | 435 | ||||
-rw-r--r-- | drivers/hid/usbhid/hiddev.c | 17 | ||||
-rw-r--r-- | drivers/hid/usbhid/usbhid.h | 14 |
5 files changed, 396 insertions, 103 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 1cc967448f4d..feaeb6167ea4 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -1822,6 +1822,22 @@ static DECLARE_WORK(hid_compat_work, hid_compat_load); | |||
1822 | static struct workqueue_struct *hid_compat_wq; | 1822 | static struct workqueue_struct *hid_compat_wq; |
1823 | #endif | 1823 | #endif |
1824 | 1824 | ||
1825 | int hid_check_keys_pressed(struct hid_device *hid) | ||
1826 | { | ||
1827 | struct hid_input *hidinput; | ||
1828 | int i; | ||
1829 | |||
1830 | list_for_each_entry(hidinput, &hid->inputs, list) { | ||
1831 | for (i = 0; i < BITS_TO_LONGS(KEY_MAX); i++) | ||
1832 | if (hidinput->input->key[i]) | ||
1833 | return 1; | ||
1834 | } | ||
1835 | |||
1836 | return 0; | ||
1837 | } | ||
1838 | |||
1839 | EXPORT_SYMBOL_GPL(hid_check_keys_pressed); | ||
1840 | |||
1825 | static int __init hid_init(void) | 1841 | static int __init hid_init(void) |
1826 | { | 1842 | { |
1827 | int ret; | 1843 | 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 f0a0f72238ab..625e7e8eb373 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 | } | ||
470 | 544 | ||
471 | spin_unlock_irqrestore(&usbhid->ctrllock, flags); | 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; | ||
549 | |||
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; |
@@ -850,11 +980,11 @@ static int usbhid_start(struct hid_device *hid) | |||
850 | 980 | ||
851 | init_waitqueue_head(&usbhid->wait); | 981 | init_waitqueue_head(&usbhid->wait); |
852 | INIT_WORK(&usbhid->reset_work, hid_reset); | 982 | INIT_WORK(&usbhid->reset_work, hid_reset); |
983 | INIT_WORK(&usbhid->restart_work, __usbhid_restart_queues); | ||
853 | setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid); | 984 | setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid); |
854 | 985 | ||
855 | spin_lock_init(&usbhid->inlock); | 986 | spin_lock_init(&usbhid->lock); |
856 | spin_lock_init(&usbhid->outlock); | 987 | spin_lock_init(&usbhid->lock); |
857 | spin_lock_init(&usbhid->ctrllock); | ||
858 | 988 | ||
859 | usbhid->intf = intf; | 989 | usbhid->intf = intf; |
860 | usbhid->ifnum = interface->desc.bInterfaceNumber; | 990 | usbhid->ifnum = interface->desc.bInterfaceNumber; |
@@ -906,15 +1036,14 @@ static void usbhid_stop(struct hid_device *hid) | |||
906 | return; | 1036 | return; |
907 | 1037 | ||
908 | clear_bit(HID_STARTED, &usbhid->iofl); | 1038 | clear_bit(HID_STARTED, &usbhid->iofl); |
909 | spin_lock_irq(&usbhid->inlock); /* Sync with error handler */ | 1039 | spin_lock_irq(&usbhid->lock); /* Sync with error handler */ |
910 | set_bit(HID_DISCONNECTED, &usbhid->iofl); | 1040 | set_bit(HID_DISCONNECTED, &usbhid->iofl); |
911 | spin_unlock_irq(&usbhid->inlock); | 1041 | spin_unlock_irq(&usbhid->lock); |
912 | usb_kill_urb(usbhid->urbin); | 1042 | usb_kill_urb(usbhid->urbin); |
913 | usb_kill_urb(usbhid->urbout); | 1043 | usb_kill_urb(usbhid->urbout); |
914 | usb_kill_urb(usbhid->urbctrl); | 1044 | usb_kill_urb(usbhid->urbctrl); |
915 | 1045 | ||
916 | del_timer_sync(&usbhid->io_retry); | 1046 | hid_cancel_delayed_stuff(usbhid); |
917 | cancel_work_sync(&usbhid->reset_work); | ||
918 | 1047 | ||
919 | if (hid->claimed & HID_CLAIMED_INPUT) | 1048 | if (hid->claimed & HID_CLAIMED_INPUT) |
920 | hidinput_disconnect(hid); | 1049 | hidinput_disconnect(hid); |
@@ -935,12 +1064,28 @@ static void usbhid_stop(struct hid_device *hid) | |||
935 | hid_free_buffers(hid_to_usb_dev(hid), hid); | 1064 | hid_free_buffers(hid_to_usb_dev(hid), hid); |
936 | } | 1065 | } |
937 | 1066 | ||
1067 | static int usbhid_power(struct hid_device *hid, int lvl) | ||
1068 | { | ||
1069 | int r = 0; | ||
1070 | |||
1071 | switch (lvl) { | ||
1072 | case PM_HINT_FULLON: | ||
1073 | r = usbhid_get_power(hid); | ||
1074 | break; | ||
1075 | case PM_HINT_NORMAL: | ||
1076 | usbhid_put_power(hid); | ||
1077 | break; | ||
1078 | } | ||
1079 | return r; | ||
1080 | } | ||
1081 | |||
938 | static struct hid_ll_driver usb_hid_driver = { | 1082 | static struct hid_ll_driver usb_hid_driver = { |
939 | .parse = usbhid_parse, | 1083 | .parse = usbhid_parse, |
940 | .start = usbhid_start, | 1084 | .start = usbhid_start, |
941 | .stop = usbhid_stop, | 1085 | .stop = usbhid_stop, |
942 | .open = usbhid_open, | 1086 | .open = usbhid_open, |
943 | .close = usbhid_close, | 1087 | .close = usbhid_close, |
1088 | .power = usbhid_power, | ||
944 | .hidinput_input_event = usb_hidinput_input_event, | 1089 | .hidinput_input_event = usb_hidinput_input_event, |
945 | }; | 1090 | }; |
946 | 1091 | ||
@@ -1049,19 +1194,75 @@ static void hid_disconnect(struct usb_interface *intf) | |||
1049 | kfree(usbhid); | 1194 | kfree(usbhid); |
1050 | } | 1195 | } |
1051 | 1196 | ||
1197 | static void hid_cancel_delayed_stuff(struct usbhid_device *usbhid) | ||
1198 | { | ||
1199 | del_timer_sync(&usbhid->io_retry); | ||
1200 | cancel_work_sync(&usbhid->restart_work); | ||
1201 | cancel_work_sync(&usbhid->reset_work); | ||
1202 | } | ||
1203 | |||
1204 | static void hid_cease_io(struct usbhid_device *usbhid) | ||
1205 | { | ||
1206 | del_timer(&usbhid->io_retry); | ||
1207 | usb_kill_urb(usbhid->urbin); | ||
1208 | usb_kill_urb(usbhid->urbctrl); | ||
1209 | usb_kill_urb(usbhid->urbout); | ||
1210 | flush_scheduled_work(); | ||
1211 | } | ||
1212 | |||
1052 | static int hid_suspend(struct usb_interface *intf, pm_message_t message) | 1213 | static int hid_suspend(struct usb_interface *intf, pm_message_t message) |
1053 | { | 1214 | { |
1054 | struct hid_device *hid = usb_get_intfdata (intf); | 1215 | struct hid_device *hid = usb_get_intfdata(intf); |
1055 | struct usbhid_device *usbhid = hid->driver_data; | 1216 | struct usbhid_device *usbhid = hid->driver_data; |
1217 | struct usb_device *udev = interface_to_usbdev(intf); | ||
1218 | int status; | ||
1056 | 1219 | ||
1057 | if (!test_bit(HID_STARTED, &usbhid->iofl)) | 1220 | if (udev->auto_pm) { |
1058 | return 0; | 1221 | spin_lock_irq(&usbhid->lock); /* Sync with error handler */ |
1222 | if (!test_bit(HID_RESET_PENDING, &usbhid->iofl) | ||
1223 | && !test_bit(HID_CLEAR_HALT, &usbhid->iofl) | ||
1224 | && !test_bit(HID_OUT_RUNNING, &usbhid->iofl) | ||
1225 | && !test_bit(HID_CTRL_RUNNING, &usbhid->iofl) | ||
1226 | && !test_bit(HID_KEYS_PRESSED, &usbhid->iofl) | ||
1227 | && (!usbhid->ledcount || ignoreled)) | ||
1228 | { | ||
1229 | set_bit(HID_REPORTED_IDLE, &usbhid->iofl); | ||
1230 | spin_unlock_irq(&usbhid->lock); | ||
1231 | } else { | ||
1232 | usbhid_mark_busy(usbhid); | ||
1233 | spin_unlock_irq(&usbhid->lock); | ||
1234 | return -EBUSY; | ||
1235 | } | ||
1059 | 1236 | ||
1060 | spin_lock_irq(&usbhid->inlock); /* Sync with error handler */ | 1237 | } else { |
1061 | set_bit(HID_SUSPENDED, &usbhid->iofl); | 1238 | spin_lock_irq(&usbhid->lock); |
1062 | spin_unlock_irq(&usbhid->inlock); | 1239 | set_bit(HID_REPORTED_IDLE, &usbhid->iofl); |
1063 | del_timer_sync(&usbhid->io_retry); | 1240 | spin_unlock_irq(&usbhid->lock); |
1064 | usb_kill_urb(usbhid->urbin); | 1241 | if (usbhid_wait_io(hid) < 0) |
1242 | return -EIO; | ||
1243 | } | ||
1244 | |||
1245 | if (!ignoreled && udev->auto_pm) { | ||
1246 | spin_lock_irq(&usbhid->lock); | ||
1247 | if (test_bit(HID_LED_ON, &usbhid->iofl)) { | ||
1248 | spin_unlock_irq(&usbhid->lock); | ||
1249 | usbhid_mark_busy(usbhid); | ||
1250 | return -EBUSY; | ||
1251 | } | ||
1252 | spin_unlock_irq(&usbhid->lock); | ||
1253 | } | ||
1254 | |||
1255 | hid_cancel_delayed_stuff(usbhid); | ||
1256 | hid_cease_io(usbhid); | ||
1257 | |||
1258 | if (udev->auto_pm && test_bit(HID_KEYS_PRESSED, &usbhid->iofl)) { | ||
1259 | /* lost race against keypresses */ | ||
1260 | status = hid_start_in(hid); | ||
1261 | if (status < 0) | ||
1262 | hid_io_error(hid); | ||
1263 | usbhid_mark_busy(usbhid); | ||
1264 | return -EBUSY; | ||
1265 | } | ||
1065 | dev_dbg(&intf->dev, "suspend\n"); | 1266 | dev_dbg(&intf->dev, "suspend\n"); |
1066 | return 0; | 1267 | return 0; |
1067 | } | 1268 | } |
@@ -1075,18 +1276,33 @@ static int hid_resume(struct usb_interface *intf) | |||
1075 | if (!test_bit(HID_STARTED, &usbhid->iofl)) | 1276 | if (!test_bit(HID_STARTED, &usbhid->iofl)) |
1076 | return 0; | 1277 | return 0; |
1077 | 1278 | ||
1078 | clear_bit(HID_SUSPENDED, &usbhid->iofl); | 1279 | clear_bit(HID_REPORTED_IDLE, &usbhid->iofl); |
1280 | usbhid_mark_busy(usbhid); | ||
1281 | |||
1282 | if (test_bit(HID_CLEAR_HALT, &usbhid->iofl) || | ||
1283 | test_bit(HID_RESET_PENDING, &usbhid->iofl)) | ||
1284 | schedule_work(&usbhid->reset_work); | ||
1079 | usbhid->retry_delay = 0; | 1285 | usbhid->retry_delay = 0; |
1080 | status = hid_start_in(hid); | 1286 | status = hid_start_in(hid); |
1287 | if (status < 0) | ||
1288 | hid_io_error(hid); | ||
1289 | usbhid_restart_queues(usbhid); | ||
1290 | |||
1081 | dev_dbg(&intf->dev, "resume status %d\n", status); | 1291 | dev_dbg(&intf->dev, "resume status %d\n", status); |
1082 | return status; | 1292 | return 0; |
1083 | } | 1293 | } |
1084 | 1294 | ||
1085 | /* Treat USB reset pretty much the same as suspend/resume */ | 1295 | /* Treat USB reset pretty much the same as suspend/resume */ |
1086 | static int hid_pre_reset(struct usb_interface *intf) | 1296 | static int hid_pre_reset(struct usb_interface *intf) |
1087 | { | 1297 | { |
1088 | /* FIXME: What if the interface is already suspended? */ | 1298 | struct hid_device *hid = usb_get_intfdata(intf); |
1089 | hid_suspend(intf, PMSG_ON); | 1299 | struct usbhid_device *usbhid = hid->driver_data; |
1300 | |||
1301 | spin_lock_irq(&usbhid->lock); | ||
1302 | set_bit(HID_RESET_PENDING, &usbhid->iofl); | ||
1303 | spin_unlock_irq(&usbhid->lock); | ||
1304 | hid_cease_io(usbhid); | ||
1305 | |||
1090 | return 0; | 1306 | return 0; |
1091 | } | 1307 | } |
1092 | 1308 | ||
@@ -1094,11 +1310,35 @@ static int hid_pre_reset(struct usb_interface *intf) | |||
1094 | static int hid_post_reset(struct usb_interface *intf) | 1310 | static int hid_post_reset(struct usb_interface *intf) |
1095 | { | 1311 | { |
1096 | struct usb_device *dev = interface_to_usbdev (intf); | 1312 | struct usb_device *dev = interface_to_usbdev (intf); |
1097 | 1313 | struct hid_device *hid = usb_get_intfdata(intf); | |
1314 | struct usbhid_device *usbhid = hid->driver_data; | ||
1315 | int status; | ||
1316 | |||
1317 | spin_lock_irq(&usbhid->lock); | ||
1318 | clear_bit(HID_RESET_PENDING, &usbhid->iofl); | ||
1319 | spin_unlock_irq(&usbhid->lock); | ||
1098 | hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0); | 1320 | hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0); |
1099 | /* FIXME: Any more reinitialization needed? */ | 1321 | /* FIXME: Any more reinitialization needed? */ |
1322 | status = hid_start_in(hid); | ||
1323 | if (status < 0) | ||
1324 | hid_io_error(hid); | ||
1325 | usbhid_restart_queues(usbhid); | ||
1100 | 1326 | ||
1101 | return hid_resume(intf); | 1327 | return 0; |
1328 | } | ||
1329 | |||
1330 | int usbhid_get_power(struct hid_device *hid) | ||
1331 | { | ||
1332 | struct usbhid_device *usbhid = hid->driver_data; | ||
1333 | |||
1334 | return usb_autopm_get_interface(usbhid->intf); | ||
1335 | } | ||
1336 | |||
1337 | void usbhid_put_power(struct hid_device *hid) | ||
1338 | { | ||
1339 | struct usbhid_device *usbhid = hid->driver_data; | ||
1340 | |||
1341 | usb_autopm_put_interface(usbhid->intf); | ||
1102 | } | 1342 | } |
1103 | 1343 | ||
1104 | static struct usb_device_id hid_usb_ids [] = { | 1344 | static struct usb_device_id hid_usb_ids [] = { |
@@ -1134,7 +1374,11 @@ static struct hid_driver hid_usb_driver = { | |||
1134 | 1374 | ||
1135 | static int __init hid_init(void) | 1375 | static int __init hid_init(void) |
1136 | { | 1376 | { |
1137 | int retval; | 1377 | int retval = -ENOMEM; |
1378 | |||
1379 | resumption_waker = create_freezeable_workqueue("usbhid_resumer"); | ||
1380 | if (!resumption_waker) | ||
1381 | goto no_queue; | ||
1138 | retval = hid_register_driver(&hid_usb_driver); | 1382 | retval = hid_register_driver(&hid_usb_driver); |
1139 | if (retval) | 1383 | if (retval) |
1140 | goto hid_register_fail; | 1384 | goto hid_register_fail; |
@@ -1158,6 +1402,8 @@ hiddev_init_fail: | |||
1158 | usbhid_quirks_init_fail: | 1402 | usbhid_quirks_init_fail: |
1159 | hid_unregister_driver(&hid_usb_driver); | 1403 | hid_unregister_driver(&hid_usb_driver); |
1160 | hid_register_fail: | 1404 | hid_register_fail: |
1405 | destroy_workqueue(resumption_waker); | ||
1406 | no_queue: | ||
1161 | return retval; | 1407 | return retval; |
1162 | } | 1408 | } |
1163 | 1409 | ||
@@ -1167,6 +1413,7 @@ static void __exit hid_exit(void) | |||
1167 | hiddev_exit(); | 1413 | hiddev_exit(); |
1168 | usbhid_quirks_exit(); | 1414 | usbhid_quirks_exit(); |
1169 | hid_unregister_driver(&hid_usb_driver); | 1415 | hid_unregister_driver(&hid_usb_driver); |
1416 | destroy_workqueue(resumption_waker); | ||
1170 | } | 1417 | } |
1171 | 1418 | ||
1172 | module_init(hid_init); | 1419 | module_init(hid_init); |
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index 1f5b5d4c3c34..fd7375627e5d 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c | |||
@@ -249,10 +249,12 @@ static int hiddev_release(struct inode * inode, struct file * file) | |||
249 | spin_unlock_irqrestore(&list->hiddev->list_lock, flags); | 249 | spin_unlock_irqrestore(&list->hiddev->list_lock, flags); |
250 | 250 | ||
251 | if (!--list->hiddev->open) { | 251 | if (!--list->hiddev->open) { |
252 | if (list->hiddev->exist) | 252 | if (list->hiddev->exist) { |
253 | usbhid_close(list->hiddev->hid); | 253 | usbhid_close(list->hiddev->hid); |
254 | else | 254 | usbhid_put_power(list->hiddev->hid); |
255 | } else { | ||
255 | kfree(list->hiddev); | 256 | kfree(list->hiddev); |
257 | } | ||
256 | } | 258 | } |
257 | 259 | ||
258 | kfree(list); | 260 | kfree(list); |
@@ -303,6 +305,17 @@ static int hiddev_open(struct inode *inode, struct file *file) | |||
303 | list_add_tail(&list->node, &hiddev_table[i]->list); | 305 | list_add_tail(&list->node, &hiddev_table[i]->list); |
304 | spin_unlock_irq(&list->hiddev->list_lock); | 306 | spin_unlock_irq(&list->hiddev->list_lock); |
305 | 307 | ||
308 | if (!list->hiddev->open++) | ||
309 | if (list->hiddev->exist) { | ||
310 | struct hid_device *hid = hiddev_table[i]->hid; | ||
311 | res = usbhid_get_power(hid); | ||
312 | if (res < 0) { | ||
313 | res = -EIO; | ||
314 | goto bail; | ||
315 | } | ||
316 | usbhid_open(hid); | ||
317 | } | ||
318 | |||
306 | return 0; | 319 | return 0; |
307 | bail: | 320 | bail: |
308 | file->private_data = NULL; | 321 | 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) \ |