Merge remote-tracking branch 'origin/master' into isa/arm64
[lunaix-os.git] / lunaix-os / hal / term / term_io.c
index 8042e3b2eae71859816926bcbf8d420c2f873001..03a9572dfb2fd4bbdc71ab4b7d5ec5772b701991 100644 (file)
@@ -1,81 +1,49 @@
 #include <hal/term.h>
 
 #include <lunaix/clock.h>
 #include <hal/term.h>
 
 #include <lunaix/clock.h>
-#include <lunaix/sched.h>
+#include <lunaix/kpreempt.h>
 
 #include <usr/lunaix/term.h>
 
 
 #include <usr/lunaix/term.h>
 
-#define ONBREAK (LSTATE_EOF | LSTATE_SIGRAISE)
-#define ONSTOP (LSTATE_SIGRAISE | LSTATE_EOL | LSTATE_EOF)
+#define ONBREAK (LEVT_EOF | LEVT_SIGRAISE)
+#define ONSTOP (LEVT_SIGRAISE | LEVT_EOL | LEVT_EOF)
 
 static int
 do_read_raw(struct term* tdev)
 {
 
 static int
 do_read_raw(struct term* tdev)
 {
-    struct device* chdev = tdev->chdev;
-
-    struct linebuffer* line_in = &tdev->line_in;
-    size_t max_lb_sz = line_in->sz_hlf;
-
-    line_flip(line_in);
-
-    char* inbuffer = line_in->current->buffer;
-    size_t min = tdev->cc[_VMIN] - 1;
-    size_t sz = chdev->ops.read_async(chdev, inbuffer, 0, max_lb_sz);
-    time_t t = clock_systime(), dt = 0;
-    time_t expr = (tdev->cc[_VTIME] * 100) - 1;
-
+    struct linebuffer* line_in;
+    lbuf_ref_t current_buf;
+    size_t min, sz = 0;
+    time_t t, expr, dt = 0;
+    
+    line_in = &tdev->line_in;
+    current_buf = ref_current(line_in);
+
+    min = tdev->cc[_VMIN] - 1;
+    t = clock_systime();
+    expr = (tdev->cc[_VTIME] * 100) - 1;
+
+    min = MIN(min, (size_t)line_in->sz_hlf);
     while (sz <= min && dt <= expr) {
         // XXX should we held the device lock while we are waiting?
     while (sz <= min && dt <= expr) {
         // XXX should we held the device lock while we are waiting?
-        sched_yieldk();
+        yield_current();
         dt = clock_systime() - t;
         t += dt;
 
         dt = clock_systime() - t;
         t += dt;
 
-        max_lb_sz -= sz;
-
-        // TODO pass a flags to read to indicate it is non blocking ops
-        sz += chdev->ops.read_async(chdev, inbuffer, sz, max_lb_sz);
+        sz = deref(current_buf)->len;
     }
 
     }
 
-    rbuffer_puts(line_in->next, inbuffer, sz);
-    line_flip(line_in);
-
     return 0;
 }
 
     return 0;
 }
 
-static int
-do_read_raw_canno(struct term* tdev)
-{
-    struct device* chdev = tdev->chdev;
-    struct linebuffer* line_in = &tdev->line_in;
-    struct rbuffer* current_buf = line_in->current;
-    int sz = chdev->ops.read(chdev, current_buf->buffer, 0, line_in->sz_hlf);
-
-    current_buf->ptr = sz;
-    current_buf->len = sz;
-
-    return sz;
-}
-
-static int
-term_read_noncano(struct term* tdev)
-{
-    struct device* chdev = tdev->chdev;
-    return do_read_raw(tdev);
-}
-
-static int
+static inline int
 term_read_cano(struct term* tdev)
 {
 term_read_cano(struct term* tdev)
 {
-    struct device* chdev = tdev->chdev;
-    struct linebuffer* line_in = &tdev->line_in;
-    int size = 0;
+    struct linebuffer* line_in;
 
 
+    line_in = &tdev->line_in;
     while (!(line_in->sflags & ONSTOP)) {
     while (!(line_in->sflags & ONSTOP)) {
-        // move all hold-out content to 'next' buffer
-        line_flip(line_in);
-
-        size += do_read_raw_canno(tdev);
-        lcntl_transform_inseq(tdev);
+        pwait(&tdev->line_in_event);
     }
 
     return 0;
     }
 
     return 0;
@@ -87,32 +55,75 @@ term_read(struct term* tdev)
     if ((tdev->lflags & _ICANON)) {
         return term_read_cano(tdev);
     }
     if ((tdev->lflags & _ICANON)) {
         return term_read_cano(tdev);
     }
-    return term_read_noncano(tdev);
+
+    return do_read_raw(tdev);
 }
 
 int
 term_flush(struct term* tdev)
 {
 }
 
 int
 term_flush(struct term* tdev)
 {
-    if ((tdev->oflags & _OPOST)) {
-        lcntl_transform_outseq(tdev);
-    }
-
+    struct device* chardev;
     struct linebuffer* line_out = &tdev->line_out;
     struct linebuffer* line_out = &tdev->line_out;
-    size_t xmit_len = line_out->current->len;
-    void* xmit_buf = line_out->next->buffer;
+    char* xmit_buf = tdev->scratch_pad;
+    lbuf_ref_t current_ref = ref_current(line_out);
+    
+    int count = 0;
+
+    chardev = tdev->chdev;
+
+    while (!rbuffer_empty(deref(current_ref))) {
+        if ((tdev->oflags & _OPOST)) {
+            lcntl_transform_outseq(tdev);
+        }
+
+        size_t xmit_len = line_out->current->len;
 
 
-    rbuffer_gets(line_out->current, xmit_buf, xmit_len);
+        rbuffer_gets(line_out->current, xmit_buf, xmit_len);
 
 
-    off_t off = 0;
-    int ret = 0;
-    while (xmit_len && ret >= 0) {
-        ret = tdev->chdev->ops.write(tdev->chdev, xmit_buf, off, xmit_len);
-        xmit_len -= ret;
-        off += ret;
+        off_t off = 0;
+        int ret = 0;
+        while (xmit_len && ret >= 0) {
+            ret = chardev->ops.write(chardev, &xmit_buf[off], 0, xmit_len);
+            xmit_len -= ret;
+            off += ret;
+            count += ret;
+        }
+
+        // put back the left over if transmittion went south
+        rbuffer_puts(line_out->current, xmit_buf, xmit_len);
+
+        line_flip(line_out);
     }
 
     }
 
-    // put back the left over if transmittion went south
-    rbuffer_puts(line_out->current, xmit_buf, xmit_len);
+    return count;
+}
+
+void
+term_notify_data_avaliable(struct termport_potens* cap)
+{
+    struct term* term;
+    struct device* term_chrdev;
+    struct linebuffer* line_in;
+    lbuf_ref_t current_ref;
+    char* buf;
+    int sz;
+
+    term = cap->term;
+    term_chrdev = term->chdev;
+    line_in = &term->line_in;
+    current_ref = ref_current(line_in);
+    
+    // make room for current buf
+    line_flip(line_in);
+    buf = deref(current_ref)->buffer;
+
+    sz = term_chrdev->ops.read_async(term_chrdev, buf, 0, line_in->sz_hlf);
+    rbuffer_setcontent(deref(current_ref), sz);
+
+    if ((term->lflags & _ICANON)) {
+        lcntl_transform_inseq(term);
+        // write all processed to next, and flip back to current
+    }
 
 
-    return off;
+    pwake_all(&term->line_in_event);
 }
\ No newline at end of file
 }
\ No newline at end of file