Boot framework rework (#45)
[lunaix-os.git] / lunaix-os / hal / term / term.c
index 3db875903761375fd575a265662659279fd9d4df..4353265935e13a02479dd0ae3eaf339486467696 100644 (file)
@@ -8,15 +8,11 @@
 
 #include <usr/lunaix/ioctl_defs.h>
 
 
 #include <usr/lunaix/ioctl_defs.h>
 
-#define ANSI_LCNTL 0
 #define termdev(dev) ((struct term*)(dev)->underlay)
 
 #define termdev(dev) ((struct term*)(dev)->underlay)
 
-extern struct term_lcntl ansi_line_controller;
-static struct term_lcntl* line_controls[] = {[ANSI_LCNTL] =
-                                                 &ansi_line_controller};
 #define LCNTL_TABLE_LEN (sizeof(line_controls) / sizeof(struct term_lcntl*))
 
 #define LCNTL_TABLE_LEN (sizeof(line_controls) / sizeof(struct term_lcntl*))
 
-static struct devclass termdev = DEVCLASS(DEVIF_NON, DEVFN_TTY, DEV_VTERM);
+static struct devclass termdev_class = DEVCLASS(DEVIF_NON, DEVFN_TTY, DEV_VTERM);
 
 struct device* sysconsole = NULL;
 
 
 struct device* sysconsole = NULL;
 
@@ -85,7 +81,9 @@ term_exec_cmd(struct device* dev, u32_t req, va_list args)
             tios->c_baud = term->iospeed;
         } break;
         case TDEV_TCSETATTR: {
             tios->c_baud = term->iospeed;
         } break;
         case TDEV_TCSETATTR: {
+            struct termport_cap_ops* cap_ops;
             struct termios* tios = va_arg(args, struct termios*);
             struct termios* tios = va_arg(args, struct termios*);
+
             term->iflags = tios->c_iflag;
             term->oflags = tios->c_oflag;
             term->lflags = tios->c_lflag;
             term->iflags = tios->c_iflag;
             term->oflags = tios->c_oflag;
             term->lflags = tios->c_lflag;
@@ -98,14 +96,16 @@ term_exec_cmd(struct device* dev, u32_t req, va_list args)
                 goto done;
             }
 
                 goto done;
             }
 
+            cap_ops = term->tp_cap->cap_ops;
+
             if (tios->c_baud != term->iospeed) {
                 term->iospeed = tios->c_baud;
 
             if (tios->c_baud != term->iospeed) {
                 term->iospeed = tios->c_baud;
 
-                term->tp_cap->set_speed(term->chdev, tios->c_baud);
+                cap_ops->set_speed(term->chdev, tios->c_baud);
             }
 
             if (old_cf != tios->c_cflag) {
             }
 
             if (old_cf != tios->c_cflag) {
-                term->tp_cap->set_cntrl_mode(term->chdev, tios->c_cflag);
+                cap_ops->set_cntrl_mode(term->chdev, tios->c_cflag);
             }
         } break;
         default:
             }
         } break;
         default:
@@ -146,16 +146,14 @@ tdev_do_read(struct device* dev, void* buf, off_t fpos, size_t len)
     lbuf_ref_t current = ref_current(&tdev->line_in);
     bool cont = true;
     size_t rdsz = 0;
     lbuf_ref_t current = ref_current(&tdev->line_in);
     bool cont = true;
     size_t rdsz = 0;
-    while (cont && rdsz < len) {
-        if (rbuffer_empty(deref(current))) {
-            tdev->line_in.sflags = 0;
-            cont = term_read(tdev);
-        }
 
 
+    while (cont && rdsz < len) {
+        cont = term_read(tdev);
         rdsz += rbuffer_gets(
             deref(current), &((char*)buf)[rdsz], len - rdsz);
     }
         rdsz += rbuffer_gets(
             deref(current), &((char*)buf)[rdsz], len - rdsz);
     }
-
+    
+    tdev->line_in.sflags = 0;
     return rdsz;
 }
 
     return rdsz;
 }
 
@@ -167,6 +165,7 @@ load_default_setting(struct term* tdev)
     tdev->lflags = _ICANON | _IEXTEN | _ISIG | _ECHO | _ECHOE | _ECHONL;
     tdev->iflags = _ICRNL | _IGNBRK;
     tdev->oflags = _ONLCR | _OPOST;
     tdev->lflags = _ICANON | _IEXTEN | _ISIG | _ECHO | _ECHOE | _ECHONL;
     tdev->iflags = _ICRNL | _IGNBRK;
     tdev->oflags = _ONLCR | _OPOST;
+    tdev->iospeed = _B9600;
     memcpy(tdev->cc, default_cc, _NCCS * sizeof(cc_t));
 }
 
     memcpy(tdev->cc, default_cc, _NCCS * sizeof(cc_t));
 }
 
@@ -181,38 +180,46 @@ alloc_term_buffer(struct term* terminal, size_t sz_hlf)
 struct term*
 term_create(struct device* chardev, char* suffix)
 {
 struct term*
 term_create(struct device* chardev, char* suffix)
 {
-    struct term* terminal = vzalloc(sizeof(struct term));
+    struct term* terminal;
+    struct device* tdev;
+    struct capability_meta* termport_cap;
+    struct capability_meta* tios_cap;
 
 
+    terminal = vzalloc(sizeof(struct term));
     if (!terminal) {
         return NULL;
     }
 
     if (!terminal) {
         return NULL;
     }
 
-    terminal->dev = device_allocseq(NULL, terminal);
+    tdev = device_allocseq(NULL, terminal);
+    terminal->dev = tdev;
     terminal->chdev = chardev;
 
     terminal->chdev = chardev;
 
-    terminal->dev->ops.read = tdev_do_read;
-    terminal->dev->ops.write = tdev_do_write;
-    terminal->dev->ops.exec_cmd = term_exec_cmd;
+    tdev->ops.read = tdev_do_read;
+    tdev->ops.write = tdev_do_write;
+    tdev->ops.exec_cmd = term_exec_cmd;
 
 
-    // TODO choice of lcntl can be flexible
-    terminal->lcntl = line_controls[ANSI_LCNTL];
+    waitq_init(&terminal->line_in_event);
 
     alloc_term_buffer(terminal, 1024);
 
     if (chardev) {
         int cdev_var = DEV_VAR_FROM(chardev->ident.unique);
 
     alloc_term_buffer(terminal, 1024);
 
     if (chardev) {
         int cdev_var = DEV_VAR_FROM(chardev->ident.unique);
-        register_device(terminal->dev, &termdev, "tty%s%d", suffix, cdev_var);
+        register_device(tdev, &termdev_class, "tty%s%d", suffix, cdev_var);
     } else {
     } else {
-        register_device(terminal->dev, &termdev, "tty%d", termdev.variant++);
+        register_device(tdev, &termdev_class, "tty%d", termdev_class.variant++);
     }
 
     }
 
-    struct capability_meta* termport_cap = device_get_capability(chardev, TERMPORT_CAP);
+    termport_cap = device_get_capability(chardev, TERMPORT_CAP);
     if (termport_cap) {
     if (termport_cap) {
-        terminal->tp_cap = get_capability(termport_cap, struct termport_capability);
+        terminal->tp_cap = 
+            get_capability(termport_cap, struct termport_capability);
+        
+        assert(terminal->tp_cap->cap_ops);
+        terminal->tp_cap->term = terminal;
     }
 
     }
 
-    struct capability_meta* term_cap = new_capability_marker(TERMIOS_CAP);
-    device_grant_capability(terminal->dev, term_cap);
+    tios_cap = new_capability_marker(TERMIOS_CAP);
+    device_grant_capability(tdev, tios_cap);
 
     load_default_setting(terminal);
 
 
     load_default_setting(terminal);
 
@@ -253,6 +260,7 @@ void
 term_sendsig(struct term* tdev, int signal)
 {
     if ((tdev->lflags & _ISIG)) {
 term_sendsig(struct term* tdev, int signal)
 {
     if ((tdev->lflags & _ISIG)) {
-        proc_setsignal(get_process(tdev->fggrp), signal);
+        signal_send(-tdev->fggrp, signal);
+        pwake_all(&tdev->line_in_event);
     }
 }
\ No newline at end of file
     }
 }
\ No newline at end of file