LCOV - code coverage report
Current view: top level - drivers/input/serio - libps2.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 186 0.0 %
Date: 2023-08-24 13:40:31 Functions: 0 15 0.0 %

          Line data    Source code
       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           0 : 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           0 :         int attempt = 0;
      48             :         int error;
      49             : 
      50             :         lockdep_assert_held(&ps2dev->serio->lock);
      51             : 
      52             :         do {
      53           0 :                 ps2dev->nak = 1;
      54           0 :                 ps2dev->flags |= PS2_FLAG_ACK;
      55             : 
      56           0 :                 serio_continue_rx(ps2dev->serio);
      57             : 
      58           0 :                 error = serio_write(ps2dev->serio, byte);
      59           0 :                 if (error)
      60             :                         dev_dbg(&ps2dev->serio->dev,
      61             :                                 "failed to write %#02x: %d\n", byte, error);
      62             :                 else
      63           0 :                         wait_event_timeout(ps2dev->wait,
      64             :                                            !(ps2dev->flags & PS2_FLAG_ACK),
      65             :                                            msecs_to_jiffies(timeout));
      66             : 
      67           0 :                 serio_pause_rx(ps2dev->serio);
      68           0 :         } while (ps2dev->nak == PS2_RET_NAK && ++attempt < max_attempts);
      69             : 
      70           0 :         ps2dev->flags &= ~PS2_FLAG_ACK;
      71             : 
      72           0 :         if (!error) {
      73           0 :                 switch (ps2dev->nak) {
      74             :                 case 0:
      75             :                         break;
      76             :                 case PS2_RET_NAK:
      77           0 :                         error = -EAGAIN;
      78           0 :                         break;
      79             :                 case PS2_RET_ERR:
      80           0 :                         error = -EPROTO;
      81           0 :                         break;
      82             :                 default:
      83           0 :                         error = -EIO;
      84           0 :                         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           0 :         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           0 : int ps2_sendbyte(struct ps2dev *ps2dev, u8 byte, unsigned int timeout)
     108             : {
     109             :         int retval;
     110             : 
     111           0 :         serio_pause_rx(ps2dev->serio);
     112             : 
     113           0 :         retval = ps2_do_sendbyte(ps2dev, byte, timeout, 1);
     114             :         dev_dbg(&ps2dev->serio->dev, "%02x - %x\n", byte, ps2dev->nak);
     115             : 
     116           0 :         serio_continue_rx(ps2dev->serio);
     117             : 
     118           0 :         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           0 : void ps2_begin_command(struct ps2dev *ps2dev)
     130             : {
     131           0 :         struct mutex *m = ps2dev->serio->ps2_cmd_mutex ?: &ps2dev->cmd_mutex;
     132             : 
     133           0 :         mutex_lock(m);
     134           0 : }
     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           0 : void ps2_end_command(struct ps2dev *ps2dev)
     142             : {
     143           0 :         struct mutex *m = ps2dev->serio->ps2_cmd_mutex ?: &ps2dev->cmd_mutex;
     144             : 
     145           0 :         mutex_unlock(m);
     146           0 : }
     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           0 : void ps2_drain(struct ps2dev *ps2dev, size_t maxbytes, unsigned int timeout)
     157             : {
     158           0 :         if (maxbytes > sizeof(ps2dev->cmdbuf)) {
     159           0 :                 WARN_ON(1);
     160           0 :                 maxbytes = sizeof(ps2dev->cmdbuf);
     161             :         }
     162             : 
     163           0 :         ps2_begin_command(ps2dev);
     164             : 
     165           0 :         serio_pause_rx(ps2dev->serio);
     166           0 :         ps2dev->flags = PS2_FLAG_CMD;
     167           0 :         ps2dev->cmdcnt = maxbytes;
     168           0 :         serio_continue_rx(ps2dev->serio);
     169             : 
     170           0 :         wait_event_timeout(ps2dev->wait,
     171             :                            !(ps2dev->flags & PS2_FLAG_CMD),
     172             :                            msecs_to_jiffies(timeout));
     173             : 
     174           0 :         ps2_end_command(ps2dev);
     175           0 : }
     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           0 : 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           0 :         return memchr(keyboard_ids, id_byte, 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           0 : static int ps2_adjust_timeout(struct ps2dev *ps2dev,
     204             :                               unsigned int command, unsigned int timeout)
     205             : {
     206           0 :         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           0 :                 if (timeout > msecs_to_jiffies(100))
     216           0 :                         timeout = msecs_to_jiffies(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           0 :                 if (ps2dev->cmdbuf[1] == 0xaa) {
     227           0 :                         serio_pause_rx(ps2dev->serio);
     228           0 :                         ps2dev->flags = 0;
     229           0 :                         serio_continue_rx(ps2dev->serio);
     230           0 :                         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           0 :                 if (!ps2_is_keyboard_id(ps2dev->cmdbuf[1])) {
     238           0 :                         serio_pause_rx(ps2dev->serio);
     239           0 :                         ps2dev->flags = ps2dev->cmdcnt = 0;
     240           0 :                         serio_continue_rx(ps2dev->serio);
     241           0 :                         timeout = 0;
     242             :                 }
     243             :                 break;
     244             : 
     245             :         default:
     246             :                 break;
     247             :         }
     248             : 
     249           0 :         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           0 : int __ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command)
     266             : {
     267             :         unsigned int timeout;
     268           0 :         unsigned int send = (command >> 12) & 0xf;
     269           0 :         unsigned int receive = (command >> 8) & 0xf;
     270             :         int rc;
     271             :         int i;
     272             :         u8 send_param[16];
     273             : 
     274           0 :         if (receive > sizeof(ps2dev->cmdbuf)) {
     275           0 :                 WARN_ON(1);
     276           0 :                 return -EINVAL;
     277             :         }
     278             : 
     279           0 :         if (send && !param) {
     280           0 :                 WARN_ON(1);
     281           0 :                 return -EINVAL;
     282             :         }
     283             : 
     284           0 :         memcpy(send_param, param, send);
     285             : 
     286           0 :         serio_pause_rx(ps2dev->serio);
     287             : 
     288           0 :         ps2dev->cmdcnt = receive;
     289             : 
     290           0 :         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           0 :                 ps2dev->flags = PS2_FLAG_WAITID;
     297           0 :                 break;
     298             : 
     299             :         case PS2_CMD_SETLEDS:
     300             :         case PS2_CMD_EX_SETLEDS:
     301             :         case PS2_CMD_SETREP:
     302           0 :                 ps2dev->flags = PS2_FLAG_PASS_NOACK;
     303           0 :                 break;
     304             : 
     305             :         default:
     306           0 :                 ps2dev->flags = 0;
     307           0 :                 break;
     308             :         }
     309             : 
     310           0 :         if (receive) {
     311             :                 /* Indicate that we expect response to the command. */
     312           0 :                 ps2dev->flags |= PS2_FLAG_CMD | PS2_FLAG_CMD1;
     313           0 :                 if (param)
     314           0 :                         for (i = 0; i < receive; i++)
     315           0 :                                 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           0 :         timeout = command == PS2_CMD_RESET_BAT ? 1000 : 200;
     324             : 
     325           0 :         rc = ps2_do_sendbyte(ps2dev, command & 0xff, timeout, 2);
     326           0 :         if (rc)
     327             :                 goto out_reset_flags;
     328             : 
     329             :         /* Send command parameters, if any. */
     330           0 :         for (i = 0; i < send; i++) {
     331           0 :                 rc = ps2_do_sendbyte(ps2dev, param[i], 200, 2);
     332           0 :                 if (rc)
     333             :                         goto out_reset_flags;
     334             :         }
     335             : 
     336           0 :         serio_continue_rx(ps2dev->serio);
     337             : 
     338             :         /*
     339             :          * The reset command takes a long time to execute.
     340             :          */
     341           0 :         timeout = msecs_to_jiffies(command == PS2_CMD_RESET_BAT ? 4000 : 500);
     342             : 
     343           0 :         timeout = wait_event_timeout(ps2dev->wait,
     344             :                                      !(ps2dev->flags & PS2_FLAG_CMD1), timeout);
     345             : 
     346           0 :         if (ps2dev->cmdcnt && !(ps2dev->flags & PS2_FLAG_CMD1)) {
     347             : 
     348           0 :                 timeout = ps2_adjust_timeout(ps2dev, command, timeout);
     349           0 :                 wait_event_timeout(ps2dev->wait,
     350             :                                    !(ps2dev->flags & PS2_FLAG_CMD), timeout);
     351             :         }
     352             : 
     353           0 :         serio_pause_rx(ps2dev->serio);
     354             : 
     355           0 :         if (param) {
     356           0 :                 for (i = 0; i < receive; i++)
     357           0 :                         param[i] = ps2dev->cmdbuf[(receive - 1) - i];
     358             :                 kmsan_unpoison_memory(param, receive);
     359             :         }
     360             : 
     361           0 :         if (ps2dev->cmdcnt &&
     362           0 :             (command != PS2_CMD_RESET_BAT || ps2dev->cmdcnt != 1)) {
     363             :                 rc = -EPROTO;
     364             :                 goto out_reset_flags;
     365             :         }
     366             : 
     367           0 :         rc = 0;
     368             : 
     369             :  out_reset_flags:
     370           0 :         ps2dev->flags = 0;
     371           0 :         serio_continue_rx(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           0 :         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           0 : int ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command)
     402             : {
     403             :         int rc;
     404             : 
     405           0 :         ps2_begin_command(ps2dev);
     406           0 :         rc = __ps2_command(ps2dev, param, command);
     407           0 :         ps2_end_command(ps2dev);
     408             : 
     409           0 :         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           0 : int ps2_sliced_command(struct ps2dev *ps2dev, u8 command)
     424             : {
     425             :         int i;
     426             :         int retval;
     427             : 
     428           0 :         ps2_begin_command(ps2dev);
     429             : 
     430           0 :         retval = __ps2_command(ps2dev, NULL, PS2_CMD_SETSCALE11);
     431           0 :         if (retval)
     432             :                 goto out;
     433             : 
     434           0 :         for (i = 6; i >= 0; i -= 2) {
     435           0 :                 u8 d = (command >> i) & 3;
     436           0 :                 retval = __ps2_command(ps2dev, &d, PS2_CMD_SETRES);
     437           0 :                 if (retval)
     438             :                         break;
     439             :         }
     440             : 
     441             : out:
     442             :         dev_dbg(&ps2dev->serio->dev, "%02x - %d\n", command, retval);
     443           0 :         ps2_end_command(ps2dev);
     444           0 :         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           0 : 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           0 :         ps2dev->pre_receive_handler = pre_receive_handler;
     462           0 :         ps2dev->receive_handler = receive_handler;
     463             : 
     464           0 :         mutex_init(&ps2dev->cmd_mutex);
     465             :         lockdep_set_subclass(&ps2dev->cmd_mutex, serio->depth);
     466           0 :         init_waitqueue_head(&ps2dev->wait);
     467           0 :         ps2dev->serio = serio;
     468           0 :         serio_set_drvdata(serio, ps2dev);
     469           0 : }
     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           0 : static void ps2_handle_response(struct ps2dev *ps2dev, u8 data)
     480             : {
     481           0 :         if (ps2dev->cmdcnt)
     482           0 :                 ps2dev->cmdbuf[--ps2dev->cmdcnt] = data;
     483             : 
     484           0 :         if (ps2dev->flags & PS2_FLAG_CMD1) {
     485           0 :                 ps2dev->flags &= ~PS2_FLAG_CMD1;
     486           0 :                 if (ps2dev->cmdcnt)
     487           0 :                         wake_up(&ps2dev->wait);
     488             :         }
     489             : 
     490           0 :         if (!ps2dev->cmdcnt) {
     491           0 :                 ps2dev->flags &= ~PS2_FLAG_CMD;
     492           0 :                 wake_up(&ps2dev->wait);
     493             :         }
     494           0 : }
     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           0 : static void ps2_handle_ack(struct ps2dev *ps2dev, u8 data)
     502             : {
     503           0 :         switch (data) {
     504             :         case PS2_RET_ACK:
     505           0 :                 ps2dev->nak = 0;
     506           0 :                 break;
     507             : 
     508             :         case PS2_RET_NAK:
     509           0 :                 ps2dev->flags |= PS2_FLAG_NAK;
     510           0 :                 ps2dev->nak = PS2_RET_NAK;
     511           0 :                 break;
     512             : 
     513             :         case PS2_RET_ERR:
     514           0 :                 if (ps2dev->flags & PS2_FLAG_NAK) {
     515           0 :                         ps2dev->flags &= ~PS2_FLAG_NAK;
     516           0 :                         ps2dev->nak = PS2_RET_ERR;
     517           0 :                         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           0 :                 if (ps2dev->flags & PS2_FLAG_WAITID) {
     529           0 :                         ps2dev->nak = 0;
     530           0 :                         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           0 :                 if (ps2dev->flags & PS2_FLAG_PASS_NOACK)
     549           0 :                         ps2dev->receive_handler(ps2dev, data);
     550           0 :                 ps2dev->flags &= ~(PS2_FLAG_WAITID | PS2_FLAG_PASS_NOACK);
     551           0 :                 return;
     552             :         }
     553             : 
     554           0 :         if (!ps2dev->nak)
     555           0 :                 ps2dev->flags &= ~PS2_FLAG_NAK;
     556             : 
     557           0 :         ps2dev->flags &= ~PS2_FLAG_ACK;
     558             : 
     559           0 :         if (!ps2dev->nak && data != PS2_RET_ACK)
     560           0 :                 ps2_handle_response(ps2dev, data);
     561             :         else
     562           0 :                 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           0 : static void ps2_cleanup(struct ps2dev *ps2dev)
     570             : {
     571           0 :         unsigned long old_flags = ps2dev->flags;
     572             : 
     573             :         /* reset all flags except last nak */
     574           0 :         ps2dev->flags &= PS2_FLAG_NAK;
     575             : 
     576           0 :         if (old_flags & PS2_FLAG_ACK)
     577           0 :                 ps2dev->nak = 1;
     578             : 
     579           0 :         if (old_flags & (PS2_FLAG_ACK | PS2_FLAG_CMD))
     580           0 :                 wake_up(&ps2dev->wait);
     581           0 : }
     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           0 : irqreturn_t ps2_interrupt(struct serio *serio, u8 data, unsigned int flags) {
     595           0 :         struct ps2dev *ps2dev = serio_get_drvdata(serio);
     596             :         enum ps2_disposition rc;
     597             : 
     598           0 :         rc = ps2dev->pre_receive_handler(ps2dev, data, flags);
     599           0 :         switch (rc) {
     600             :         case PS2_ERROR:
     601           0 :                 ps2_cleanup(ps2dev);
     602           0 :                 break;
     603             : 
     604             :         case PS2_IGNORE:
     605             :                 break;
     606             : 
     607             :         case PS2_PROCESS:
     608           0 :                 if (ps2dev->flags & PS2_FLAG_ACK)
     609           0 :                         ps2_handle_ack(ps2dev, data);
     610           0 :                 else if (ps2dev->flags & PS2_FLAG_CMD)
     611           0 :                         ps2_handle_response(ps2dev, data);
     612             :                 else
     613           0 :                         ps2dev->receive_handler(ps2dev, data);
     614             :                 break;
     615             :         }
     616             : 
     617           0 :         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");

Generated by: LCOV version 1.14