LCOV - code coverage report
Current view: top level - drivers/input/serio - libps2.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 125 196 63.8 %
Date: 2022-04-01 14:58:12 Functions: 11 14 78.6 %
Branches: 62 148 41.9 %

           Branch data     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/serio.h>
      16                 :            : #include <linux/i8042.h>
      17                 :            : #include <linux/libps2.h>
      18                 :            : 
      19                 :            : #define DRIVER_DESC     "PS/2 driver library"
      20                 :            : 
      21                 :            : MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
      22                 :            : MODULE_DESCRIPTION("PS/2 driver library");
      23                 :            : MODULE_LICENSE("GPL");
      24                 :            : 
      25                 :        324 : static int ps2_do_sendbyte(struct ps2dev *ps2dev, u8 byte,
      26                 :            :                            unsigned int timeout, unsigned int max_attempts)
      27                 :            :         __releases(&ps2dev->serio->lock) __acquires(&ps2dev->serio->lock)
      28                 :            : {
      29                 :        324 :         int attempt = 0;
      30                 :        324 :         int error;
      31                 :            : 
      32                 :        324 :         lockdep_assert_held(&ps2dev->serio->lock);
      33                 :            : 
      34                 :        324 :         do {
      35                 :        324 :                 ps2dev->nak = 1;
      36                 :        324 :                 ps2dev->flags |= PS2_FLAG_ACK;
      37                 :            : 
      38                 :        324 :                 serio_continue_rx(ps2dev->serio);
      39                 :            : 
      40         [ +  - ]:        324 :                 error = serio_write(ps2dev->serio, byte);
      41         [ +  - ]:        324 :                 if (error)
      42                 :            :                         dev_dbg(&ps2dev->serio->dev,
      43                 :            :                                 "failed to write %#02x: %d\n", byte, error);
      44                 :            :                 else
      45   [ -  +  -  +  :        660 :                         wait_event_timeout(ps2dev->wait,
          +  +  -  +  -  
                +  +  + ]
      46                 :            :                                            !(ps2dev->flags & PS2_FLAG_ACK),
      47                 :            :                                            msecs_to_jiffies(timeout));
      48                 :            : 
      49                 :        324 :                 serio_pause_rx(ps2dev->serio);
      50   [ -  +  -  - ]:        324 :         } while (ps2dev->nak == PS2_RET_NAK && ++attempt < max_attempts);
      51                 :            : 
      52                 :        324 :         ps2dev->flags &= ~PS2_FLAG_ACK;
      53                 :            : 
      54         [ -  + ]:        324 :         if (!error) {
      55   [ -  -  +  + ]:        324 :                 switch (ps2dev->nak) {
      56                 :            :                 case 0:
      57                 :            :                         break;
      58                 :          0 :                 case PS2_RET_NAK:
      59                 :          0 :                         error = -EAGAIN;
      60                 :          0 :                         break;
      61                 :          0 :                 case PS2_RET_ERR:
      62                 :          0 :                         error = -EPROTO;
      63                 :          0 :                         break;
      64                 :          6 :                 default:
      65                 :          6 :                         error = -EIO;
      66                 :          6 :                         break;
      67                 :            :                 }
      68                 :          0 :         }
      69                 :            : 
      70                 :        324 :         if (error || attempt > 1)
      71                 :            :                 dev_dbg(&ps2dev->serio->dev,
      72                 :            :                         "%02x - %d (%x), attempt %d\n",
      73                 :            :                         byte, error, ps2dev->nak, attempt);
      74                 :            : 
      75                 :        324 :         return error;
      76                 :            : }
      77                 :            : 
      78                 :            : /*
      79                 :            :  * ps2_sendbyte() sends a byte to the device and waits for acknowledge.
      80                 :            :  * It doesn't handle retransmission, the caller is expected to handle
      81                 :            :  * it when needed.
      82                 :            :  *
      83                 :            :  * ps2_sendbyte() can only be called from a process context.
      84                 :            :  */
      85                 :            : 
      86                 :         27 : int ps2_sendbyte(struct ps2dev *ps2dev, u8 byte, unsigned int timeout)
      87                 :            : {
      88                 :         27 :         int retval;
      89                 :            : 
      90                 :         27 :         serio_pause_rx(ps2dev->serio);
      91                 :            : 
      92                 :         27 :         retval = ps2_do_sendbyte(ps2dev, byte, timeout, 1);
      93                 :         27 :         dev_dbg(&ps2dev->serio->dev, "%02x - %x\n", byte, ps2dev->nak);
      94                 :            : 
      95                 :         27 :         serio_continue_rx(ps2dev->serio);
      96                 :            : 
      97                 :         27 :         return retval;
      98                 :            : }
      99                 :            : EXPORT_SYMBOL(ps2_sendbyte);
     100                 :            : 
     101                 :        213 : void ps2_begin_command(struct ps2dev *ps2dev)
     102                 :            : {
     103         [ -  + ]:         15 :         struct mutex *m = ps2dev->serio->ps2_cmd_mutex ?: &ps2dev->cmd_mutex;
     104                 :            : 
     105                 :        213 :         mutex_lock(m);
     106                 :         15 : }
     107                 :            : EXPORT_SYMBOL(ps2_begin_command);
     108                 :            : 
     109                 :        213 : void ps2_end_command(struct ps2dev *ps2dev)
     110                 :            : {
     111         [ -  + ]:         15 :         struct mutex *m = ps2dev->serio->ps2_cmd_mutex ?: &ps2dev->cmd_mutex;
     112                 :            : 
     113                 :        213 :         mutex_unlock(m);
     114                 :         15 : }
     115                 :            : EXPORT_SYMBOL(ps2_end_command);
     116                 :            : 
     117                 :            : /*
     118                 :            :  * ps2_drain() waits for device to transmit requested number of bytes
     119                 :            :  * and discards them.
     120                 :            :  */
     121                 :            : 
     122                 :          0 : void ps2_drain(struct ps2dev *ps2dev, size_t maxbytes, unsigned int timeout)
     123                 :            : {
     124         [ #  # ]:          0 :         if (maxbytes > sizeof(ps2dev->cmdbuf)) {
     125                 :          0 :                 WARN_ON(1);
     126                 :          0 :                 maxbytes = sizeof(ps2dev->cmdbuf);
     127                 :            :         }
     128                 :            : 
     129         [ #  # ]:          0 :         ps2_begin_command(ps2dev);
     130                 :            : 
     131                 :          0 :         serio_pause_rx(ps2dev->serio);
     132                 :          0 :         ps2dev->flags = PS2_FLAG_CMD;
     133                 :          0 :         ps2dev->cmdcnt = maxbytes;
     134                 :          0 :         serio_continue_rx(ps2dev->serio);
     135                 :            : 
     136   [ #  #  #  #  :          0 :         wait_event_timeout(ps2dev->wait,
          #  #  #  #  #  
                #  #  # ]
     137                 :            :                            !(ps2dev->flags & PS2_FLAG_CMD),
     138                 :            :                            msecs_to_jiffies(timeout));
     139                 :            : 
     140         [ #  # ]:          0 :         ps2_end_command(ps2dev);
     141                 :          0 : }
     142                 :            : EXPORT_SYMBOL(ps2_drain);
     143                 :            : 
     144                 :            : /*
     145                 :            :  * ps2_is_keyboard_id() checks received ID byte against the list of
     146                 :            :  * known keyboard IDs.
     147                 :            :  */
     148                 :            : 
     149                 :         21 : bool ps2_is_keyboard_id(u8 id_byte)
     150                 :            : {
     151                 :         21 :         static const u8 keyboard_ids[] = {
     152                 :            :                 0xab,   /* Regular keyboards            */
     153                 :            :                 0xac,   /* NCD Sun keyboard             */
     154                 :            :                 0x2b,   /* Trust keyboard, translated   */
     155                 :            :                 0x5d,   /* Trust keyboard               */
     156                 :            :                 0x60,   /* NMB SGI keyboard, translated */
     157                 :            :                 0x47,   /* NMB SGI keyboard             */
     158                 :            :         };
     159                 :            : 
     160                 :         21 :         return memchr(keyboard_ids, id_byte, sizeof(keyboard_ids)) != NULL;
     161                 :            : }
     162                 :            : EXPORT_SYMBOL(ps2_is_keyboard_id);
     163                 :            : 
     164                 :            : /*
     165                 :            :  * ps2_adjust_timeout() is called after receiving 1st byte of command
     166                 :            :  * response and tries to reduce remaining timeout to speed up command
     167                 :            :  * completion.
     168                 :            :  */
     169                 :            : 
     170                 :         15 : static int ps2_adjust_timeout(struct ps2dev *ps2dev,
     171                 :            :                               unsigned int command, unsigned int timeout)
     172                 :            : {
     173      [ -  +  - ]:         15 :         switch (command) {
     174                 :          0 :         case PS2_CMD_RESET_BAT:
     175                 :            :                 /*
     176                 :            :                  * Device has sent the first response byte after
     177                 :            :                  * reset command, reset is thus done, so we can
     178                 :            :                  * shorten the timeout.
     179                 :            :                  * The next byte will come soon (keyboard) or not
     180                 :            :                  * at all (mouse).
     181                 :            :                  */
     182                 :          0 :                 if (timeout > msecs_to_jiffies(100))
     183                 :            :                         timeout = msecs_to_jiffies(100);
     184                 :            :                 break;
     185                 :            : 
     186                 :         15 :         case PS2_CMD_GETID:
     187                 :            :                 /*
     188                 :            :                  * Microsoft Natural Elite keyboard responds to
     189                 :            :                  * the GET ID command as it were a mouse, with
     190                 :            :                  * a single byte. Fail the command so atkbd will
     191                 :            :                  * use alternative probe to detect it.
     192                 :            :                  */
     193         [ -  + ]:         15 :                 if (ps2dev->cmdbuf[1] == 0xaa) {
     194                 :          0 :                         serio_pause_rx(ps2dev->serio);
     195                 :          0 :                         ps2dev->flags = 0;
     196                 :          0 :                         serio_continue_rx(ps2dev->serio);
     197                 :          0 :                         timeout = 0;
     198                 :            :                 }
     199                 :            : 
     200                 :            :                 /*
     201                 :            :                  * If device behind the port is not a keyboard there
     202                 :            :                  * won't be 2nd byte of ID response.
     203                 :            :                  */
     204         [ +  - ]:         15 :                 if (!ps2_is_keyboard_id(ps2dev->cmdbuf[1])) {
     205                 :         15 :                         serio_pause_rx(ps2dev->serio);
     206                 :         15 :                         ps2dev->flags = ps2dev->cmdcnt = 0;
     207                 :         15 :                         serio_continue_rx(ps2dev->serio);
     208                 :         15 :                         timeout = 0;
     209                 :            :                 }
     210                 :            :                 break;
     211                 :            : 
     212                 :            :         default:
     213                 :            :                 break;
     214                 :            :         }
     215                 :            : 
     216                 :         15 :         return timeout;
     217                 :            : }
     218                 :            : 
     219                 :            : /*
     220                 :            :  * ps2_command() sends a command and its parameters to the mouse,
     221                 :            :  * then waits for the response and puts it in the param array.
     222                 :            :  *
     223                 :            :  * ps2_command() can only be called from a process context
     224                 :            :  */
     225                 :            : 
     226                 :        198 : int __ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command)
     227                 :            : {
     228                 :        198 :         unsigned int timeout;
     229                 :        198 :         unsigned int send = (command >> 12) & 0xf;
     230                 :        198 :         unsigned int receive = (command >> 8) & 0xf;
     231                 :        198 :         int rc;
     232                 :        198 :         int i;
     233                 :        198 :         u8 send_param[16];
     234                 :            : 
     235         [ -  + ]:        198 :         if (receive > sizeof(ps2dev->cmdbuf)) {
     236                 :          0 :                 WARN_ON(1);
     237                 :          0 :                 return -EINVAL;
     238                 :            :         }
     239                 :            : 
     240         [ -  + ]:        198 :         if (send && !param) {
     241                 :          0 :                 WARN_ON(1);
     242                 :          0 :                 return -EINVAL;
     243                 :            :         }
     244                 :            : 
     245                 :        198 :         memcpy(send_param, param, send);
     246                 :            : 
     247                 :        198 :         serio_pause_rx(ps2dev->serio);
     248                 :            : 
     249         [ +  + ]:        198 :         ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0;
     250                 :        198 :         ps2dev->cmdcnt = receive;
     251         [ +  + ]:        198 :         if (receive && param)
     252         [ +  + ]:        132 :                 for (i = 0; i < receive; i++)
     253                 :         93 :                         ps2dev->cmdbuf[(receive - 1) - i] = param[i];
     254                 :            : 
     255                 :            :         /* Signal that we are sending the command byte */
     256                 :        198 :         ps2dev->flags |= PS2_FLAG_ACK_CMD;
     257                 :            : 
     258                 :            :         /*
     259                 :            :          * Some devices (Synaptics) peform the reset before
     260                 :            :          * ACKing the reset command, and so it can take a long
     261                 :            :          * time before the ACK arrives.
     262                 :            :          */
     263         [ +  + ]:        198 :         timeout = command == PS2_CMD_RESET_BAT ? 1000 : 200;
     264                 :            : 
     265                 :        198 :         rc = ps2_do_sendbyte(ps2dev, command & 0xff, timeout, 2);
     266         [ +  + ]:        198 :         if (rc)
     267                 :          6 :                 goto out_reset_flags;
     268                 :            : 
     269                 :            :         /* Now we are sending command parameters, if any */
     270                 :        192 :         ps2dev->flags &= ~PS2_FLAG_ACK_CMD;
     271                 :            : 
     272         [ +  + ]:        291 :         for (i = 0; i < send; i++) {
     273                 :         99 :                 rc = ps2_do_sendbyte(ps2dev, param[i], 200, 2);
     274         [ -  + ]:         99 :                 if (rc)
     275                 :          0 :                         goto out_reset_flags;
     276                 :            :         }
     277                 :            : 
     278                 :        192 :         serio_continue_rx(ps2dev->serio);
     279                 :            : 
     280                 :            :         /*
     281                 :            :          * The reset command takes a long time to execute.
     282                 :            :          */
     283         [ +  + ]:        192 :         timeout = msecs_to_jiffies(command == PS2_CMD_RESET_BAT ? 4000 : 500);
     284                 :            : 
     285   [ -  +  -  +  :        192 :         timeout = wait_event_timeout(ps2dev->wait,
             -  -  -  - ]
     286                 :            :                                      !(ps2dev->flags & PS2_FLAG_CMD1), timeout);
     287                 :            : 
     288   [ +  +  +  - ]:        192 :         if (ps2dev->cmdcnt && !(ps2dev->flags & PS2_FLAG_CMD1)) {
     289                 :            : 
     290                 :         15 :                 timeout = ps2_adjust_timeout(ps2dev, command, timeout);
     291   [ +  -  -  +  :         15 :                 wait_event_timeout(ps2dev->wait,
             -  -  -  - ]
     292                 :            :                                    !(ps2dev->flags & PS2_FLAG_CMD), timeout);
     293                 :            :         }
     294                 :            : 
     295                 :        192 :         serio_pause_rx(ps2dev->serio);
     296                 :            : 
     297         [ +  + ]:        192 :         if (param)
     298         [ +  + ]:        222 :                 for (i = 0; i < receive; i++)
     299                 :         87 :                         param[i] = ps2dev->cmdbuf[(receive - 1) - i];
     300                 :            : 
     301   [ -  +  -  - ]:        192 :         if (ps2dev->cmdcnt &&
     302         [ #  # ]:          0 :             (command != PS2_CMD_RESET_BAT || ps2dev->cmdcnt != 1)) {
     303                 :          0 :                 rc = -EPROTO;
     304                 :          0 :                 goto out_reset_flags;
     305                 :            :         }
     306                 :            : 
     307                 :            :         rc = 0;
     308                 :            : 
     309                 :        198 :  out_reset_flags:
     310                 :        198 :         ps2dev->flags = 0;
     311                 :        198 :         serio_continue_rx(ps2dev->serio);
     312                 :            : 
     313                 :        198 :         dev_dbg(&ps2dev->serio->dev,
     314                 :            :                 "%02x [%*ph] - %x/%08lx [%*ph]\n",
     315                 :            :                 command & 0xff, send, send_param,
     316                 :            :                 ps2dev->nak, ps2dev->flags,
     317                 :            :                 receive, param ?: send_param);
     318                 :            : 
     319                 :            :         /*
     320                 :            :          * ps_command() handles resends itself, so do not leak -EAGAIN
     321                 :            :          * to the callers.
     322                 :            :          */
     323         [ -  + ]:        198 :         return rc != -EAGAIN ? rc : -EPROTO;
     324                 :            : }
     325                 :            : EXPORT_SYMBOL(__ps2_command);
     326                 :            : 
     327                 :        198 : int ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command)
     328                 :            : {
     329                 :        198 :         int rc;
     330                 :            : 
     331         [ -  + ]:        198 :         ps2_begin_command(ps2dev);
     332                 :        198 :         rc = __ps2_command(ps2dev, param, command);
     333         [ -  + ]:        198 :         ps2_end_command(ps2dev);
     334                 :            : 
     335                 :        198 :         return rc;
     336                 :            : }
     337                 :            : EXPORT_SYMBOL(ps2_command);
     338                 :            : 
     339                 :            : /*
     340                 :            :  * ps2_sliced_command() sends an extended PS/2 command to the mouse
     341                 :            :  * using sliced syntax, understood by advanced devices, such as Logitech
     342                 :            :  * or Synaptics touchpads. The command is encoded as:
     343                 :            :  * 0xE6 0xE8 rr 0xE8 ss 0xE8 tt 0xE8 uu where (rr*64)+(ss*16)+(tt*4)+uu
     344                 :            :  * is the command.
     345                 :            :  */
     346                 :            : 
     347                 :          0 : int ps2_sliced_command(struct ps2dev *ps2dev, u8 command)
     348                 :            : {
     349                 :          0 :         int i;
     350                 :          0 :         int retval;
     351                 :            : 
     352         [ #  # ]:          0 :         ps2_begin_command(ps2dev);
     353                 :            : 
     354                 :          0 :         retval = __ps2_command(ps2dev, NULL, PS2_CMD_SETSCALE11);
     355         [ #  # ]:          0 :         if (retval)
     356                 :          0 :                 goto out;
     357                 :            : 
     358         [ #  # ]:          0 :         for (i = 6; i >= 0; i -= 2) {
     359                 :          0 :                 u8 d = (command >> i) & 3;
     360                 :          0 :                 retval = __ps2_command(ps2dev, &d, PS2_CMD_SETRES);
     361         [ #  # ]:          0 :                 if (retval)
     362                 :            :                         break;
     363                 :            :         }
     364                 :            : 
     365                 :          0 : out:
     366                 :          0 :         dev_dbg(&ps2dev->serio->dev, "%02x - %d\n", command, retval);
     367         [ #  # ]:          0 :         ps2_end_command(ps2dev);
     368                 :          0 :         return retval;
     369                 :            : }
     370                 :            : EXPORT_SYMBOL(ps2_sliced_command);
     371                 :            : 
     372                 :            : /*
     373                 :            :  * ps2_init() initializes ps2dev structure
     374                 :            :  */
     375                 :            : 
     376                 :          9 : void ps2_init(struct ps2dev *ps2dev, struct serio *serio)
     377                 :            : {
     378                 :          9 :         mutex_init(&ps2dev->cmd_mutex);
     379                 :          9 :         lockdep_set_subclass(&ps2dev->cmd_mutex, serio->depth);
     380                 :          9 :         init_waitqueue_head(&ps2dev->wait);
     381                 :          9 :         ps2dev->serio = serio;
     382                 :          9 : }
     383                 :            : EXPORT_SYMBOL(ps2_init);
     384                 :            : 
     385                 :            : /*
     386                 :            :  * ps2_handle_ack() is supposed to be used in interrupt handler
     387                 :            :  * to properly process ACK/NAK of a command from a PS/2 device.
     388                 :            :  */
     389                 :            : 
     390                 :        318 : bool ps2_handle_ack(struct ps2dev *ps2dev, u8 data)
     391                 :            : {
     392   [ +  -  -  -  :        318 :         switch (data) {
                      - ]
     393                 :        318 :         case PS2_RET_ACK:
     394                 :        318 :                 ps2dev->nak = 0;
     395                 :        318 :                 break;
     396                 :            : 
     397                 :          0 :         case PS2_RET_NAK:
     398                 :          0 :                 ps2dev->flags |= PS2_FLAG_NAK;
     399                 :          0 :                 ps2dev->nak = PS2_RET_NAK;
     400                 :          0 :                 break;
     401                 :            : 
     402                 :          0 :         case PS2_RET_ERR:
     403         [ #  # ]:          0 :                 if (ps2dev->flags & PS2_FLAG_NAK) {
     404                 :          0 :                         ps2dev->flags &= ~PS2_FLAG_NAK;
     405                 :          0 :                         ps2dev->nak = PS2_RET_ERR;
     406                 :          0 :                         break;
     407                 :            :                 }
     408                 :            :                 /* Fall through */
     409                 :            : 
     410                 :            :         /*
     411                 :            :          * Workaround for mice which don't ACK the Get ID command.
     412                 :            :          * These are valid mouse IDs that we recognize.
     413                 :            :          */
     414                 :            :         case 0x00:
     415                 :            :         case 0x03:
     416                 :            :         case 0x04:
     417         [ #  # ]:          0 :                 if (ps2dev->flags & PS2_FLAG_WAITID) {
     418                 :          0 :                         ps2dev->nak = 0;
     419                 :          0 :                         break;
     420                 :            :                 }
     421                 :            :                 /* Fall through */
     422                 :            :         default:
     423                 :            :                 /*
     424                 :            :                  * Do not signal errors if we get unexpected reply while
     425                 :            :                  * waiting for an ACK to the initial (first) command byte:
     426                 :            :                  * the device might not be quiesced yet and continue
     427                 :            :                  * delivering data.
     428                 :            :                  * Note that we reset PS2_FLAG_WAITID flag, so the workaround
     429                 :            :                  * for mice not acknowledging the Get ID command only triggers
     430                 :            :                  * on the 1st byte; if device spews data we really want to see
     431                 :            :                  * a real ACK from it.
     432                 :            :                  */
     433                 :          0 :                 dev_dbg(&ps2dev->serio->dev, "unexpected %#02x\n", data);
     434                 :          0 :                 ps2dev->flags &= ~PS2_FLAG_WAITID;
     435                 :          0 :                 return ps2dev->flags & PS2_FLAG_ACK_CMD;
     436                 :            :         }
     437                 :            : 
     438         [ +  - ]:        318 :         if (!ps2dev->nak) {
     439                 :        318 :                 ps2dev->flags &= ~PS2_FLAG_NAK;
     440         [ +  + ]:        318 :                 if (ps2dev->cmdcnt)
     441                 :         36 :                         ps2dev->flags |= PS2_FLAG_CMD | PS2_FLAG_CMD1;
     442                 :            :         }
     443                 :            : 
     444                 :        318 :         ps2dev->flags &= ~PS2_FLAG_ACK;
     445                 :        318 :         wake_up(&ps2dev->wait);
     446                 :            : 
     447         [ -  + ]:        318 :         if (data != PS2_RET_ACK)
     448                 :          0 :                 ps2_handle_response(ps2dev, data);
     449                 :            : 
     450                 :            :         return true;
     451                 :            : }
     452                 :            : EXPORT_SYMBOL(ps2_handle_ack);
     453                 :            : 
     454                 :            : /*
     455                 :            :  * ps2_handle_response() is supposed to be used in interrupt handler
     456                 :            :  * to properly store device's response to a command and notify process
     457                 :            :  * waiting for completion of the command.
     458                 :            :  */
     459                 :            : 
     460                 :         72 : bool ps2_handle_response(struct ps2dev *ps2dev, u8 data)
     461                 :            : {
     462         [ +  - ]:         72 :         if (ps2dev->cmdcnt)
     463                 :         72 :                 ps2dev->cmdbuf[--ps2dev->cmdcnt] = data;
     464                 :            : 
     465         [ +  + ]:         72 :         if (ps2dev->flags & PS2_FLAG_CMD1) {
     466                 :         36 :                 ps2dev->flags &= ~PS2_FLAG_CMD1;
     467         [ +  - ]:         36 :                 if (ps2dev->cmdcnt)
     468                 :         36 :                         wake_up(&ps2dev->wait);
     469                 :            :         }
     470                 :            : 
     471         [ +  + ]:         72 :         if (!ps2dev->cmdcnt) {
     472                 :         21 :                 ps2dev->flags &= ~PS2_FLAG_CMD;
     473                 :         21 :                 wake_up(&ps2dev->wait);
     474                 :            :         }
     475                 :            : 
     476                 :         72 :         return true;
     477                 :            : }
     478                 :            : EXPORT_SYMBOL(ps2_handle_response);
     479                 :            : 
     480                 :          0 : void ps2_cmd_aborted(struct ps2dev *ps2dev)
     481                 :            : {
     482         [ #  # ]:          0 :         if (ps2dev->flags & PS2_FLAG_ACK)
     483                 :          0 :                 ps2dev->nak = 1;
     484                 :            : 
     485         [ #  # ]:          0 :         if (ps2dev->flags & (PS2_FLAG_ACK | PS2_FLAG_CMD))
     486                 :          0 :                 wake_up(&ps2dev->wait);
     487                 :            : 
     488                 :            :         /* reset all flags except last nack */
     489                 :          0 :         ps2dev->flags &= PS2_FLAG_NAK;
     490                 :          0 : }
     491                 :            : EXPORT_SYMBOL(ps2_cmd_aborted);

Generated by: LCOV version 1.14