AquilaOS documentation
How it works, and its code
Loading...
Searching...
No Matches
ps2mouse.c
Go to the documentation of this file.
1
12
13
14#include <core/system.h>
15#include <core/module.h>
16#include <core/arch.h>
17
18#include <cpu/cpu.h>
19
20#include <dev/i8042.h>
21
22#include <sys/proc.h>
23#include <sys/sched.h>
24
25#include <dev/dev.h>
26#include <fs/devfs.h>
27#include <fs/posix.h>
28
29#include <ds/ringbuf.h>
30#include <ds/queue.h>
31
32#include <aquila/errno.h>
33
35
36#define USE_DEFAULTS 0xF6
37#define ENABLE_MOUSE 0xF4
38#define RESET 0xFF
39
40#define BUF_SIZE 1024
41
42static struct ringbuf *mouse_ring = RINGBUF_NEW(BUF_SIZE); /* the bytes received */
43static struct proc *proc = NULL; /* the process that has it open */
44static struct waitq *mouse_read_queue = &(struct waitq){0}; /* readers sleep here */
45
46/* how many of the replies to the reset done at open are still to come:
47 * they are dropped, nobody reads them */
48static int skip = 0;
49
56void ps2mouse_handler(int byte)
57{
58 char b = byte;
59
60 if (skip) {
61 skip--;
62 return;
63 }
64
65 /* if nobody reads and the ring is full, the byte is lost */
66 ringbuf_write(mouse_ring, 1, &b);
67
68 /* wake the readers, and select() and poll(), which don't sleep on
69 * the queue */
71}
72
79
81static ssize_t ps2mouse_read(struct devid *dd __unused, off_t offset __unused, struct iobuf *io)
82{
83 return ringbuf_read_iobuf(mouse_ring, io->resid, io);
84}
85
88static ssize_t ps2mouse_write(struct devid *dd __unused, off_t offset __unused, struct iobuf *io)
89{
90 size_t size = io->resid;
91
92 for (size_t i = 0; i < size; ++i) {
93 uint8_t c;
94 ssize_t r = iobuf_in(io, &c, 1);
95
96 if (r < 0)
97 return i ? (ssize_t) i : r;
98
99 if (i8042_aux_write(c))
100 return i ? (ssize_t) i : -EIO;
101 }
102
103 return size;
104}
105
124
127static int ps2mouse_file_open(struct file *file)
128{
129 if (proc) /* only one process can have the mouse open */
130 return -EACCES;
131
132 proc = curproc;
133 file->vnode->read_queue = mouse_read_queue;
134
135 /* make it a plain PS/2 mouse again, whatever the last opener made it
136 * (its replies, ACK AA 00 and ACK, are dropped), with nothing left
137 * from before in the ring */
138 char c;
139 while (ringbuf_read(mouse_ring, 1, &c))
140 ;
141 skip = 4;
144
145 return posix_file_open(file);
146}
147
149static int ps2mouse_file_can_read(struct file *file, size_t size)
150{
151 (void) file;
152 return ringbuf_available(mouse_ring);
153}
154
156static int ps2mouse_file_close(struct file *file)
157{
158 proc = NULL;
159 return posix_file_close(file);
160}
161
162struct dev ps2mousedev = {
163 .name = "mousedev",
164
165 .probe = ps2mouse_probe,
166 .read = ps2mouse_read,
167 .write = ps2mouse_write,
168
169 .fops = {
170 .open = ps2mouse_file_open,
171 .read = posix_file_read,
172 .write = posix_file_write,
173 .close = ps2mouse_file_close,
174
175 .can_read = ps2mouse_file_can_read,
176 .can_write = __vfs_can_always,
177 .eof = __vfs_eof_never,
178 },
179};
180
void i8042_handler_register(int port, void(*fun)(int))
Registers the function that gets each byte a port receives.
Definition i8042.c:75
int i8042_aux_write(uint8_t byte)
Sends a byte to the device on the second port (the mouse).
Definition i8042.c:100
ssize_t iobuf_in(struct iobuf *io, void *dst, size_t n)
Copies bytes from the iobuf's buffer into the kernel, and moves past them.
Definition iobuf.c:135
void kdev_chrdev_register(devid_t major, struct dev *dev)
Registers a driver as the character device of a major number.
Definition kdev.c:575
#define MODULE_INIT(name, i, f)
Definition module.h:10
int posix_file_open(struct file *file)
Finishes opening a file: with O_TRUNC, a regular file is truncated to 0 bytes.
Definition open.c:17
int posix_file_close(struct file *file)
Closes an open file by dropping its reference to its vnode.
Definition close.c:15
ssize_t posix_file_read(struct file *file, struct iobuf *io)
Reads from an open file at its offset, and moves the offset past what was read.
Definition read.c:29
ssize_t posix_file_write(struct file *file, struct iobuf *io)
Writes to an open file at its offset, and moves the offset past what was written.
Definition write.c:25
static ssize_t ps2mouse_read(struct devid *dd, off_t offset, struct iobuf *io)
Reads the bytes received from the mouse.
Definition ps2mouse.c:81
static int skip
Definition ps2mouse.c:48
static struct ringbuf * mouse_ring
Definition ps2mouse.c:42
#define ENABLE_MOUSE
Definition ps2mouse.c:37
static int ps2mouse_file_can_read(struct file *file, size_t size)
Returns whether there are bytes to read.
Definition ps2mouse.c:149
#define BUF_SIZE
Definition ps2mouse.c:40
static int ps2mouse_file_close(struct file *file)
Closes /dev/mouse: another process may open it now.
Definition ps2mouse.c:156
int ps2mouse_probe()
Sets the mouse up at boot (its default settings, and reporting on) and registers /dev/mouse.
Definition ps2mouse.c:114
void ps2mouse_register(void)
Has the i8042 driver send the bytes of its second port, the mouse's, to this driver.
Definition ps2mouse.c:75
static struct waitq * mouse_read_queue
Definition ps2mouse.c:44
#define RESET
Definition ps2mouse.c:38
#define USE_DEFAULTS
Definition ps2mouse.c:36
void ps2mouse_handler(int byte)
Takes a byte from the mouse, which the i8042 driver received: it goes to the readers,...
Definition ps2mouse.c:56
struct dev ps2mousedev
Definition ps2mouse.c:34
static int ps2mouse_file_open(struct file *file)
Opens /dev/mouse, which one process at a time may have open (EACCES otherwise), and resets the mouse.
Definition ps2mouse.c:127
static ssize_t ps2mouse_write(struct devid *dd, off_t offset, struct iobuf *io)
Sends what is written to the mouse, a byte at a time: commands, which it replies to (an ACK to each b...
Definition ps2mouse.c:88
#define RINGBUF_NEW(sz)
Definition ringbuf.h:26
#define curproc
Definition sched.h:13
#define NULL
Definition stddef.h:27
unsigned char uint8_t
Definition stddef.h:20
A device driver: its operations, any of which may be NULL.
Definition dev.h:28
Which device: its kind (S_IFCHR or S_IFBLK) and numbers.
Definition dev.h:21
An open file (POSIX's "open file description", fs/file.c).
Definition vfs.h:157
An iobuf.
Definition iobuf.h:35
size_t resid
Definition iobuf.h:38
A process.
Definition proc.h:75
A ring buffer.
Definition ringbuf.h:18
Definition waitq.h:19
long int ssize_t
Definition types.h:12
long int off_t
Definition types.h:10
void waitq_wakeup(struct waitq *waitq)
Wakes up every thread sleeping on a wait queue, and every thread polling it.
Definition waitq.c:178