cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

libps2.c (11298B)


      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
     21MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
     22MODULE_DESCRIPTION("PS/2 driver library");
     23MODULE_LICENSE("GPL");
     24
     25static 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	int attempt = 0;
     30	int error;
     31
     32	lockdep_assert_held(&ps2dev->serio->lock);
     33
     34	do {
     35		ps2dev->nak = 1;
     36		ps2dev->flags |= PS2_FLAG_ACK;
     37
     38		serio_continue_rx(ps2dev->serio);
     39
     40		error = serio_write(ps2dev->serio, byte);
     41		if (error)
     42			dev_dbg(&ps2dev->serio->dev,
     43				"failed to write %#02x: %d\n", byte, error);
     44		else
     45			wait_event_timeout(ps2dev->wait,
     46					   !(ps2dev->flags & PS2_FLAG_ACK),
     47					   msecs_to_jiffies(timeout));
     48
     49		serio_pause_rx(ps2dev->serio);
     50	} while (ps2dev->nak == PS2_RET_NAK && ++attempt < max_attempts);
     51
     52	ps2dev->flags &= ~PS2_FLAG_ACK;
     53
     54	if (!error) {
     55		switch (ps2dev->nak) {
     56		case 0:
     57			break;
     58		case PS2_RET_NAK:
     59			error = -EAGAIN;
     60			break;
     61		case PS2_RET_ERR:
     62			error = -EPROTO;
     63			break;
     64		default:
     65			error = -EIO;
     66			break;
     67		}
     68	}
     69
     70	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	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
     86int ps2_sendbyte(struct ps2dev *ps2dev, u8 byte, unsigned int timeout)
     87{
     88	int retval;
     89
     90	serio_pause_rx(ps2dev->serio);
     91
     92	retval = ps2_do_sendbyte(ps2dev, byte, timeout, 1);
     93	dev_dbg(&ps2dev->serio->dev, "%02x - %x\n", byte, ps2dev->nak);
     94
     95	serio_continue_rx(ps2dev->serio);
     96
     97	return retval;
     98}
     99EXPORT_SYMBOL(ps2_sendbyte);
    100
    101void ps2_begin_command(struct ps2dev *ps2dev)
    102{
    103	struct mutex *m = ps2dev->serio->ps2_cmd_mutex ?: &ps2dev->cmd_mutex;
    104
    105	mutex_lock(m);
    106}
    107EXPORT_SYMBOL(ps2_begin_command);
    108
    109void ps2_end_command(struct ps2dev *ps2dev)
    110{
    111	struct mutex *m = ps2dev->serio->ps2_cmd_mutex ?: &ps2dev->cmd_mutex;
    112
    113	mutex_unlock(m);
    114}
    115EXPORT_SYMBOL(ps2_end_command);
    116
    117/*
    118 * ps2_drain() waits for device to transmit requested number of bytes
    119 * and discards them.
    120 */
    121
    122void ps2_drain(struct ps2dev *ps2dev, size_t maxbytes, unsigned int timeout)
    123{
    124	if (maxbytes > sizeof(ps2dev->cmdbuf)) {
    125		WARN_ON(1);
    126		maxbytes = sizeof(ps2dev->cmdbuf);
    127	}
    128
    129	ps2_begin_command(ps2dev);
    130
    131	serio_pause_rx(ps2dev->serio);
    132	ps2dev->flags = PS2_FLAG_CMD;
    133	ps2dev->cmdcnt = maxbytes;
    134	serio_continue_rx(ps2dev->serio);
    135
    136	wait_event_timeout(ps2dev->wait,
    137			   !(ps2dev->flags & PS2_FLAG_CMD),
    138			   msecs_to_jiffies(timeout));
    139
    140	ps2_end_command(ps2dev);
    141}
    142EXPORT_SYMBOL(ps2_drain);
    143
    144/*
    145 * ps2_is_keyboard_id() checks received ID byte against the list of
    146 * known keyboard IDs.
    147 */
    148
    149bool ps2_is_keyboard_id(u8 id_byte)
    150{
    151	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	return memchr(keyboard_ids, id_byte, sizeof(keyboard_ids)) != NULL;
    161}
    162EXPORT_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
    170static int ps2_adjust_timeout(struct ps2dev *ps2dev,
    171			      unsigned int command, unsigned int timeout)
    172{
    173	switch (command) {
    174	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		if (timeout > msecs_to_jiffies(100))
    183			timeout = msecs_to_jiffies(100);
    184		break;
    185
    186	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		if (ps2dev->cmdbuf[1] == 0xaa) {
    194			serio_pause_rx(ps2dev->serio);
    195			ps2dev->flags = 0;
    196			serio_continue_rx(ps2dev->serio);
    197			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		if (!ps2_is_keyboard_id(ps2dev->cmdbuf[1])) {
    205			serio_pause_rx(ps2dev->serio);
    206			ps2dev->flags = ps2dev->cmdcnt = 0;
    207			serio_continue_rx(ps2dev->serio);
    208			timeout = 0;
    209		}
    210		break;
    211
    212	default:
    213		break;
    214	}
    215
    216	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
    226int __ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command)
    227{
    228	unsigned int timeout;
    229	unsigned int send = (command >> 12) & 0xf;
    230	unsigned int receive = (command >> 8) & 0xf;
    231	int rc;
    232	int i;
    233	u8 send_param[16];
    234
    235	if (receive > sizeof(ps2dev->cmdbuf)) {
    236		WARN_ON(1);
    237		return -EINVAL;
    238	}
    239
    240	if (send && !param) {
    241		WARN_ON(1);
    242		return -EINVAL;
    243	}
    244
    245	memcpy(send_param, param, send);
    246
    247	serio_pause_rx(ps2dev->serio);
    248
    249	ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0;
    250	ps2dev->cmdcnt = receive;
    251	if (receive && param)
    252		for (i = 0; i < receive; i++)
    253			ps2dev->cmdbuf[(receive - 1) - i] = param[i];
    254
    255	/* Signal that we are sending the command byte */
    256	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	timeout = command == PS2_CMD_RESET_BAT ? 1000 : 200;
    264
    265	rc = ps2_do_sendbyte(ps2dev, command & 0xff, timeout, 2);
    266	if (rc)
    267		goto out_reset_flags;
    268
    269	/* Now we are sending command parameters, if any */
    270	ps2dev->flags &= ~PS2_FLAG_ACK_CMD;
    271
    272	for (i = 0; i < send; i++) {
    273		rc = ps2_do_sendbyte(ps2dev, param[i], 200, 2);
    274		if (rc)
    275			goto out_reset_flags;
    276	}
    277
    278	serio_continue_rx(ps2dev->serio);
    279
    280	/*
    281	 * The reset command takes a long time to execute.
    282	 */
    283	timeout = msecs_to_jiffies(command == PS2_CMD_RESET_BAT ? 4000 : 500);
    284
    285	timeout = wait_event_timeout(ps2dev->wait,
    286				     !(ps2dev->flags & PS2_FLAG_CMD1), timeout);
    287
    288	if (ps2dev->cmdcnt && !(ps2dev->flags & PS2_FLAG_CMD1)) {
    289
    290		timeout = ps2_adjust_timeout(ps2dev, command, timeout);
    291		wait_event_timeout(ps2dev->wait,
    292				   !(ps2dev->flags & PS2_FLAG_CMD), timeout);
    293	}
    294
    295	serio_pause_rx(ps2dev->serio);
    296
    297	if (param)
    298		for (i = 0; i < receive; i++)
    299			param[i] = ps2dev->cmdbuf[(receive - 1) - i];
    300
    301	if (ps2dev->cmdcnt &&
    302	    (command != PS2_CMD_RESET_BAT || ps2dev->cmdcnt != 1)) {
    303		rc = -EPROTO;
    304		goto out_reset_flags;
    305	}
    306
    307	rc = 0;
    308
    309 out_reset_flags:
    310	ps2dev->flags = 0;
    311	serio_continue_rx(ps2dev->serio);
    312
    313	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	return rc != -EAGAIN ? rc : -EPROTO;
    324}
    325EXPORT_SYMBOL(__ps2_command);
    326
    327int ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command)
    328{
    329	int rc;
    330
    331	ps2_begin_command(ps2dev);
    332	rc = __ps2_command(ps2dev, param, command);
    333	ps2_end_command(ps2dev);
    334
    335	return rc;
    336}
    337EXPORT_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
    347int ps2_sliced_command(struct ps2dev *ps2dev, u8 command)
    348{
    349	int i;
    350	int retval;
    351
    352	ps2_begin_command(ps2dev);
    353
    354	retval = __ps2_command(ps2dev, NULL, PS2_CMD_SETSCALE11);
    355	if (retval)
    356		goto out;
    357
    358	for (i = 6; i >= 0; i -= 2) {
    359		u8 d = (command >> i) & 3;
    360		retval = __ps2_command(ps2dev, &d, PS2_CMD_SETRES);
    361		if (retval)
    362			break;
    363	}
    364
    365out:
    366	dev_dbg(&ps2dev->serio->dev, "%02x - %d\n", command, retval);
    367	ps2_end_command(ps2dev);
    368	return retval;
    369}
    370EXPORT_SYMBOL(ps2_sliced_command);
    371
    372/*
    373 * ps2_init() initializes ps2dev structure
    374 */
    375
    376void ps2_init(struct ps2dev *ps2dev, struct serio *serio)
    377{
    378	mutex_init(&ps2dev->cmd_mutex);
    379	lockdep_set_subclass(&ps2dev->cmd_mutex, serio->depth);
    380	init_waitqueue_head(&ps2dev->wait);
    381	ps2dev->serio = serio;
    382}
    383EXPORT_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
    390bool ps2_handle_ack(struct ps2dev *ps2dev, u8 data)
    391{
    392	switch (data) {
    393	case PS2_RET_ACK:
    394		ps2dev->nak = 0;
    395		break;
    396
    397	case PS2_RET_NAK:
    398		ps2dev->flags |= PS2_FLAG_NAK;
    399		ps2dev->nak = PS2_RET_NAK;
    400		break;
    401
    402	case PS2_RET_ERR:
    403		if (ps2dev->flags & PS2_FLAG_NAK) {
    404			ps2dev->flags &= ~PS2_FLAG_NAK;
    405			ps2dev->nak = PS2_RET_ERR;
    406			break;
    407		}
    408		fallthrough;
    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		if (ps2dev->flags & PS2_FLAG_WAITID) {
    418			ps2dev->nak = 0;
    419			break;
    420		}
    421		fallthrough;
    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		dev_dbg(&ps2dev->serio->dev, "unexpected %#02x\n", data);
    434		ps2dev->flags &= ~PS2_FLAG_WAITID;
    435		return ps2dev->flags & PS2_FLAG_ACK_CMD;
    436	}
    437
    438	if (!ps2dev->nak) {
    439		ps2dev->flags &= ~PS2_FLAG_NAK;
    440		if (ps2dev->cmdcnt)
    441			ps2dev->flags |= PS2_FLAG_CMD | PS2_FLAG_CMD1;
    442	}
    443
    444	ps2dev->flags &= ~PS2_FLAG_ACK;
    445	wake_up(&ps2dev->wait);
    446
    447	if (data != PS2_RET_ACK)
    448		ps2_handle_response(ps2dev, data);
    449
    450	return true;
    451}
    452EXPORT_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
    460bool ps2_handle_response(struct ps2dev *ps2dev, u8 data)
    461{
    462	if (ps2dev->cmdcnt)
    463		ps2dev->cmdbuf[--ps2dev->cmdcnt] = data;
    464
    465	if (ps2dev->flags & PS2_FLAG_CMD1) {
    466		ps2dev->flags &= ~PS2_FLAG_CMD1;
    467		if (ps2dev->cmdcnt)
    468			wake_up(&ps2dev->wait);
    469	}
    470
    471	if (!ps2dev->cmdcnt) {
    472		ps2dev->flags &= ~PS2_FLAG_CMD;
    473		wake_up(&ps2dev->wait);
    474	}
    475
    476	return true;
    477}
    478EXPORT_SYMBOL(ps2_handle_response);
    479
    480void ps2_cmd_aborted(struct ps2dev *ps2dev)
    481{
    482	if (ps2dev->flags & PS2_FLAG_ACK)
    483		ps2dev->nak = 1;
    484
    485	if (ps2dev->flags & (PS2_FLAG_ACK | PS2_FLAG_CMD))
    486		wake_up(&ps2dev->wait);
    487
    488	/* reset all flags except last nack */
    489	ps2dev->flags &= PS2_FLAG_NAK;
    490}
    491EXPORT_SYMBOL(ps2_cmd_aborted);