drivers/input/serio/libps2.c

Source file repositories/reference/linux-study-clean/drivers/input/serio/libps2.c

File Facts

System
Linux kernel
Corpus path
drivers/input/serio/libps2.c
Extension
.c
Size
16374 bytes
Lines
621
Domain
Driver Families
Bucket
drivers/input
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

switch (ps2dev->nak) {
		case 0:
			break;
		case PS2_RET_NAK:
			error = -EAGAIN;
			break;
		case PS2_RET_ERR:
			error = -EPROTO;
			break;
		default:
			error = -EIO;
			break;
		}
	}

	if (error || attempt > 1)
		dev_dbg(&ps2dev->serio->dev,
			"%02x - %d (%x), attempt %d\n",
			byte, error, ps2dev->nak, attempt);

	return error;
}

/**
 * ps2_sendbyte - sends a byte to the device and wait for acknowledgement
 * @ps2dev: a PS/2 device to send the data to
 * @byte: data to be sent to the device
 * @timeout: timeout for sending the data and receiving an acknowledge
 *
 * The function doesn't handle retransmission, the caller is expected to handle
 * it when needed.
 *
 * ps2_sendbyte() can only be called from a process context.
 */
int ps2_sendbyte(struct ps2dev *ps2dev, u8 byte, unsigned int timeout)
{
	int retval;

	guard(serio_pause_rx)(ps2dev->serio);

	retval = ps2_do_sendbyte(ps2dev, byte, timeout, 1);
	dev_dbg(&ps2dev->serio->dev, "%02x - %x\n", byte, ps2dev->nak);

	return retval;
}
EXPORT_SYMBOL(ps2_sendbyte);

/**
 * ps2_begin_command - mark beginning of execution of a complex command
 * @ps2dev: a PS/2 device executing the command
 *
 * Serializes a complex/compound command. Once command is finished
 * ps2_end_command() should be called.
 */
void ps2_begin_command(struct ps2dev *ps2dev)
{
	struct mutex *m = ps2dev->serio->ps2_cmd_mutex ?: &ps2dev->cmd_mutex;

	mutex_lock(m);
}
EXPORT_SYMBOL(ps2_begin_command);

/**
 * ps2_end_command - mark end of execution of a complex command
 * @ps2dev: a PS/2 device executing the command
 */
void ps2_end_command(struct ps2dev *ps2dev)
{
	struct mutex *m = ps2dev->serio->ps2_cmd_mutex ?: &ps2dev->cmd_mutex;

	mutex_unlock(m);
}
EXPORT_SYMBOL(ps2_end_command);

/**
 * ps2_drain - waits for device to transmit requested number of bytes
 * and discards them
 * @ps2dev: the PS/2 device that should be drained
 * @maxbytes: maximum number of bytes to be drained
 * @timeout: time to drain the device
 */
void ps2_drain(struct ps2dev *ps2dev, size_t maxbytes, unsigned int timeout)
{
	if (WARN_ON(maxbytes > sizeof(ps2dev->cmdbuf)))
		maxbytes = sizeof(ps2dev->cmdbuf);

	ps2_begin_command(ps2dev);

	scoped_guard(serio_pause_rx, ps2dev->serio) {
		ps2dev->flags = PS2_FLAG_CMD;

Annotation

Implementation Notes