X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/1eeed1150149b63d6e49e033697454bc12b533b9..35a7d633d3f16c1e0539af6ca5d8e7482926cd93:/lunaix-os/hal/term/term_io.c diff --git a/lunaix-os/hal/term/term_io.c b/lunaix-os/hal/term/term_io.c index 57602c8..03a9572 100644 --- a/lunaix-os/hal/term/term_io.c +++ b/lunaix-os/hal/term/term_io.c @@ -1,81 +1,49 @@ #include #include -#include +#include #include -#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) { - 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? - sched_yieldk(); + yield_current(); 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], 0, max_lb_sz); + sz = deref(current_buf)->len; } - rbuffer_puts(line_in->next, inbuffer, sz); - line_flip(line_in); - 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) { - 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)) { - // 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; @@ -87,18 +55,22 @@ term_read(struct term* 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) { + struct device* chardev; struct linebuffer* line_out = &tdev->line_out; 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); @@ -111,7 +83,7 @@ term_flush(struct term* tdev) off_t off = 0; int ret = 0; while (xmit_len && ret >= 0) { - ret = tdev->chdev->ops.write(tdev->chdev, &xmit_buf[off], 0, xmit_len); + ret = chardev->ops.write(chardev, &xmit_buf[off], 0, xmit_len); xmit_len -= ret; off += ret; count += ret; @@ -124,4 +96,34 @@ term_flush(struct term* tdev) } 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 + } + + pwake_all(&term->line_in_event); } \ No newline at end of file