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

Configure Feed

Select the types of activity you want to include in your feed.

Input: libps2 - introduce common interrupt handler

Instead of exposing inner workings of libps2 to drivers such as atkbd and
psmouse, have them define pre-receive and receive callbacks, and provide a
common handler that can be used with underlying serio port.

While at this add kerneldoc to the module.

Link: https://lore.kernel.org/r/ZGK81cxqjr/KS1kA@google.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

+276 -159
+53 -40
drivers/input/keyboard/atkbd.c
··· 399 399 } 400 400 401 401 /* 402 - * atkbd_interrupt(). Here takes place processing of data received from 403 - * the keyboard into events. 402 + * Tries to handle frame or parity error by requesting the keyboard controller 403 + * to resend the last byte. This historically not done on x86 as controllers 404 + * there typically do not implement this command. 404 405 */ 405 - 406 - static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, 407 - unsigned int flags) 406 + static bool __maybe_unused atkbd_handle_frame_error(struct ps2dev *ps2dev, 407 + u8 data, unsigned int flags) 408 408 { 409 - struct atkbd *atkbd = atkbd_from_serio(serio); 409 + struct atkbd *atkbd = container_of(ps2dev, struct atkbd, ps2dev); 410 + struct serio *serio = ps2dev->serio; 411 + 412 + if ((flags & (SERIO_FRAME | SERIO_PARITY)) && 413 + (~flags & SERIO_TIMEOUT) && 414 + !atkbd->resend && atkbd->write) { 415 + dev_warn(&serio->dev, "Frame/parity error: %02x\n", flags); 416 + serio_write(serio, ATKBD_CMD_RESEND); 417 + atkbd->resend = true; 418 + return true; 419 + } 420 + 421 + if (!flags && data == ATKBD_RET_ACK) 422 + atkbd->resend = false; 423 + 424 + return false; 425 + } 426 + 427 + static enum ps2_disposition atkbd_pre_receive_byte(struct ps2dev *ps2dev, 428 + u8 data, unsigned int flags) 429 + { 430 + struct serio *serio = ps2dev->serio; 431 + 432 + dev_dbg(&serio->dev, "Received %02x flags %02x\n", data, flags); 433 + 434 + #if !defined(__i386__) && !defined (__x86_64__) 435 + if (atkbd_handle_frame_error(ps2dev, data, flags)) 436 + return PS2_IGNORE; 437 + #endif 438 + 439 + return PS2_PROCESS; 440 + } 441 + 442 + static void atkbd_receive_byte(struct ps2dev *ps2dev, u8 data) 443 + { 444 + struct serio *serio = ps2dev->serio; 445 + struct atkbd *atkbd = container_of(ps2dev, struct atkbd, ps2dev); 410 446 struct input_dev *dev = atkbd->dev; 411 447 unsigned int code = data; 412 448 int scroll = 0, hscroll = 0, click = -1; 413 449 int value; 414 450 unsigned short keycode; 415 451 416 - dev_dbg(&serio->dev, "Received %02x flags %02x\n", data, flags); 417 - 418 - #if !defined(__i386__) && !defined (__x86_64__) 419 - if ((flags & (SERIO_FRAME | SERIO_PARITY)) && (~flags & SERIO_TIMEOUT) && !atkbd->resend && atkbd->write) { 420 - dev_warn(&serio->dev, "Frame/parity error: %02x\n", flags); 421 - serio_write(serio, ATKBD_CMD_RESEND); 422 - atkbd->resend = true; 423 - goto out; 424 - } 425 - 426 - if (!flags && data == ATKBD_RET_ACK) 427 - atkbd->resend = false; 428 - #endif 429 - 430 - if (unlikely(atkbd->ps2dev.flags & PS2_FLAG_ACK)) 431 - if (ps2_handle_ack(&atkbd->ps2dev, data)) 432 - goto out; 433 - 434 - if (unlikely(atkbd->ps2dev.flags & PS2_FLAG_CMD)) 435 - if (ps2_handle_response(&atkbd->ps2dev, data)) 436 - goto out; 437 - 438 452 pm_wakeup_event(&serio->dev, 0); 439 453 440 454 if (!atkbd->enabled) 441 - goto out; 455 + return; 442 456 443 457 input_event(dev, EV_MSC, MSC_RAW, code); 444 458 ··· 474 460 case ATKBD_RET_BAT: 475 461 atkbd->enabled = false; 476 462 serio_reconnect(atkbd->ps2dev.serio); 477 - goto out; 463 + return; 478 464 case ATKBD_RET_EMUL0: 479 465 atkbd->emul = 1; 480 - goto out; 466 + return; 481 467 case ATKBD_RET_EMUL1: 482 468 atkbd->emul = 2; 483 - goto out; 469 + return; 484 470 case ATKBD_RET_RELEASE: 485 471 atkbd->release = true; 486 - goto out; 472 + return; 487 473 case ATKBD_RET_ACK: 488 474 case ATKBD_RET_NAK: 489 475 if (printk_ratelimit()) ··· 491 477 "Spurious %s on %s. " 492 478 "Some program might be trying to access hardware directly.\n", 493 479 data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys); 494 - goto out; 480 + return; 495 481 case ATKBD_RET_ERR: 496 482 atkbd->err_count++; 497 483 dev_dbg(&serio->dev, "Keyboard on %s reports too many keys pressed.\n", 498 484 serio->phys); 499 - goto out; 485 + return; 500 486 } 501 487 502 488 code = atkbd_compat_scancode(atkbd, code); 503 489 504 490 if (atkbd->emul && --atkbd->emul) 505 - goto out; 491 + return; 506 492 507 493 keycode = atkbd->keycode[code]; 508 494 ··· 578 564 } 579 565 580 566 atkbd->release = false; 581 - out: 582 - return IRQ_HANDLED; 583 567 } 584 568 585 569 static int atkbd_set_repeat_rate(struct atkbd *atkbd) ··· 1241 1229 goto fail1; 1242 1230 1243 1231 atkbd->dev = dev; 1244 - ps2_init(&atkbd->ps2dev, serio); 1232 + ps2_init(&atkbd->ps2dev, serio, 1233 + atkbd_pre_receive_byte, atkbd_receive_byte); 1245 1234 INIT_DELAYED_WORK(&atkbd->event_work, atkbd_event_work); 1246 1235 mutex_init(&atkbd->mutex); 1247 1236 ··· 1398 1385 }, 1399 1386 .description = DRIVER_DESC, 1400 1387 .id_table = atkbd_serio_ids, 1401 - .interrupt = atkbd_interrupt, 1388 + .interrupt = ps2_interrupt, 1402 1389 .connect = atkbd_connect, 1403 1390 .reconnect = atkbd_reconnect, 1404 1391 .disconnect = atkbd_disconnect,
+23 -30
drivers/input/mouse/psmouse-base.c
··· 336 336 } 337 337 } 338 338 339 - /* 340 - * psmouse_interrupt() handles incoming characters, either passing them 341 - * for normal processing or gathering them as command response. 342 - */ 343 - static irqreturn_t psmouse_interrupt(struct serio *serio, 344 - u8 data, unsigned int flags) 339 + static enum ps2_disposition psmouse_pre_receive_byte(struct ps2dev *ps2dev, 340 + u8 data, 341 + unsigned int flags) 345 342 { 346 - struct psmouse *psmouse = psmouse_from_serio(serio); 343 + struct psmouse *psmouse = container_of(ps2dev, struct psmouse, ps2dev); 347 344 348 345 if (psmouse->state == PSMOUSE_IGNORE) 349 - goto out; 346 + return PS2_IGNORE; 350 347 351 348 if (unlikely((flags & SERIO_TIMEOUT) || 352 349 ((flags & SERIO_PARITY) && ··· 354 357 "bad data from KBC -%s%s\n", 355 358 flags & SERIO_TIMEOUT ? " timeout" : "", 356 359 flags & SERIO_PARITY ? " bad parity" : ""); 357 - ps2_cmd_aborted(&psmouse->ps2dev); 358 - goto out; 360 + return PS2_ERROR; 359 361 } 360 362 361 363 if (flags & SERIO_OOB_DATA) { 362 364 psmouse_handle_oob_data(psmouse, data); 363 - goto out; 365 + return PS2_IGNORE; 364 366 } 365 367 366 - if (unlikely(psmouse->ps2dev.flags & PS2_FLAG_ACK)) 367 - if (ps2_handle_ack(&psmouse->ps2dev, data)) 368 - goto out; 368 + return PS2_PROCESS; 369 + } 369 370 370 - if (unlikely(psmouse->ps2dev.flags & PS2_FLAG_CMD)) 371 - if (ps2_handle_response(&psmouse->ps2dev, data)) 372 - goto out; 371 + static void psmouse_receive_byte(struct ps2dev *ps2dev, u8 data) 372 + { 373 + struct psmouse *psmouse = container_of(ps2dev, struct psmouse, ps2dev); 373 374 374 - pm_wakeup_event(&serio->dev, 0); 375 + pm_wakeup_event(&ps2dev->serio->dev, 0); 375 376 376 377 if (psmouse->state <= PSMOUSE_RESYNCING) 377 - goto out; 378 + return; 378 379 379 380 if (psmouse->state == PSMOUSE_ACTIVATED && 380 381 psmouse->pktcnt && time_after(jiffies, psmouse->last + HZ/2)) { ··· 381 386 psmouse->badbyte = psmouse->packet[0]; 382 387 __psmouse_set_state(psmouse, PSMOUSE_RESYNCING); 383 388 psmouse_queue_work(psmouse, &psmouse->resync_work, 0); 384 - goto out; 389 + return; 385 390 } 386 391 387 392 psmouse->packet[psmouse->pktcnt++] = data; ··· 390 395 if (unlikely(psmouse->packet[0] == PSMOUSE_RET_BAT && psmouse->pktcnt <= 2)) { 391 396 if (psmouse->pktcnt == 1) { 392 397 psmouse->last = jiffies; 393 - goto out; 398 + return; 394 399 } 395 400 396 401 if (psmouse->packet[1] == PSMOUSE_RET_ID || 397 402 (psmouse->protocol->type == PSMOUSE_HGPK && 398 403 psmouse->packet[1] == PSMOUSE_RET_BAT)) { 399 404 __psmouse_set_state(psmouse, PSMOUSE_IGNORE); 400 - serio_reconnect(serio); 401 - goto out; 405 + serio_reconnect(ps2dev->serio); 406 + return; 402 407 } 403 408 404 409 /* Not a new device, try processing first byte normally */ 405 410 psmouse->pktcnt = 1; 406 411 if (psmouse_handle_byte(psmouse)) 407 - goto out; 412 + return; 408 413 409 414 psmouse->packet[psmouse->pktcnt++] = data; 410 415 } ··· 419 424 psmouse->badbyte = psmouse->packet[0]; 420 425 __psmouse_set_state(psmouse, PSMOUSE_RESYNCING); 421 426 psmouse_queue_work(psmouse, &psmouse->resync_work, 0); 422 - goto out; 427 + return; 423 428 } 424 429 425 430 psmouse->last = jiffies; 426 431 psmouse_handle_byte(psmouse); 427 - 428 - out: 429 - return IRQ_HANDLED; 430 432 } 431 433 432 434 /* ··· 1596 1604 if (!psmouse || !input_dev) 1597 1605 goto err_free; 1598 1606 1599 - ps2_init(&psmouse->ps2dev, serio); 1607 + ps2_init(&psmouse->ps2dev, serio, 1608 + psmouse_pre_receive_byte, psmouse_receive_byte); 1600 1609 INIT_DELAYED_WORK(&psmouse->resync_work, psmouse_resync); 1601 1610 psmouse->dev = input_dev; 1602 1611 snprintf(psmouse->phys, sizeof(psmouse->phys), "%s/input0", serio->phys); ··· 1779 1786 }, 1780 1787 .description = DRIVER_DESC, 1781 1788 .id_table = psmouse_serio_ids, 1782 - .interrupt = psmouse_interrupt, 1789 + .interrupt = ps2_interrupt, 1783 1790 .connect = psmouse_connect, 1784 1791 .reconnect = psmouse_reconnect, 1785 1792 .fast_reconnect = psmouse_fast_reconnect,
+162 -66
drivers/input/serio/libps2.c
··· 19 19 20 20 #define DRIVER_DESC "PS/2 driver library" 21 21 22 - MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>"); 23 - MODULE_DESCRIPTION("PS/2 driver library"); 24 - MODULE_LICENSE("GPL"); 22 + #define PS2_CMD_SETSCALE11 0x00e6 23 + #define PS2_CMD_SETRES 0x10e8 24 + #define PS2_CMD_GETID 0x02f2 25 + #define PS2_CMD_RESET_BAT 0x02ff 26 + 27 + #define PS2_RET_BAT 0xaa 28 + #define PS2_RET_ID 0x00 29 + #define PS2_RET_ACK 0xfa 30 + #define PS2_RET_NAK 0xfe 31 + #define PS2_RET_ERR 0xfc 32 + 33 + #define PS2_FLAG_ACK BIT(0) /* Waiting for ACK/NAK */ 34 + #define PS2_FLAG_CMD BIT(1) /* Waiting for a command to finish */ 35 + #define PS2_FLAG_CMD1 BIT(2) /* Waiting for the first byte of command response */ 36 + #define PS2_FLAG_WAITID BIT(3) /* Command executing is GET ID */ 37 + #define PS2_FLAG_NAK BIT(4) /* Last transmission was NAKed */ 25 38 26 39 static int ps2_do_sendbyte(struct ps2dev *ps2dev, u8 byte, 27 40 unsigned int timeout, unsigned int max_attempts) ··· 89 76 return error; 90 77 } 91 78 92 - /* 93 - * ps2_sendbyte() sends a byte to the device and waits for acknowledge. 94 - * It doesn't handle retransmission, the caller is expected to handle 79 + /** 80 + * ps2_sendbyte - sends a byte to the device and wait for acknowledgement 81 + * @ps2dev: a PS/2 device to send the data to 82 + * @byte: data to be sent to the device 83 + * @timeout: timeout for sending the data and receiving an acknowledge 84 + * 85 + * The function doesn't handle retransmission, the caller is expected to handle 95 86 * it when needed. 96 87 * 97 88 * ps2_sendbyte() can only be called from a process context. 98 89 */ 99 - 100 90 int ps2_sendbyte(struct ps2dev *ps2dev, u8 byte, unsigned int timeout) 101 91 { 102 92 int retval; ··· 115 99 } 116 100 EXPORT_SYMBOL(ps2_sendbyte); 117 101 102 + /** 103 + * ps2_begin_command - mark beginning of execution of a complex command 104 + * @ps2dev: a PS/2 device executing the command 105 + * 106 + * Serializes a complex/compound command. Once command is finished 107 + * ps2_end_command() should be called. 108 + */ 118 109 void ps2_begin_command(struct ps2dev *ps2dev) 119 110 { 120 111 struct mutex *m = ps2dev->serio->ps2_cmd_mutex ?: &ps2dev->cmd_mutex; ··· 130 107 } 131 108 EXPORT_SYMBOL(ps2_begin_command); 132 109 110 + /** 111 + * ps2_end_command - mark end of execution of a complex command 112 + * @ps2dev: a PS/2 device executing the command 113 + */ 133 114 void ps2_end_command(struct ps2dev *ps2dev) 134 115 { 135 116 struct mutex *m = ps2dev->serio->ps2_cmd_mutex ?: &ps2dev->cmd_mutex; ··· 142 115 } 143 116 EXPORT_SYMBOL(ps2_end_command); 144 117 145 - /* 146 - * ps2_drain() waits for device to transmit requested number of bytes 147 - * and discards them. 118 + /** 119 + * ps2_drain - waits for device to transmit requested number of bytes 120 + * and discards them 121 + * @ps2dev: the PS/2 device that should be drained 122 + * @maxbytes: maximum number of bytes to be drained 123 + * @timeout: time to drain the device 148 124 */ 149 - 150 125 void ps2_drain(struct ps2dev *ps2dev, size_t maxbytes, unsigned int timeout) 151 126 { 152 127 if (maxbytes > sizeof(ps2dev->cmdbuf)) { ··· 171 142 } 172 143 EXPORT_SYMBOL(ps2_drain); 173 144 174 - /* 175 - * ps2_is_keyboard_id() checks received ID byte against the list of 176 - * known keyboard IDs. 145 + /** 146 + * ps2_is_keyboard_id - checks received ID byte against the list of 147 + * known keyboard IDs 148 + * @id_byte: data byte that should be checked 177 149 */ 178 - 179 150 bool ps2_is_keyboard_id(u8 id_byte) 180 151 { 181 152 static const u8 keyboard_ids[] = { ··· 196 167 * response and tries to reduce remaining timeout to speed up command 197 168 * completion. 198 169 */ 199 - 200 170 static int ps2_adjust_timeout(struct ps2dev *ps2dev, 201 171 unsigned int command, unsigned int timeout) 202 172 { ··· 245 217 return timeout; 246 218 } 247 219 248 - /* 249 - * ps2_command() sends a command and its parameters to the mouse, 250 - * then waits for the response and puts it in the param array. 220 + /** 221 + * __ps2_command - send a command to PS/2 device 222 + * @ps2dev: the PS/2 device that should execute the command 223 + * @param: a buffer containing parameters to be sent along with the command, 224 + * or place where the results of the command execution will be deposited, 225 + * or both 226 + * @command: command word that encodes the command itself, as well as number of 227 + * additional parameter bytes that should be sent to the device and expected 228 + * length of the command response 251 229 * 252 - * ps2_command() can only be called from a process context 230 + * Not serialized. Callers should use ps2_begin_command() and ps2_end_command() 231 + * to ensure proper serialization for complex commands. 253 232 */ 254 - 255 233 int __ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command) 256 234 { 257 235 unsigned int timeout; ··· 361 327 } 362 328 EXPORT_SYMBOL(__ps2_command); 363 329 330 + /** 331 + * ps2_command - send a command to PS/2 device 332 + * @ps2dev: the PS/2 device that should execute the command 333 + * @param: a buffer containing parameters to be sent along with the command, 334 + * or place where the results of the command execution will be deposited, 335 + * or both 336 + * @command: command word that encodes the command itself, as well as number of 337 + * additional parameter bytes that should be sent to the device and expected 338 + * length of the command response 339 + * 340 + * Note: ps2_command() serializes the command execution so that only one 341 + * command can be executed at a time for either individual port or the entire 342 + * 8042 controller. 343 + */ 364 344 int ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command) 365 345 { 366 346 int rc; ··· 387 339 } 388 340 EXPORT_SYMBOL(ps2_command); 389 341 390 - /* 391 - * ps2_sliced_command() sends an extended PS/2 command to the mouse 392 - * using sliced syntax, understood by advanced devices, such as Logitech 393 - * or Synaptics touchpads. The command is encoded as: 342 + /** 343 + * ps2_sliced_command - sends an extended PS/2 command to a mouse 344 + * @ps2dev: the PS/2 device that should execute the command 345 + * @command: command byte 346 + * 347 + * The command is sent using "sliced" syntax understood by advanced devices, 348 + * such as Logitech or Synaptics touchpads. The command is encoded as: 394 349 * 0xE6 0xE8 rr 0xE8 ss 0xE8 tt 0xE8 uu where (rr*64)+(ss*16)+(tt*4)+uu 395 350 * is the command. 396 351 */ 397 - 398 352 int ps2_sliced_command(struct ps2dev *ps2dev, u8 command) 399 353 { 400 354 int i; ··· 422 372 } 423 373 EXPORT_SYMBOL(ps2_sliced_command); 424 374 425 - /* 426 - * ps2_init() initializes ps2dev structure 375 + /** 376 + * ps2_init - initializes ps2dev structure 377 + * @ps2dev: structure to be initialized 378 + * @serio: serio port associated with the PS/2 device 379 + * @pre_receive_handler: validation handler to check basic communication state 380 + * @receive_handler: main protocol handler 381 + * 382 + * Prepares ps2dev structure for use in drivers for PS/2 devices. 427 383 */ 428 - 429 - void ps2_init(struct ps2dev *ps2dev, struct serio *serio) 384 + void ps2_init(struct ps2dev *ps2dev, struct serio *serio, 385 + ps2_pre_receive_handler_t pre_receive_handler, 386 + ps2_receive_handler_t receive_handler) 430 387 { 388 + ps2dev->pre_receive_handler = pre_receive_handler; 389 + ps2dev->receive_handler = receive_handler; 390 + 431 391 mutex_init(&ps2dev->cmd_mutex); 432 392 lockdep_set_subclass(&ps2dev->cmd_mutex, serio->depth); 433 393 init_waitqueue_head(&ps2dev->wait); ··· 447 387 EXPORT_SYMBOL(ps2_init); 448 388 449 389 /* 450 - * ps2_handle_ack() is supposed to be used in interrupt handler 451 - * to properly process ACK/NAK of a command from a PS/2 device. 390 + * ps2_handle_response() stores device's response to a command and notifies 391 + * the process waiting for completion of the command. Note that there is a 392 + * distinction between waiting for the first byte of the response, and 393 + * waiting for subsequent bytes. It is done so that callers could shorten 394 + * timeouts once first byte of response is received. 452 395 */ 396 + static void ps2_handle_response(struct ps2dev *ps2dev, u8 data) 397 + { 398 + if (ps2dev->cmdcnt) 399 + ps2dev->cmdbuf[--ps2dev->cmdcnt] = data; 453 400 454 - bool ps2_handle_ack(struct ps2dev *ps2dev, u8 data) 401 + if (ps2dev->flags & PS2_FLAG_CMD1) { 402 + ps2dev->flags &= ~PS2_FLAG_CMD1; 403 + if (ps2dev->cmdcnt) 404 + wake_up(&ps2dev->wait); 405 + } 406 + 407 + if (!ps2dev->cmdcnt) { 408 + ps2dev->flags &= ~PS2_FLAG_CMD; 409 + wake_up(&ps2dev->wait); 410 + } 411 + } 412 + 413 + /* 414 + * ps2_handle_ack() processes ACK/NAK of a command from a PS/2 device, 415 + * possibly applying workarounds for mice not acknowledging the "get ID" 416 + * command. 417 + */ 418 + static void ps2_handle_ack(struct ps2dev *ps2dev, u8 data) 455 419 { 456 420 switch (data) { 457 421 case PS2_RET_ACK: ··· 520 436 */ 521 437 dev_dbg(&ps2dev->serio->dev, "unexpected %#02x\n", data); 522 438 ps2dev->flags &= ~PS2_FLAG_WAITID; 523 - return true; 439 + return; 524 440 } 525 441 526 442 if (!ps2dev->nak) 527 443 ps2dev->flags &= ~PS2_FLAG_NAK; 528 444 529 445 ps2dev->flags &= ~PS2_FLAG_ACK; 530 - wake_up(&ps2dev->wait); 531 446 532 447 if (!ps2dev->nak && data != PS2_RET_ACK) 533 448 ps2_handle_response(ps2dev, data); 534 - 535 - return true; 536 - } 537 - EXPORT_SYMBOL(ps2_handle_ack); 538 - 539 - /* 540 - * ps2_handle_response() is supposed to be used in interrupt handler 541 - * to properly store device's response to a command and notify process 542 - * waiting for completion of the command. 543 - */ 544 - 545 - bool ps2_handle_response(struct ps2dev *ps2dev, u8 data) 546 - { 547 - if (ps2dev->cmdcnt) 548 - ps2dev->cmdbuf[--ps2dev->cmdcnt] = data; 549 - 550 - if (ps2dev->flags & PS2_FLAG_CMD1) { 551 - ps2dev->flags &= ~PS2_FLAG_CMD1; 552 - if (ps2dev->cmdcnt) 553 - wake_up(&ps2dev->wait); 554 - } 555 - 556 - if (!ps2dev->cmdcnt) { 557 - ps2dev->flags &= ~PS2_FLAG_CMD; 449 + else 558 450 wake_up(&ps2dev->wait); 559 - } 560 - 561 - return true; 562 451 } 563 - EXPORT_SYMBOL(ps2_handle_response); 564 452 565 453 /* 566 454 * Clears state of PS/2 device after communication error by resetting majority 567 455 * of flags and waking up waiters, if any. 568 456 */ 569 - void ps2_cmd_aborted(struct ps2dev *ps2dev) 457 + static void ps2_cleanup(struct ps2dev *ps2dev) 570 458 { 571 459 unsigned long old_flags = ps2dev->flags; 572 460 ··· 550 494 551 495 if (old_flags & (PS2_FLAG_ACK | PS2_FLAG_CMD)) 552 496 wake_up(&ps2dev->wait); 553 - 554 497 } 555 - EXPORT_SYMBOL(ps2_cmd_aborted); 498 + 499 + /** 500 + * ps2_interrupt - common interrupt handler for PS/2 devices 501 + * @serio: serio port for the device 502 + * @data: a data byte received from the device 503 + * @flags: flags such as %SERIO_PARITY or %SERIO_TIMEOUT indicating state of 504 + * the data transfer 505 + * 506 + * ps2_interrupt() invokes pre-receive handler, optionally handles command 507 + * acknowledgement and response from the device, and finally passes the data 508 + * to the main protocol handler for future processing. 509 + */ 510 + irqreturn_t ps2_interrupt(struct serio *serio, u8 data, unsigned int flags) { 511 + struct ps2dev *ps2dev = serio_get_drvdata(serio); 512 + enum ps2_disposition rc; 513 + 514 + rc = ps2dev->pre_receive_handler(ps2dev, data, flags); 515 + switch (rc) { 516 + case PS2_ERROR: 517 + ps2_cleanup(ps2dev); 518 + break; 519 + 520 + case PS2_IGNORE: 521 + break; 522 + 523 + case PS2_PROCESS: 524 + if (ps2dev->flags & PS2_FLAG_ACK) 525 + ps2_handle_ack(ps2dev, data); 526 + else if (ps2dev->flags & PS2_FLAG_CMD) 527 + ps2_handle_response(ps2dev, data); 528 + else 529 + ps2dev->receive_handler(ps2dev, data); 530 + break; 531 + } 532 + 533 + return IRQ_HANDLED; 534 + } 535 + EXPORT_SYMBOL(ps2_interrupt); 536 + 537 + MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>"); 538 + MODULE_DESCRIPTION("PS/2 driver library"); 539 + MODULE_LICENSE("GPL");
+38 -23
include/linux/libps2.h
··· 8 8 */ 9 9 10 10 #include <linux/bitops.h> 11 + #include <linux/interrupt.h> 11 12 #include <linux/mutex.h> 12 13 #include <linux/types.h> 13 14 #include <linux/wait.h> 14 15 15 - #define PS2_CMD_SETSCALE11 0x00e6 16 - #define PS2_CMD_SETRES 0x10e8 17 - #define PS2_CMD_GETID 0x02f2 18 - #define PS2_CMD_RESET_BAT 0x02ff 16 + struct ps2dev; 19 17 20 - #define PS2_RET_BAT 0xaa 21 - #define PS2_RET_ID 0x00 22 - #define PS2_RET_ACK 0xfa 23 - #define PS2_RET_NAK 0xfe 24 - #define PS2_RET_ERR 0xfc 18 + /** 19 + * enum ps2_disposition - indicates how received byte should be handled 20 + * @PS2_PROCESS: pass to the main protocol handler, process normally 21 + * @PS2_IGNORE: skip the byte 22 + * @PS2_ERROR: do not process the byte, abort command in progress 23 + */ 24 + enum ps2_disposition { 25 + PS2_PROCESS, 26 + PS2_IGNORE, 27 + PS2_ERROR, 28 + }; 25 29 26 - #define PS2_FLAG_ACK BIT(0) /* Waiting for ACK/NAK */ 27 - #define PS2_FLAG_CMD BIT(1) /* Waiting for a command to finish */ 28 - #define PS2_FLAG_CMD1 BIT(2) /* Waiting for the first byte of command response */ 29 - #define PS2_FLAG_WAITID BIT(3) /* Command executing is GET ID */ 30 - #define PS2_FLAG_NAK BIT(4) /* Last transmission was NAKed */ 30 + typedef enum ps2_disposition (*ps2_pre_receive_handler_t)(struct ps2dev *, u8, 31 + unsigned int); 32 + typedef void (*ps2_receive_handler_t)(struct ps2dev *, u8); 31 33 34 + /** 35 + * struct ps2dev - represents a device using PS/2 protocol 36 + * @serio: a serio port used by the PS/2 device 37 + * @cmd_mutex: a mutex ensuring that only one command is executing at a time 38 + * @wait: a waitqueue used to signal completion from the serio interrupt handler 39 + * @flags: various internal flags indicating stages of PS/2 command execution 40 + * @cmdbuf: buffer holding command response 41 + * @cmdcnt: outstanding number of bytes of the command response 42 + * @nak: a byte transmitted by the device when it refuses command 43 + * @pre_receive_handler: checks communication errors and returns disposition 44 + * (&enum ps2_disposition) of the received data byte 45 + * @receive_handler: main handler of particular PS/2 protocol, such as keyboard 46 + * or mouse protocol 47 + */ 32 48 struct ps2dev { 33 49 struct serio *serio; 34 - 35 - /* Ensures that only one command is executing at a time */ 36 50 struct mutex cmd_mutex; 37 - 38 - /* Used to signal completion from interrupt handler */ 39 51 wait_queue_head_t wait; 40 - 41 52 unsigned long flags; 42 53 u8 cmdbuf[8]; 43 54 u8 cmdcnt; 44 55 u8 nak; 56 + 57 + ps2_pre_receive_handler_t pre_receive_handler; 58 + ps2_receive_handler_t receive_handler; 45 59 }; 46 60 47 - void ps2_init(struct ps2dev *ps2dev, struct serio *serio); 61 + void ps2_init(struct ps2dev *ps2dev, struct serio *serio, 62 + ps2_pre_receive_handler_t pre_receive_handler, 63 + ps2_receive_handler_t receive_handler); 48 64 int ps2_sendbyte(struct ps2dev *ps2dev, u8 byte, unsigned int timeout); 49 65 void ps2_drain(struct ps2dev *ps2dev, size_t maxbytes, unsigned int timeout); 50 66 void ps2_begin_command(struct ps2dev *ps2dev); ··· 68 52 int __ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command); 69 53 int ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command); 70 54 int ps2_sliced_command(struct ps2dev *ps2dev, u8 command); 71 - bool ps2_handle_ack(struct ps2dev *ps2dev, u8 data); 72 - bool ps2_handle_response(struct ps2dev *ps2dev, u8 data); 73 - void ps2_cmd_aborted(struct ps2dev *ps2dev); 74 55 bool ps2_is_keyboard_id(u8 id); 56 + 57 + irqreturn_t ps2_interrupt(struct serio *serio, u8 data, unsigned int flags); 75 58 76 59 #endif /* _LIBPS2_H */