Commit 43740f43 authored by Léo Grange's avatar Léo Grange
Browse files

add definitions to use a centralized TTY device

parent d730b301
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -7,7 +7,8 @@ include device/usb/subdir.mk


C_SRC_L:= \
	device_registering.c
	device_registering.c \
	tty.c


CURDIR:=device

device/tty.c

0 → 100644
+84 −0
Original line number Diff line number Diff line
#include <fs/file_operations.h>
#include <fs/file.h>
#include "tty.h"


static struct tty *_ttydev_minors[TTYDEV_MINOR_MAX] = {NULL};


// private definitions

static void ttydev_init();

static int ttydev_open(uint16 minor, struct file *filep);

static int ttydev_release(struct file *filep);

static ssize_t ttydev_write(struct file *filep, void *source, size_t len);

static ssize_t ttydev_read(struct file *filep, void *dest, size_t len);

static int ttydev_ioctl(struct file *filep, int cmd, void *data);

// structs for device and file manipulation
struct device ttydev_device = {
	.name = "tty",
	.init = &ttydev_init,
	.open = &ttydev_open
};


static const struct file_operations _ttydev_fop = {
	.release = &ttydev_release,
	.write = &ttydev_write,
	.read = &ttydev_read,
	.ioctl = &ttydev_ioctl
};


struct tty *ttydev_get_minor(uint16 minor) {
	return minor < TTYDEV_MINOR_MAX ? _ttydev_minors[minor] : NULL;
}

int ttydev_set_minor(uint16 minor, struct tty *tty) {
	if(minor < TTYDEV_MINOR_MAX) {
		_ttydev_minors[minor] = tty;
		return 0;
	}
	return -1;
}


static void ttydev_init() {
	
}

static int ttydev_open(uint16 minor, struct file *filep) {
	if(minor < TTYDEV_MINOR_MAX) {
		struct tty *tty = _ttydev_minors[minor];

		filep->op = &_ttydev_fop;
		filep->private_data = tty;
		return tty_open(tty);
	}
	return -ENXIO;
}


static int ttydev_release(struct file *filep) {
	tty_release(filep->private_data);
	return 0;
}

static ssize_t ttydev_write(struct file *filep, void *source, size_t len) {
	return tty_write(filep->private_data, source, len);
}

static ssize_t ttydev_read(struct file *filep, void *dest, size_t len) {
	return tty_read(filep->private_data, dest, len);
}

static int ttydev_ioctl(struct file *filep, int cmd, void *data) {
	return tty_ioctl(filep->private_data, cmd, data);
}

device/tty.h

0 → 100644
+34 −0
Original line number Diff line number Diff line
#ifndef _DEVICE_TTY_H
#define _DEVICE_TTY_H

#include <sys/tty.h>
#include <device/device.h>


/**
 * TTY device driver, which centralized each TTY implementation inside a
 * single device (each TTY has the same major, and different minors).
 * The generic TTY implementation is defined in sys/tty.h
 */


// number of TTY minors handle by the TTY device
#define TTYDEV_MINOR_MAX	10


extern struct device ttydev_device;

/**
 * Get/set a TTY from its minor number inside the TTY device.
 * ttydev_set_minor() returns non-zero if queried minor is outside
 * [0, TTYDEV_MINOR_MAX[ range.
 */
struct tty *ttydev_get_minor(uint16 minor);

int ttydev_set_minor(uint16 minor, struct tty *tty);





#endif //_DEVICE_TTY_H
+28 −2
Original line number Diff line number Diff line
@@ -55,10 +55,13 @@ struct tty_ops {
	int (*tty_write) (struct tty *tty, const char *data, size_t len);

	// read/write a single character
	int (*getchar) (struct tty *tty);
	//int (*getchar) (struct tty *tty);
	int (*putchar) (struct tty *tty, char c);
	
	// ioctl support
	int (*ioctl)(struct tty *tty, int cmd, void *data);
	
	// get/set terminal size (used by ioctl implementation)
	int (*ioctl_setwinsize)(struct tty *tty, const struct winsize *size);
	int (*ioctl_getwinsize)(struct tty *tty, struct winsize *size);

@@ -72,6 +75,16 @@ struct tty_ops {

	// last chance to flush output from a TTY (e.g. after a oops)
	int (*force_flush)(struct tty *tty);

	/**
	 * Called each time something get the control of the tty (such as a user
	 * process after a open() on a TTY device, or from the kernel itself).
	 * Negative value is expected if an error occurs.
	 */
	int (*open)(struct tty *tty);

	// release an opened tty (should be called symmetrically with open)
	void (*release)(struct tty *tty);
};


@@ -174,7 +187,8 @@ extern inline int tty_set_termios(struct tty *tty, const struct termios *ios)

/**
 * Used to dispatch tty-level ioctls using tty->ops and tty data.
 * return special value -EFAULT if ioctl is not tty-level command
 * Any non-implemented command will cause a call to tty->ops->ioctl() if not
 * NULL.
 */
int tty_ioctl(struct tty *tty, int cmd, void *data);

@@ -197,4 +211,16 @@ extern inline int tty_force_flush(struct tty *tty) {
	return -EIO;
}


extern inline int tty_open(struct tty *tty) {
	if(tty->ops->open != NULL)
		return tty->ops->open(tty);
	return 0;
}

extern inline void tty_release(struct tty *tty) {
	if(tty->ops->release != NULL)
		tty->ops->release(tty);
}

#endif //_SYS_TTY_H