1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * PS/2 driver library |
4 | * |
5 | * Copyright (c) 1999-2002 Vojtech Pavlik |
6 | * Copyright (c) 2004 Dmitry Torokhov |
7 | */ |
8 | |
9 | |
10 | #include <linux/delay.h> |
11 | #include <linux/module.h> |
12 | #include <linux/sched.h> |
13 | #include <linux/interrupt.h> |
14 | #include <linux/input.h> |
15 | #include <linux/kmsan-checks.h> |
16 | #include <linux/serio.h> |
17 | #include <linux/i8042.h> |
18 | #include <linux/libps2.h> |
19 | |
20 | #define DRIVER_DESC "PS/2 driver library" |
21 | |
22 | #define PS2_CMD_SETSCALE11 0x00e6 |
23 | #define PS2_CMD_SETRES 0x10e8 |
24 | #define PS2_CMD_EX_SETLEDS 0x20eb |
25 | #define PS2_CMD_SETLEDS 0x10ed |
26 | #define PS2_CMD_GETID 0x02f2 |
27 | #define PS2_CMD_SETREP 0x10f3 /* Set repeat rate/set report rate */ |
28 | #define PS2_CMD_RESET_BAT 0x02ff |
29 | |
30 | #define PS2_RET_BAT 0xaa |
31 | #define PS2_RET_ID 0x00 |
32 | #define PS2_RET_ACK 0xfa |
33 | #define PS2_RET_NAK 0xfe |
34 | #define PS2_RET_ERR 0xfc |
35 | |
36 | #define PS2_FLAG_ACK BIT(0) /* Waiting for ACK/NAK */ |
37 | #define PS2_FLAG_CMD BIT(1) /* Waiting for a command to finish */ |
38 | #define PS2_FLAG_CMD1 BIT(2) /* Waiting for the first byte of command response */ |
39 | #define PS2_FLAG_WAITID BIT(3) /* Command executing is GET ID */ |
40 | #define PS2_FLAG_NAK BIT(4) /* Last transmission was NAKed */ |
41 | #define PS2_FLAG_PASS_NOACK BIT(5) /* Pass non-ACK byte to receive handler */ |
42 | |
43 | static int ps2_do_sendbyte(struct ps2dev *ps2dev, u8 byte, |
44 | unsigned int timeout, unsigned int max_attempts) |
45 | __releases(&ps2dev->serio->lock) __acquires(&ps2dev->serio->lock) |
46 | { |
47 | int attempt = 0; |
48 | int error; |
49 | |
50 | lockdep_assert_held(&ps2dev->serio->lock); |
51 | |
52 | do { |
53 | ps2dev->nak = 1; |
54 | ps2dev->flags |= PS2_FLAG_ACK; |
55 | |
56 | serio_continue_rx(serio: ps2dev->serio); |
57 | |
58 | error = serio_write(serio: ps2dev->serio, data: byte); |
59 | if (error) |
60 | dev_dbg(&ps2dev->serio->dev, |
61 | "failed to write %#02x: %d\n" , byte, error); |
62 | else |
63 | wait_event_timeout(ps2dev->wait, |
64 | !(ps2dev->flags & PS2_FLAG_ACK), |
65 | msecs_to_jiffies(timeout)); |
66 | |
67 | serio_pause_rx(serio: ps2dev->serio); |
68 | } while (ps2dev->nak == PS2_RET_NAK && ++attempt < max_attempts); |
69 | |
70 | ps2dev->flags &= ~PS2_FLAG_ACK; |
71 | |
72 | if (!error) { |
73 | switch (ps2dev->nak) { |
74 | case 0: |
75 | break; |
76 | case PS2_RET_NAK: |
77 | error = -EAGAIN; |
78 | break; |
79 | case PS2_RET_ERR: |
80 | error = -EPROTO; |
81 | break; |
82 | default: |
83 | error = -EIO; |
84 | break; |
85 | } |
86 | } |
87 | |
88 | if (error || attempt > 1) |
89 | dev_dbg(&ps2dev->serio->dev, |
90 | "%02x - %d (%x), attempt %d\n" , |
91 | byte, error, ps2dev->nak, attempt); |
92 | |
93 | return error; |
94 | } |
95 | |
96 | /** |
97 | * ps2_sendbyte - sends a byte to the device and wait for acknowledgement |
98 | * @ps2dev: a PS/2 device to send the data to |
99 | * @byte: data to be sent to the device |
100 | * @timeout: timeout for sending the data and receiving an acknowledge |
101 | * |
102 | * The function doesn't handle retransmission, the caller is expected to handle |
103 | * it when needed. |
104 | * |
105 | * ps2_sendbyte() can only be called from a process context. |
106 | */ |
107 | int ps2_sendbyte(struct ps2dev *ps2dev, u8 byte, unsigned int timeout) |
108 | { |
109 | int retval; |
110 | |
111 | serio_pause_rx(serio: ps2dev->serio); |
112 | |
113 | retval = ps2_do_sendbyte(ps2dev, byte, timeout, max_attempts: 1); |
114 | dev_dbg(&ps2dev->serio->dev, "%02x - %x\n" , byte, ps2dev->nak); |
115 | |
116 | serio_continue_rx(serio: ps2dev->serio); |
117 | |
118 | return retval; |
119 | } |
120 | EXPORT_SYMBOL(ps2_sendbyte); |
121 | |
122 | /** |
123 | * ps2_begin_command - mark beginning of execution of a complex command |
124 | * @ps2dev: a PS/2 device executing the command |
125 | * |
126 | * Serializes a complex/compound command. Once command is finished |
127 | * ps2_end_command() should be called. |
128 | */ |
129 | void ps2_begin_command(struct ps2dev *ps2dev) |
130 | { |
131 | struct mutex *m = ps2dev->serio->ps2_cmd_mutex ?: &ps2dev->cmd_mutex; |
132 | |
133 | mutex_lock(m); |
134 | } |
135 | EXPORT_SYMBOL(ps2_begin_command); |
136 | |
137 | /** |
138 | * ps2_end_command - mark end of execution of a complex command |
139 | * @ps2dev: a PS/2 device executing the command |
140 | */ |
141 | void ps2_end_command(struct ps2dev *ps2dev) |
142 | { |
143 | struct mutex *m = ps2dev->serio->ps2_cmd_mutex ?: &ps2dev->cmd_mutex; |
144 | |
145 | mutex_unlock(lock: m); |
146 | } |
147 | EXPORT_SYMBOL(ps2_end_command); |
148 | |
149 | /** |
150 | * ps2_drain - waits for device to transmit requested number of bytes |
151 | * and discards them |
152 | * @ps2dev: the PS/2 device that should be drained |
153 | * @maxbytes: maximum number of bytes to be drained |
154 | * @timeout: time to drain the device |
155 | */ |
156 | void ps2_drain(struct ps2dev *ps2dev, size_t maxbytes, unsigned int timeout) |
157 | { |
158 | if (maxbytes > sizeof(ps2dev->cmdbuf)) { |
159 | WARN_ON(1); |
160 | maxbytes = sizeof(ps2dev->cmdbuf); |
161 | } |
162 | |
163 | ps2_begin_command(ps2dev); |
164 | |
165 | serio_pause_rx(serio: ps2dev->serio); |
166 | ps2dev->flags = PS2_FLAG_CMD; |
167 | ps2dev->cmdcnt = maxbytes; |
168 | serio_continue_rx(serio: ps2dev->serio); |
169 | |
170 | wait_event_timeout(ps2dev->wait, |
171 | !(ps2dev->flags & PS2_FLAG_CMD), |
172 | msecs_to_jiffies(timeout)); |
173 | |
174 | ps2_end_command(ps2dev); |
175 | } |
176 | EXPORT_SYMBOL(ps2_drain); |
177 | |
178 | /** |
179 | * ps2_is_keyboard_id - checks received ID byte against the list of |
180 | * known keyboard IDs |
181 | * @id_byte: data byte that should be checked |
182 | */ |
183 | bool ps2_is_keyboard_id(u8 id_byte) |
184 | { |
185 | static const u8 keyboard_ids[] = { |
186 | 0xab, /* Regular keyboards */ |
187 | 0xac, /* NCD Sun keyboard */ |
188 | 0x2b, /* Trust keyboard, translated */ |
189 | 0x5d, /* Trust keyboard */ |
190 | 0x60, /* NMB SGI keyboard, translated */ |
191 | 0x47, /* NMB SGI keyboard */ |
192 | }; |
193 | |
194 | return memchr(p: keyboard_ids, c: id_byte, size: sizeof(keyboard_ids)) != NULL; |
195 | } |
196 | EXPORT_SYMBOL(ps2_is_keyboard_id); |
197 | |
198 | /* |
199 | * ps2_adjust_timeout() is called after receiving 1st byte of command |
200 | * response and tries to reduce remaining timeout to speed up command |
201 | * completion. |
202 | */ |
203 | static int ps2_adjust_timeout(struct ps2dev *ps2dev, |
204 | unsigned int command, unsigned int timeout) |
205 | { |
206 | switch (command) { |
207 | case PS2_CMD_RESET_BAT: |
208 | /* |
209 | * Device has sent the first response byte after |
210 | * reset command, reset is thus done, so we can |
211 | * shorten the timeout. |
212 | * The next byte will come soon (keyboard) or not |
213 | * at all (mouse). |
214 | */ |
215 | if (timeout > msecs_to_jiffies(m: 100)) |
216 | timeout = msecs_to_jiffies(m: 100); |
217 | break; |
218 | |
219 | case PS2_CMD_GETID: |
220 | /* |
221 | * Microsoft Natural Elite keyboard responds to |
222 | * the GET ID command as it were a mouse, with |
223 | * a single byte. Fail the command so atkbd will |
224 | * use alternative probe to detect it. |
225 | */ |
226 | if (ps2dev->cmdbuf[1] == 0xaa) { |
227 | serio_pause_rx(serio: ps2dev->serio); |
228 | ps2dev->flags = 0; |
229 | serio_continue_rx(serio: ps2dev->serio); |
230 | timeout = 0; |
231 | } |
232 | |
233 | /* |
234 | * If device behind the port is not a keyboard there |
235 | * won't be 2nd byte of ID response. |
236 | */ |
237 | if (!ps2_is_keyboard_id(ps2dev->cmdbuf[1])) { |
238 | serio_pause_rx(serio: ps2dev->serio); |
239 | ps2dev->flags = ps2dev->cmdcnt = 0; |
240 | serio_continue_rx(serio: ps2dev->serio); |
241 | timeout = 0; |
242 | } |
243 | break; |
244 | |
245 | default: |
246 | break; |
247 | } |
248 | |
249 | return timeout; |
250 | } |
251 | |
252 | /** |
253 | * __ps2_command - send a command to PS/2 device |
254 | * @ps2dev: the PS/2 device that should execute the command |
255 | * @param: a buffer containing parameters to be sent along with the command, |
256 | * or place where the results of the command execution will be deposited, |
257 | * or both |
258 | * @command: command word that encodes the command itself, as well as number of |
259 | * additional parameter bytes that should be sent to the device and expected |
260 | * length of the command response |
261 | * |
262 | * Not serialized. Callers should use ps2_begin_command() and ps2_end_command() |
263 | * to ensure proper serialization for complex commands. |
264 | */ |
265 | int __ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command) |
266 | { |
267 | unsigned int timeout; |
268 | unsigned int send = (command >> 12) & 0xf; |
269 | unsigned int receive = (command >> 8) & 0xf; |
270 | int rc; |
271 | int i; |
272 | u8 send_param[16]; |
273 | |
274 | if (receive > sizeof(ps2dev->cmdbuf)) { |
275 | WARN_ON(1); |
276 | return -EINVAL; |
277 | } |
278 | |
279 | if (send && !param) { |
280 | WARN_ON(1); |
281 | return -EINVAL; |
282 | } |
283 | |
284 | memcpy(send_param, param, send); |
285 | |
286 | serio_pause_rx(serio: ps2dev->serio); |
287 | |
288 | ps2dev->cmdcnt = receive; |
289 | |
290 | switch (command) { |
291 | case PS2_CMD_GETID: |
292 | /* |
293 | * Some mice do not ACK the "get ID" command, prepare to |
294 | * handle this. |
295 | */ |
296 | ps2dev->flags = PS2_FLAG_WAITID; |
297 | break; |
298 | |
299 | case PS2_CMD_SETLEDS: |
300 | case PS2_CMD_EX_SETLEDS: |
301 | case PS2_CMD_SETREP: |
302 | ps2dev->flags = PS2_FLAG_PASS_NOACK; |
303 | break; |
304 | |
305 | default: |
306 | ps2dev->flags = 0; |
307 | break; |
308 | } |
309 | |
310 | if (receive) { |
311 | /* Indicate that we expect response to the command. */ |
312 | ps2dev->flags |= PS2_FLAG_CMD | PS2_FLAG_CMD1; |
313 | if (param) |
314 | for (i = 0; i < receive; i++) |
315 | ps2dev->cmdbuf[(receive - 1) - i] = param[i]; |
316 | } |
317 | |
318 | /* |
319 | * Some devices (Synaptics) perform the reset before |
320 | * ACKing the reset command, and so it can take a long |
321 | * time before the ACK arrives. |
322 | */ |
323 | timeout = command == PS2_CMD_RESET_BAT ? 1000 : 200; |
324 | |
325 | rc = ps2_do_sendbyte(ps2dev, byte: command & 0xff, timeout, max_attempts: 2); |
326 | if (rc) |
327 | goto out_reset_flags; |
328 | |
329 | /* Send command parameters, if any. */ |
330 | for (i = 0; i < send; i++) { |
331 | rc = ps2_do_sendbyte(ps2dev, byte: param[i], timeout: 200, max_attempts: 2); |
332 | if (rc) |
333 | goto out_reset_flags; |
334 | } |
335 | |
336 | serio_continue_rx(serio: ps2dev->serio); |
337 | |
338 | /* |
339 | * The reset command takes a long time to execute. |
340 | */ |
341 | timeout = msecs_to_jiffies(m: command == PS2_CMD_RESET_BAT ? 4000 : 500); |
342 | |
343 | timeout = wait_event_timeout(ps2dev->wait, |
344 | !(ps2dev->flags & PS2_FLAG_CMD1), timeout); |
345 | |
346 | if (ps2dev->cmdcnt && !(ps2dev->flags & PS2_FLAG_CMD1)) { |
347 | |
348 | timeout = ps2_adjust_timeout(ps2dev, command, timeout); |
349 | wait_event_timeout(ps2dev->wait, |
350 | !(ps2dev->flags & PS2_FLAG_CMD), timeout); |
351 | } |
352 | |
353 | serio_pause_rx(serio: ps2dev->serio); |
354 | |
355 | if (param) { |
356 | for (i = 0; i < receive; i++) |
357 | param[i] = ps2dev->cmdbuf[(receive - 1) - i]; |
358 | kmsan_unpoison_memory(address: param, size: receive); |
359 | } |
360 | |
361 | if (ps2dev->cmdcnt && |
362 | (command != PS2_CMD_RESET_BAT || ps2dev->cmdcnt != 1)) { |
363 | rc = -EPROTO; |
364 | goto out_reset_flags; |
365 | } |
366 | |
367 | rc = 0; |
368 | |
369 | out_reset_flags: |
370 | ps2dev->flags = 0; |
371 | serio_continue_rx(serio: ps2dev->serio); |
372 | |
373 | dev_dbg(&ps2dev->serio->dev, |
374 | "%02x [%*ph] - %x/%08lx [%*ph]\n" , |
375 | command & 0xff, send, send_param, |
376 | ps2dev->nak, ps2dev->flags, |
377 | receive, param ?: send_param); |
378 | |
379 | /* |
380 | * ps_command() handles resends itself, so do not leak -EAGAIN |
381 | * to the callers. |
382 | */ |
383 | return rc != -EAGAIN ? rc : -EPROTO; |
384 | } |
385 | EXPORT_SYMBOL(__ps2_command); |
386 | |
387 | /** |
388 | * ps2_command - send a command to PS/2 device |
389 | * @ps2dev: the PS/2 device that should execute the command |
390 | * @param: a buffer containing parameters to be sent along with the command, |
391 | * or place where the results of the command execution will be deposited, |
392 | * or both |
393 | * @command: command word that encodes the command itself, as well as number of |
394 | * additional parameter bytes that should be sent to the device and expected |
395 | * length of the command response |
396 | * |
397 | * Note: ps2_command() serializes the command execution so that only one |
398 | * command can be executed at a time for either individual port or the entire |
399 | * 8042 controller. |
400 | */ |
401 | int ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command) |
402 | { |
403 | int rc; |
404 | |
405 | ps2_begin_command(ps2dev); |
406 | rc = __ps2_command(ps2dev, param, command); |
407 | ps2_end_command(ps2dev); |
408 | |
409 | return rc; |
410 | } |
411 | EXPORT_SYMBOL(ps2_command); |
412 | |
413 | /** |
414 | * ps2_sliced_command - sends an extended PS/2 command to a mouse |
415 | * @ps2dev: the PS/2 device that should execute the command |
416 | * @command: command byte |
417 | * |
418 | * The command is sent using "sliced" syntax understood by advanced devices, |
419 | * such as Logitech or Synaptics touchpads. The command is encoded as: |
420 | * 0xE6 0xE8 rr 0xE8 ss 0xE8 tt 0xE8 uu where (rr*64)+(ss*16)+(tt*4)+uu |
421 | * is the command. |
422 | */ |
423 | int ps2_sliced_command(struct ps2dev *ps2dev, u8 command) |
424 | { |
425 | int i; |
426 | int retval; |
427 | |
428 | ps2_begin_command(ps2dev); |
429 | |
430 | retval = __ps2_command(ps2dev, NULL, PS2_CMD_SETSCALE11); |
431 | if (retval) |
432 | goto out; |
433 | |
434 | for (i = 6; i >= 0; i -= 2) { |
435 | u8 d = (command >> i) & 3; |
436 | retval = __ps2_command(ps2dev, &d, PS2_CMD_SETRES); |
437 | if (retval) |
438 | break; |
439 | } |
440 | |
441 | out: |
442 | dev_dbg(&ps2dev->serio->dev, "%02x - %d\n" , command, retval); |
443 | ps2_end_command(ps2dev); |
444 | return retval; |
445 | } |
446 | EXPORT_SYMBOL(ps2_sliced_command); |
447 | |
448 | /** |
449 | * ps2_init - initializes ps2dev structure |
450 | * @ps2dev: structure to be initialized |
451 | * @serio: serio port associated with the PS/2 device |
452 | * @pre_receive_handler: validation handler to check basic communication state |
453 | * @receive_handler: main protocol handler |
454 | * |
455 | * Prepares ps2dev structure for use in drivers for PS/2 devices. |
456 | */ |
457 | void ps2_init(struct ps2dev *ps2dev, struct serio *serio, |
458 | ps2_pre_receive_handler_t pre_receive_handler, |
459 | ps2_receive_handler_t receive_handler) |
460 | { |
461 | ps2dev->pre_receive_handler = pre_receive_handler; |
462 | ps2dev->receive_handler = receive_handler; |
463 | |
464 | mutex_init(&ps2dev->cmd_mutex); |
465 | lockdep_set_subclass(&ps2dev->cmd_mutex, serio->depth); |
466 | init_waitqueue_head(&ps2dev->wait); |
467 | ps2dev->serio = serio; |
468 | serio_set_drvdata(serio, data: ps2dev); |
469 | } |
470 | EXPORT_SYMBOL(ps2_init); |
471 | |
472 | /* |
473 | * ps2_handle_response() stores device's response to a command and notifies |
474 | * the process waiting for completion of the command. Note that there is a |
475 | * distinction between waiting for the first byte of the response, and |
476 | * waiting for subsequent bytes. It is done so that callers could shorten |
477 | * timeouts once first byte of response is received. |
478 | */ |
479 | static void ps2_handle_response(struct ps2dev *ps2dev, u8 data) |
480 | { |
481 | if (ps2dev->cmdcnt) |
482 | ps2dev->cmdbuf[--ps2dev->cmdcnt] = data; |
483 | |
484 | if (ps2dev->flags & PS2_FLAG_CMD1) { |
485 | ps2dev->flags &= ~PS2_FLAG_CMD1; |
486 | if (ps2dev->cmdcnt) |
487 | wake_up(&ps2dev->wait); |
488 | } |
489 | |
490 | if (!ps2dev->cmdcnt) { |
491 | ps2dev->flags &= ~PS2_FLAG_CMD; |
492 | wake_up(&ps2dev->wait); |
493 | } |
494 | } |
495 | |
496 | /* |
497 | * ps2_handle_ack() processes ACK/NAK of a command from a PS/2 device, |
498 | * possibly applying workarounds for mice not acknowledging the "get ID" |
499 | * command. |
500 | */ |
501 | static void ps2_handle_ack(struct ps2dev *ps2dev, u8 data) |
502 | { |
503 | switch (data) { |
504 | case PS2_RET_ACK: |
505 | ps2dev->nak = 0; |
506 | break; |
507 | |
508 | case PS2_RET_NAK: |
509 | ps2dev->flags |= PS2_FLAG_NAK; |
510 | ps2dev->nak = PS2_RET_NAK; |
511 | break; |
512 | |
513 | case PS2_RET_ERR: |
514 | if (ps2dev->flags & PS2_FLAG_NAK) { |
515 | ps2dev->flags &= ~PS2_FLAG_NAK; |
516 | ps2dev->nak = PS2_RET_ERR; |
517 | break; |
518 | } |
519 | fallthrough; |
520 | |
521 | /* |
522 | * Workaround for mice which don't ACK the Get ID command. |
523 | * These are valid mouse IDs that we recognize. |
524 | */ |
525 | case 0x00: |
526 | case 0x03: |
527 | case 0x04: |
528 | if (ps2dev->flags & PS2_FLAG_WAITID) { |
529 | ps2dev->nak = 0; |
530 | break; |
531 | } |
532 | fallthrough; |
533 | default: |
534 | /* |
535 | * Do not signal errors if we get unexpected reply while |
536 | * waiting for an ACK to the initial (first) command byte: |
537 | * the device might not be quiesced yet and continue |
538 | * delivering data. For certain commands (such as set leds and |
539 | * set repeat rate) that can be used during normal device |
540 | * operation, we even pass this data byte to the normal receive |
541 | * handler. |
542 | * Note that we reset PS2_FLAG_WAITID flag, so the workaround |
543 | * for mice not acknowledging the Get ID command only triggers |
544 | * on the 1st byte; if device spews data we really want to see |
545 | * a real ACK from it. |
546 | */ |
547 | dev_dbg(&ps2dev->serio->dev, "unexpected %#02x\n" , data); |
548 | if (ps2dev->flags & PS2_FLAG_PASS_NOACK) |
549 | ps2dev->receive_handler(ps2dev, data); |
550 | ps2dev->flags &= ~(PS2_FLAG_WAITID | PS2_FLAG_PASS_NOACK); |
551 | return; |
552 | } |
553 | |
554 | if (!ps2dev->nak) |
555 | ps2dev->flags &= ~PS2_FLAG_NAK; |
556 | |
557 | ps2dev->flags &= ~PS2_FLAG_ACK; |
558 | |
559 | if (!ps2dev->nak && data != PS2_RET_ACK) |
560 | ps2_handle_response(ps2dev, data); |
561 | else |
562 | wake_up(&ps2dev->wait); |
563 | } |
564 | |
565 | /* |
566 | * Clears state of PS/2 device after communication error by resetting majority |
567 | * of flags and waking up waiters, if any. |
568 | */ |
569 | static void ps2_cleanup(struct ps2dev *ps2dev) |
570 | { |
571 | unsigned long old_flags = ps2dev->flags; |
572 | |
573 | /* reset all flags except last nak */ |
574 | ps2dev->flags &= PS2_FLAG_NAK; |
575 | |
576 | if (old_flags & PS2_FLAG_ACK) |
577 | ps2dev->nak = 1; |
578 | |
579 | if (old_flags & (PS2_FLAG_ACK | PS2_FLAG_CMD)) |
580 | wake_up(&ps2dev->wait); |
581 | } |
582 | |
583 | /** |
584 | * ps2_interrupt - common interrupt handler for PS/2 devices |
585 | * @serio: serio port for the device |
586 | * @data: a data byte received from the device |
587 | * @flags: flags such as %SERIO_PARITY or %SERIO_TIMEOUT indicating state of |
588 | * the data transfer |
589 | * |
590 | * ps2_interrupt() invokes pre-receive handler, optionally handles command |
591 | * acknowledgement and response from the device, and finally passes the data |
592 | * to the main protocol handler for future processing. |
593 | */ |
594 | irqreturn_t ps2_interrupt(struct serio *serio, u8 data, unsigned int flags) { |
595 | struct ps2dev *ps2dev = serio_get_drvdata(serio); |
596 | enum ps2_disposition rc; |
597 | |
598 | rc = ps2dev->pre_receive_handler(ps2dev, data, flags); |
599 | switch (rc) { |
600 | case PS2_ERROR: |
601 | ps2_cleanup(ps2dev); |
602 | break; |
603 | |
604 | case PS2_IGNORE: |
605 | break; |
606 | |
607 | case PS2_PROCESS: |
608 | if (ps2dev->flags & PS2_FLAG_ACK) |
609 | ps2_handle_ack(ps2dev, data); |
610 | else if (ps2dev->flags & PS2_FLAG_CMD) |
611 | ps2_handle_response(ps2dev, data); |
612 | else |
613 | ps2dev->receive_handler(ps2dev, data); |
614 | break; |
615 | } |
616 | |
617 | return IRQ_HANDLED; |
618 | } |
619 | EXPORT_SYMBOL(ps2_interrupt); |
620 | |
621 | MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>" ); |
622 | MODULE_DESCRIPTION("PS/2 driver library" ); |
623 | MODULE_LICENSE("GPL" ); |
624 | |