Commit f50793a8 authored by Léo Grange's avatar Léo Grange

VTs and CDC/ACM USB TTYs now use the centralized TTY device

parent 43740f43
......@@ -7,15 +7,12 @@
#include <sys/stimer.h>
#include <sys/time.h>
#include <device/tty.h>
#include <device/terminal/fx9860/text_display.h>
#include <utils/log.h>
#define VT_INPUT_BUFFER 256
#define VT_LINE_BUFFER 128
// for VT100 escape code handling :
// not in an escape sequence
......@@ -62,27 +59,9 @@ struct vt_instance {
static struct vt_instance _vts[VT_MAX_TERMINALS];
static int _vt_current;
static struct tty *vt_get_tty(uint16 minor);
const struct device virtual_term_device = {
.name = "v-term",
.init = &vt_init,
.open = &vt_open,
.get_tty = &vt_get_tty
};
static const struct file_operations _vt_fop = {
.release = &vt_release,
.write = &vt_write,
.read = &vt_read,
.ioctl = &vt_ioctl
};
static const struct text_display *_tdisp = &fx9860_text_display;
static int vt_ioctl_getwinsize(struct tty *tty, struct winsize *size);
static int vt_ioctl_setwinsize(struct tty *tty, const struct winsize *size);
......@@ -141,13 +120,14 @@ void vt_init() {
_vts[i].saved_posx = 0;
_vts[i].saved_posy = 0;
// set TTY default settings
vt_clear_escape_code(_vts + i);
// set TTY default settings, and add it to TTY device
tty_default_init(&_vts[i].tty);
_vts[i].tty.private = & _vts[i];
_vts[i].tty.ops = &_vt_tty_ops;
vt_clear_escape_code(_vts + i);
ttydev_set_minor(VT_MINOR_BASE + i, &_vts[i].tty);
}
}
......@@ -155,7 +135,6 @@ void vt_init() {
/**
* Soft timer used to display the screen only once per tick if needed.
* This allow minimal drawing without catastrophic counterpart.
* FIXME add a TTY function to force flushing (e.g. after a kernel oops)
*/
static void vt_flush_display(void *data) {
(void)data;
......@@ -521,69 +500,18 @@ void vt_set_active(int term) {
}
static int vt_tty_write(struct tty *tty, const char *data, size_t len) {
struct vt_instance *term = tty->private;
int vt_open(uint16 minor, struct file *filep) {
if(minor < VT_MAX_TERMINALS) {
filep->op = &_vt_fop;
filep->private_data = (void*)((int)minor);
return 0;
}
return -ENXIO;
}
static struct tty *vt_get_tty(uint16 minor) {
if(minor < VT_MAX_TERMINALS) {
return &_vts[minor].tty;
}
return NULL;
}
static ssize_t vt_prim_write(struct vt_instance *term, const void *source, size_t len) {
vt_term_print(term, source, len);
vt_term_print(term, data, len);
// screen should be flushed only if it's the current active
if(term == &_vts[_vt_current])
vt_delay_flush();
return len;
}
static int vt_tty_write(struct tty *tty, const char *data, size_t len) {
return vt_prim_write(tty->private, data, len);
}
ssize_t vt_write(struct file *filep, void *source, size_t len) {
int term;
term = (int)(filep->private_data);
if(term >= 0 && term <VT_MAX_TERMINALS) {
return vt_prim_write(&_vts[term], source, len);
}
return -EINVAL;
}
ssize_t vt_read(struct file *filep, void *dest, size_t len) {
int term;
term = (int)(filep->private_data);
if(term >= 0 && term <VT_MAX_TERMINALS) {
return tty_read(& _vts[term].tty, dest, len);
}
return -EINVAL;
}
int vt_release(struct file *filep) {
return 0;
}
static int vt_ioctl_getwinsize(struct tty *tty, struct winsize *size) {
(void)tty;
......@@ -601,21 +529,3 @@ static int vt_ioctl_setwinsize(struct tty *tty, const struct winsize *size) {
return -EINVAL;
}
int vt_ioctl(struct file *filep, int cmd, void *data) {
int term;
term = (int)(filep->private_data);
if(term >= 0 && term <VT_MAX_TERMINALS) {
int ret;
ret = tty_ioctl(&_vts[term].tty, cmd, data);
if(ret == -EFAULT) {
// device-level ioctl command, if any
}
else {
return ret;
}
}
return -EINVAL;
}
......@@ -5,22 +5,21 @@
#include <fs/file.h>
/**
* Virtual terminal device, built on top of text_display interface.
* This device allow to control one or more VT100-like terminals, each of them
* Virtual terminal TTY, built on top of text_display interface.
* This TTY allow to have one or more VT100-like terminals, each of them
* using a private instance of text display and keyboard handling.
*
* Only one (or zero) virtual terminal can be enable at a time.
* Each virtual term is accessible using minor from 0 to (VT_MAX_TERMINALS - 1).
* FIXME for now the keyboard handling use some fx9860-specific functions.
*/
// special characters for cursor
#define VT_CURSOR_CHAR ((char)177)
// first minor number reserver in TTY device, and number of terminals
#define VT_MINOR_BASE 0
#define VT_MAX_TERMINALS 2
extern const struct device virtual_term_device;
// call this function to add the given character as keyboard input
void vt_key_stroke(int code);
......@@ -32,17 +31,11 @@ void vt_key_stroke(int code);
void vt_set_active(int term);
/**
* Initialize virtual terminal subsystem and add each corresponding TTY to
* TTY device.
*/
void vt_init();
int vt_open(uint16 minor, struct file *filep);
int vt_release(struct file *filep);
ssize_t vt_write(struct file *filep, void *source, size_t len);
ssize_t vt_read(struct file *filep, void *dest, size_t len);
int vt_ioctl(struct file *filep, int cmd, void *data);
#endif //_DEVICE_TERMINAL_VIRTUAL_TERM_H
......@@ -4,24 +4,7 @@
#include <utils/strutils.h>
#include <interface/fixos/errno.h>
#include <sys/tty.h>
static struct tty *acm_get_tty(uint16 minor);
const struct device _acm_usb_device = {
.name = "usb-acm",
.init = acm_usb_init,
.open = acm_usb_open,
.get_tty = acm_get_tty
};
static const struct file_operations _fop_acm_usb = {
.release = acm_usb_release,
.write = acm_usb_write,
.read = acm_usb_read,
.ioctl = acm_usb_ioctl
};
#include <device/tty.h>
static int acm_tty_is_ready(struct tty *tty);
......@@ -54,73 +37,18 @@ void acm_usb_init() {
cdc_acm_init();
cdc_acm_set_receive_callback(&acm_input_char);
}
int acm_usb_open(uint16 minor, struct file *filep) {
if(minor == ACM_DEVICE_MINOR) {
filep->op = &_fop_acm_usb;
return 0;
}
return -ENXIO;
// add the CDC/ACM TTY to the TTY device
ttydev_set_minor(ACM_USB_TTY_MINOR, &_acm_tty);
}
static struct tty *acm_get_tty(uint16 minor) {
if(minor == ACM_DEVICE_MINOR) {
return &_acm_tty;
}
return NULL;
}
int acm_usb_release(struct file *filep) {
return 0;
}
ssize_t acm_usb_write(struct file *filep, void *source, size_t len) {
if(cdc_acm_is_ready()) {
return cdc_acm_send(source, len);
}
return -EIO;
}
ssize_t acm_usb_read(struct file *filep, void *dest, size_t len) {
if(cdc_acm_is_ready()) {
return tty_read(&_acm_tty, dest, len);
//return cdc_acm_receive(dest, len);
}
return -EIO;
}
int acm_usb_ioctl(struct file *filep, int cmd, void *data) {
int ret;
ret = tty_ioctl(&_acm_tty, cmd, data);
if(ret == -EFAULT) {
// device-level ioctl command, if any
return -EINVAL;
}
else {
return ret;
}
}
static int acm_tty_is_ready(struct tty *tty) {
(void)tty;
return cdc_acm_is_ready();
}
static int acm_tty_write(struct tty *tty, const char *data, size_t len) {
(void)tty;
if(cdc_acm_is_ready()) {
......
......@@ -11,20 +11,8 @@
#include <fs/file.h>
#define ACM_DEVICE_MINOR 0
extern const struct device _acm_usb_device;
#define ACM_USB_TTY_MINOR 6
void acm_usb_init();
int acm_usb_open(uint16 minor, struct file *filep);
int acm_usb_release(struct file *filep);
ssize_t acm_usb_write(struct file *filep, void *source, size_t len);
ssize_t acm_usb_read(struct file *filep, void *dest, size_t len);
int acm_usb_ioctl(struct file *filep, int cmd, void *data);
#endif //_DEVICE_USB_CDC_ACM_ACM_DEVICE_H
......@@ -40,6 +40,8 @@
#include "sys/sysctl.h"
#include "sys/mem_area.h"
#include "device/tty.h"
extern char cmdargs_begin;
extern char cmdargs_end;
......@@ -89,15 +91,17 @@ void init() {
// console initialisation as soon as possible
dev_init();
// add virtual terminal device (on major 4)
virtual_term_device.init();
dev_register_device(&virtual_term_device, 4);
// add TTY device (on major 4)
ttydev_device.init();
dev_register_device(&ttydev_device, 4);
// add virtual terminal TTYs
vt_init();
// add usb-acm device, major number 3
// USB initialisation
usb_init();
_acm_usb_device.init();
dev_register_device(&_acm_usb_device, 3);
// add usb-acm TTY
acm_usb_init();
DBG_WAIT;
......
......@@ -8,15 +8,17 @@
#include <sys/cmdline.h>
#include <sys/tty.h>
#define CONSOLE_USB_MAJOR 3
#define CONSOLE_USB_MINOR_BASE 0
#include <device/tty.h>
#include <device/terminal/virtual_term.h>
#include <device/usb/cdc_acm/acm_device.h>
#define CONSOLE_TTY_MAJOR 4
#define CONSOLE_TTY_MINOR_BASE 0
#define CONSOLE_VT_MINOR_BASE VT_MINOR_BASE
#define CONSOLE_USB_MINOR_BASE ACM_USB_TTY_MINOR
static uint32 _console_node = (CONSOLE_TTY_MAJOR << 16) | CONSOLE_TTY_MINOR_BASE;
static uint32 _console_node = makedev(CONSOLE_TTY_MAJOR,
CONSOLE_VT_MINOR_BASE);
int parse_console(const char *val) {
//printk(LOG_DEBUG, "ARG: console='%s'\n", val);
......@@ -24,16 +26,20 @@ int parse_console(const char *val) {
if(val[0]=='t' && val[1]=='t' && val[2]=='y') {
// check for ttyn
if(val[3] >= '1' && val[3] <= '9') {
_console_node = (CONSOLE_TTY_MAJOR << 16) |
(CONSOLE_TTY_MINOR_BASE + val[3] - '1');
printk(LOG_INFO, "console: will use tty%d soon\n", val[3]-'0');
return 0;
uint16 minorvt = val[3] - '1' + CONSOLE_VT_MINOR_BASE;
if(minorvt < CONSOLE_VT_MINOR_BASE + VT_MAX_TERMINALS) {
_console_node = makedev(CONSOLE_TTY_MAJOR, minorvt);
printk(LOG_INFO, "console: will use tty%d soon\n",
val[3]-'0');
return 0;
}
}
// check for USB0
else if(!strcmp(val+3, "USB0")) {
_console_node = (CONSOLE_USB_MAJOR << 16) | CONSOLE_USB_MINOR_BASE;
_console_node = makedev(CONSOLE_TTY_MAJOR,
CONSOLE_USB_MINOR_BASE);
printk(LOG_INFO, "console: will use USB soon\n");
return 0;
}
......@@ -55,8 +61,9 @@ void console_make_active() {
if(console_dev != NULL) {
struct tty *tty;
tty = console_dev->get_tty(minor(_console_node));
tty = ttydev_get_minor(minor(_console_node));
if(tty != NULL) {
tty_open(tty);
if(!tty_is_ready(tty)) {
// wait until the TTY is ready
printk(LOG_INFO, "[console tty not ready...]\n");
......
......@@ -44,9 +44,12 @@ int tty_ioctl(struct tty *tty, int cmd, void *data) {
return 0;
case TCSETS:
return tty_set_termios(tty, data);
default:
return -EFAULT;
}
// this point is reached if cmd is not recognized
if(tty->ops->ioctl != NULL)
return tty->ops->ioctl(tty, cmd, data);
return -EINVAL;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment