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

Generated by: LCOV version 1.14