Files
mango/kernel/tty/tty.c
Max Wash 3233169f25 dev: implement reading from block devices
reading from block devices is done using the block cache (bcache).
This cache stores sectors from a block device in pages of memory
marked as 'cached', which will allow them to be reclaimed when
memory pressure is high (TODO).

while block device drivers implement callbacks allowing reading/writing
at block-granularity, the device subsystem uses the block cache to
implement reading/writing at byte-granularity in a driver-agnostic way.

block drivers can disable the block cache for their devices, but this
will require that any clients communicate with the devices at
block-granularity.

also added an offset parameter to device and object read/write functions/callbacks.
2023-07-09 21:58:40 +01:00

111 lines
2.5 KiB
C

#include <socks/tty.h>
#include <socks/input.h>
#include <socks/printk.h>
static void newline(struct device *tty)
{
struct tty_device *ttydev = TTY_DEVICE(tty);
struct tty_driver *tty_driver = TTY_DRIVER(tty->dev_owner);
struct tty_driver_ops *ops = tty_driver->tty_ops;
ttydev->tty_xcur = 0;
ttydev->tty_ycur++;
if (ttydev->tty_ycur >= ttydev->tty_ycells) {
ttydev->tty_xcur = 0;
ttydev->tty_ycur = ttydev->tty_ycells - 1;
if (ops->tty_scroll) {
ops->tty_scroll(tty, TTY_SCROLL_DOWN, 1);
}
}
ops->tty_move_cursor(tty, ttydev->tty_xcur, ttydev->tty_ycur);
}
static void __putchar(struct device *tty, int c)
{
struct tty_device *ttydev = TTY_DEVICE(tty);
struct tty_driver *tty_driver = TTY_DRIVER(tty->dev_owner);
struct tty_driver_ops *ops = tty_driver->tty_ops;
ops->tty_putc(tty, c, ttydev->tty_xcur, ttydev->tty_ycur, ttydev->tty_curattrib);
ttydev->tty_xcur++;
if (ttydev->tty_xcur >= ttydev->tty_xcells) {
ttydev->tty_xcur = 0;
ttydev->tty_ycur++;
}
if (ttydev->tty_ycur >= ttydev->tty_ycells) {
ttydev->tty_xcur = 0;
ttydev->tty_ycur = ttydev->tty_ycells - 1;
if (ops->tty_scroll) {
ops->tty_scroll(tty, TTY_SCROLL_DOWN, 1);
}
}
ops->tty_move_cursor(tty, ttydev->tty_xcur, ttydev->tty_ycur);
}
static void putchar(struct device *tty, int c)
{
struct tty_driver *tty_driver = TTY_DRIVER(tty->dev_owner);
struct tty_driver_ops *ops = tty_driver->tty_ops;
if (!ops->tty_putc) {
return;
}
if (tty_driver->tty_type == TTY_DRIVER_SIMPLE) {
ops->tty_putc(tty, c, -1, -1, 0);
return;
}
switch (c) {
case '\n':
newline(tty);
break;
default:
__putchar(tty, c);
break;
}
}
kern_status_t tty_read(struct device *tty, void *buf, size_t offset, size_t max, size_t *nr_read, socks_flags_t flags)
{
kern_status_t status = KERN_UNSUPPORTED;
struct tty_device *ttydev = TTY_DEVICE(tty);
if (ttydev->tty_ldisc || ttydev->tty_ldisc->read) {
status = ttydev->tty_ldisc->read(tty, buf, max, nr_read, flags);
}
return status;
}
kern_status_t tty_write(struct device *tty, const void *buf, size_t offset, size_t len, size_t *nr_written, socks_flags_t flags)
{
size_t r = 0;
const char *s = buf;
for (size_t i = 0; i < len; i++) {
putchar(tty, s[i]);
r++;
}
*nr_written = r;
return KERN_OK;
}
kern_status_t tty_report_event(struct device *tty, const struct input_event *ev)
{
struct tty_device *ttydev = TTY_DEVICE(tty);
if (ttydev->tty_ldisc || ttydev->tty_ldisc->write) {
ttydev->tty_ldisc->write(tty, ev);
}
return KERN_OK;
}