diff --git a/drivers/floppy/floppy.c b/drivers/floppy/floppy.c index e0ec37845..1de97cdaf 100644 --- a/drivers/floppy/floppy.c +++ b/drivers/floppy/floppy.c @@ -328,7 +328,7 @@ PRIVATE void f_expire_tmrs(struct driver *dp) * for each expired timers. FLOPPY watchdog functions are f_tmr_timeout() * and stop_motor(). Possibly a new alarm call must be scheduled. */ - tmrs_exptimers(&f_timers, now); + tmrs_exptimers(&f_timers, now, NULL); if (f_timers == NULL) { f_next_timeout = TMR_NEVER; } else { /* set new sync alarm */ @@ -354,7 +354,7 @@ tmr_func_t watchdog; /* watchdog function to be called */ panic("FLOPPY","Couldn't get uptime from clock.", s); /* Add the timer to the local timer queue. */ - tmrs_settimer(&f_timers, tp, now + delta, watchdog); + tmrs_settimer(&f_timers, tp, now + delta, watchdog, NULL); /* Possibly reschedule an alarm call. This happens when the front of the * timers queue was reinserted at another position, i.e., when a timer was diff --git a/drivers/fxp/fxp.c b/drivers/fxp/fxp.c index ea6e535a6..8dfca6a1c 100644 --- a/drivers/fxp/fxp.c +++ b/drivers/fxp/fxp.c @@ -2369,7 +2369,7 @@ tmr_func_t watchdog; /* watchdog function to be called */ panic("FXP","unable to get uptime from clock", r); /* Add the timer to the local timer queue. */ - tmrs_settimer(&fxp_timers, tp, now + delta, watchdog); + tmrs_settimer(&fxp_timers, tp, now + delta, watchdog, NULL); /* Possibly reschedule an alarm call. This happens when a new timer * is added in front. @@ -2407,7 +2407,7 @@ PRIVATE void fxp_expire_timers() /* Scan the timers queue for expired timers. Dispatch the watchdog function * for each expired timers. Possibly a new alarm call must be scheduled. */ - tmrs_exptimers(&fxp_timers, now); + tmrs_exptimers(&fxp_timers, now, NULL); if (fxp_timers == NULL) fxp_next_timeout= TMR_NEVER; else diff --git a/drivers/tty/console.c b/drivers/tty/console.c index b08dfab41..2dca24fb1 100644 --- a/drivers/tty/console.c +++ b/drivers/tty/console.c @@ -114,7 +114,7 @@ struct sequence { unsigned char value; }; -FORWARD _PROTOTYPE( void cons_write, (struct tty *tp) ); +FORWARD _PROTOTYPE( int cons_write, (struct tty *tp, int try) ); FORWARD _PROTOTYPE( void cons_echo, (tty_t *tp, int c) ); FORWARD _PROTOTYPE( void out_char, (console_t *cons, int c) ); FORWARD _PROTOTYPE( void putk, (int c) ); @@ -128,14 +128,15 @@ FORWARD _PROTOTYPE( void get_6845, (int reg, unsigned *val) ); FORWARD _PROTOTYPE( void stop_beep, (timer_t *tmrp) ); FORWARD _PROTOTYPE( void cons_org0, (void) ); FORWARD _PROTOTYPE( int ga_program, (struct sequence *seq) ); -FORWARD _PROTOTYPE( void cons_ioctl, (tty_t *tp) ); +FORWARD _PROTOTYPE( int cons_ioctl, (tty_t *tp, int) ); /*===========================================================================* * cons_write * *===========================================================================*/ -PRIVATE void cons_write(tp) +PRIVATE int cons_write(tp, try) register struct tty *tp; /* tells which terminal is to be used */ +int try; { /* Copy as much data as possible to the output queue, then start I/O. On * memory-mapped terminals, such as the IBM console, the I/O will also be @@ -148,6 +149,8 @@ register struct tty *tp; /* tells which terminal is to be used */ char buf[64]; console_t *cons = tp->tty_priv; + if(try) return 1; /* we can always write to console */ + /* Check quickly for nothing to do, so this can be called often without * unmodular tests elsewhere. */ @@ -757,7 +760,7 @@ PRIVATE void beep() } } /* Add a timer to the timers list. Possibly reschedule the alarm. */ - tmrs_settimer(&tty_timers, &tmr_stop_beep, now+B_TIME, stop_beep); + tmrs_settimer(&tty_timers, &tmr_stop_beep, now+B_TIME, stop_beep, NULL); if (tty_timers->tmr_exp_time != tty_next_timeout) { tty_next_timeout = tty_timers->tmr_exp_time; if ((s=sys_syncalrm(SELF, tty_next_timeout, 1)) != OK) @@ -873,7 +876,7 @@ tty_t *tp; cons->c_column = 0; } select_console(0); - cons_ioctl(tp); + cons_ioctl(tp, 0); } /*==========================================================================* @@ -1110,8 +1113,9 @@ struct sequence *seq; /*===========================================================================* * cons_ioctl * *===========================================================================*/ -PRIVATE void cons_ioctl(tp) +PRIVATE int cons_ioctl(tp, try) tty_t *tp; +int try; { /* Set the screen dimensions. */ diff --git a/drivers/tty/keyboard.c b/drivers/tty/keyboard.c index 932e5915b..a878344f9 100644 --- a/drivers/tty/keyboard.c +++ b/drivers/tty/keyboard.c @@ -7,6 +7,8 @@ */ #include "../drivers.h" +#include +#include #include #include #include @@ -84,7 +86,7 @@ FORWARD _PROTOTYPE( int scan_keyboard, (void) ); FORWARD _PROTOTYPE( unsigned make_break, (int scode) ); FORWARD _PROTOTYPE( void set_leds, (void) ); FORWARD _PROTOTYPE( void show_key_mappings, (void) ); -FORWARD _PROTOTYPE( void kb_read, (struct tty *tp) ); +FORWARD _PROTOTYPE( int kb_read, (struct tty *tp, int try) ); FORWARD _PROTOTYPE( unsigned map_key, (int scode) ); @@ -147,6 +149,9 @@ message *m_ptr; if (ihead == ibuf + KB_IN_BYTES) ihead = ibuf; icount++; tty_table[ccurrent].tty_events = 1; + if(tty_table[ccurrent].tty_select_ops & SEL_RD) { + select_retry(&tty_table[ccurrent]); + } } } @@ -154,8 +159,9 @@ message *m_ptr; /*==========================================================================* * kb_read * *==========================================================================*/ -PRIVATE void kb_read(tp) +PRIVATE int kb_read(tp, try) tty_t *tp; +int try; { /* Process characters from the circular keyboard buffer. */ @@ -165,6 +171,12 @@ tty_t *tp; tp = &tty_table[ccurrent]; /* always use the current console */ + if(try) { + printf("tty: kb: try: %d icount: %d\n", try, icount); + if(icount > 0) return 1; + return 0; + } + while (icount > 0) { scode = *itail++; /* take one key scan code */ if (itail == ibuf + KB_IN_BYTES) itail = ibuf; @@ -213,6 +225,8 @@ tty_t *tp; } } } + + return 1; } diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 1a8ed8141..bbc4f5849 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -59,14 +59,14 @@ typedef struct pty { PRIVATE pty_t pty_table[NR_PTYS]; /* PTY bookkeeping */ -FORWARD _PROTOTYPE( void pty_write, (tty_t *tp) ); +FORWARD _PROTOTYPE( int pty_write, (tty_t *tp, int try) ); FORWARD _PROTOTYPE( void pty_echo, (tty_t *tp, int c) ); FORWARD _PROTOTYPE( void pty_start, (pty_t *pp) ); FORWARD _PROTOTYPE( void pty_finish, (pty_t *pp) ); -FORWARD _PROTOTYPE( void pty_read, (tty_t *tp) ); -FORWARD _PROTOTYPE( void pty_close, (tty_t *tp) ); -FORWARD _PROTOTYPE( void pty_icancel, (tty_t *tp) ); -FORWARD _PROTOTYPE( void pty_ocancel, (tty_t *tp) ); +FORWARD _PROTOTYPE( int pty_read, (tty_t *tp, int try) ); +FORWARD _PROTOTYPE( int pty_close, (tty_t *tp, int try) ); +FORWARD _PROTOTYPE( int pty_icancel, (tty_t *tp, int try) ); +FORWARD _PROTOTYPE( int pty_ocancel, (tty_t *tp, int try) ); /*==========================================================================* @@ -201,8 +201,9 @@ message *m_ptr; /*==========================================================================* * pty_write * *==========================================================================*/ -PRIVATE void pty_write(tp) +PRIVATE int pty_write(tp, try) tty_t *tp; +int try; { /* (*dev_write)() routine for PTYs. Transfer bytes from the writer on * /dev/ttypX to the output buffer. @@ -213,6 +214,7 @@ tty_t *tp; /* PTY closed down? */ if (pp->state & PTY_CLOSED) { + if(try) return 1; if (tp->tty_outleft > 0) { tty_reply(tp->tty_outrepcode, tp->tty_outcaller, tp->tty_outproc, EIO); @@ -227,7 +229,11 @@ tty_t *tp; count = bufend(pp->obuf) - pp->ohead; if (count > ocount) count = ocount; if (count > tp->tty_outleft) count = tp->tty_outleft; - if (count == 0 || tp->tty_inhibited) break; + if (count == 0 || tp->tty_inhibited) { + if(try) return 0; + break; + } + if(try) return 1; /* Copy from user space to the PTY output buffer. */ if((s = sys_vircopy(tp->tty_outproc, D, (vir_bytes) tp->tty_out_vir, @@ -258,9 +264,9 @@ tty_t *tp; } } pty_finish(pp); + return 1; } - /*==========================================================================* * pty_echo * *==========================================================================*/ @@ -341,8 +347,9 @@ pty_t *pp; /*==========================================================================* * pty_read * *==========================================================================*/ -PRIVATE void pty_read(tp) +PRIVATE int pty_read(tp, try) tty_t *tp; +int try; { /* Offer bytes from the PTY writer for input on the TTY. (Do it one byte at * a time, 99% of the writes will be for one byte, so no sense in being smart.) @@ -351,12 +358,19 @@ tty_t *tp; char c; if (pp->state & PTY_CLOSED) { + if(try) return 1; if (tp->tty_inleft > 0) { tty_reply(tp->tty_inrepcode, tp->tty_incaller, tp->tty_inproc, tp->tty_incum); tp->tty_inleft = tp->tty_incum = 0; } - return; + return 1; + } + + if(try) { + if(pp->wrleft > 0) + return 1; + return 0; } while (pp->wrleft > 0) { @@ -386,8 +400,9 @@ tty_t *tp; /*==========================================================================* * pty_close * *==========================================================================*/ -PRIVATE void pty_close(tp) +PRIVATE int pty_close(tp, try) tty_t *tp; +int try; { /* The tty side has closed, so shut down the pty side. */ pty_t *pp = tp->tty_priv; @@ -411,8 +426,9 @@ tty_t *tp; /*==========================================================================* * pty_icancel * *==========================================================================*/ -PRIVATE void pty_icancel(tp) +PRIVATE int pty_icancel(tp, try) tty_t *tp; +int try; { /* Discard waiting input. */ pty_t *pp = tp->tty_priv; @@ -428,8 +444,9 @@ tty_t *tp; /*==========================================================================* * pty_ocancel * *==========================================================================*/ -PRIVATE void pty_ocancel(tp) +PRIVATE int pty_ocancel(tp, try) tty_t *tp; +int try; { /* Drain the output buffer. */ pty_t *pp = tp->tty_priv; diff --git a/drivers/tty/rs232.c b/drivers/tty/rs232.c index 8fa1b2d16..1023fdab3 100644 --- a/drivers/tty/rs232.c +++ b/drivers/tty/rs232.c @@ -253,11 +253,11 @@ FORWARD _PROTOTYPE( int rs232_handler, (message *m) ); FORWARD _PROTOTYPE( void in_int, (rs232_t *rs) ); FORWARD _PROTOTYPE( void line_int, (rs232_t *rs) ); FORWARD _PROTOTYPE( void modem_int, (rs232_t *rs) ); -FORWARD _PROTOTYPE( void rs_write, (tty_t *tp) ); +FORWARD _PROTOTYPE( int rs_write, (tty_t *tp, int try) ); FORWARD _PROTOTYPE( void rs_echo, (tty_t *tp, int c) ); FORWARD _PROTOTYPE( void rs_ioctl, (tty_t *tp) ); FORWARD _PROTOTYPE( void rs_config, (rs232_t *rs) ); -FORWARD _PROTOTYPE( void rs_read, (tty_t *tp) ); +FORWARD _PROTOTYPE( int rs_read, (tty_t *tp, int try) ); FORWARD _PROTOTYPE( void rs_icancel, (tty_t *tp) ); FORWARD _PROTOTYPE( void rs_ocancel, (tty_t *tp) ); FORWARD _PROTOTYPE( void rs_ostart, (rs232_t *rs) ); @@ -282,8 +282,9 @@ PRIVATE int my_inb(port_t port) /*==========================================================================* * rs_write * *==========================================================================*/ -PRIVATE void rs_write(tp) +PRIVATE void rs_write(tp, try) register tty_t *tp; +int try; { /* (*devwrite)() routine for RS232. */ @@ -301,7 +302,7 @@ register tty_t *tp; if (rs->drain) { /* Wait for the line to drain then reconfigure and continue output. */ - if (rs->ocount > 0) return; + if (rs->ocount > 0) return 0; rs->drain = FALSE; rs_config(rs); } @@ -312,7 +313,11 @@ register tty_t *tp; count = bufend(rs->obuf) - rs->ohead; if (count > ocount) count = ocount; if (count > tp->tty_outleft) count = tp->tty_outleft; - if (count == 0 || tp->tty_inhibited) break; + if (count == 0 || tp->tty_inhibited) { + if(try) return 0; + break; + } + if(try) return 1; /* Copy from user space to the RS232 output buffer. */ sys_vircopy(tp->tty_outproc, D, (vir_bytes) tp->tty_out_vir, @@ -346,6 +351,8 @@ register tty_t *tp; tty_reply(tp->tty_outrepcode, tp->tty_outcaller, tp->tty_outproc, EIO); tp->tty_outleft = tp->tty_outcum = 0; } + + return 1; } @@ -650,8 +657,9 @@ tty_t *tp; /* which TTY */ /*==========================================================================* * rs_read * *==========================================================================*/ -PRIVATE void rs_read(tp) +PRIVATE void rs_read(tp, try) tty_t *tp; /* which tty */ +int try; { /* Process characters from the circular input buffer. */ @@ -659,6 +667,7 @@ tty_t *tp; /* which tty */ int icount, count, ostate; if (!(tp->tty_termios.c_cflag & CLOCAL)) { + if(try) return 1; /* Send a SIGHUP if hangup detected. */ lock(); ostate = rs->ostate; @@ -671,6 +680,12 @@ tty_t *tp; /* which tty */ } } + if(try) { + if(rs->icount > 0) + return 1; + return 0; + } + while ((count = rs->icount) > 0) { icount = bufend(rs->ibuf) - rs->itail; if (count > icount) count = icount; diff --git a/drivers/tty/tty.c b/drivers/tty/tty.c index 846371950..f20c8ded9 100644 --- a/drivers/tty/tty.c +++ b/drivers/tty/tty.c @@ -18,14 +18,16 @@ * * The valid messages and their parameters are: * - * HARD_INT: output has been completed or input has arrived - * HARD_STOP: MINIX wants to shutdown; run code to cleanly stop - * DEV_READ: a process wants to read from a terminal - * DEV_WRITE: a process wants to write on a terminal - * DEV_IOCTL: a process wants to change a terminal's parameters - * DEV_OPEN: a tty line has been opened - * DEV_CLOSE: a tty line has been closed - * CANCEL: terminate a previous incomplete system call immediately + * HARD_INT: output has been completed or input has arrived + * HARD_STOP: MINIX wants to shutdown; run code to cleanly stop + * DEV_READ: a process wants to read from a terminal + * DEV_WRITE: a process wants to write on a terminal + * DEV_IOCTL: a process wants to change a terminal's parameters + * DEV_OPEN: a tty line has been opened + * DEV_CLOSE: a tty line has been closed + * DEV_SELECT: start select notification request + * DEV_SELECT_CAN: cancel select notification + * CANCEL: terminate a previous incomplete system call immediately * * m_type TTY_LINE PROC_NR COUNT TTY_SPEK TTY_FLAGS ADDRESS * --------------------------------------------------------------------------- @@ -52,6 +54,7 @@ * Jul 13, 2004 support for function key observers (Jorrit N. Herder) */ +#include "../drivers.h" #include "../drivers.h" #include #if ENABLE_SRCCOMPAT || ENABLE_BINCOMPAT @@ -65,6 +68,9 @@ #endif #include "tty.h" +#include +#include + extern int irq_hook_id; /* Address of a tty structure. */ @@ -105,6 +111,7 @@ FORWARD _PROTOTYPE( void do_open, (tty_t *tp, message *m_ptr) ); FORWARD _PROTOTYPE( void do_close, (tty_t *tp, message *m_ptr) ); FORWARD _PROTOTYPE( void do_read, (tty_t *tp, message *m_ptr) ); FORWARD _PROTOTYPE( void do_write, (tty_t *tp, message *m_ptr) ); +FORWARD _PROTOTYPE( void do_select, (tty_t *tp, message *m_ptr) ); FORWARD _PROTOTYPE( void in_transfer, (tty_t *tp) ); FORWARD _PROTOTYPE( int tty_echo, (tty_t *tp, int ch) ); FORWARD _PROTOTYPE( void rawecho, (tty_t *tp, int ch) ); @@ -265,12 +272,13 @@ PUBLIC void main(void) /* Execute the requested device driver function. */ switch (tty_mess.m_type) { - case DEV_READ: do_read(tp, &tty_mess); break; - case DEV_WRITE: do_write(tp, &tty_mess); break; - case DEV_IOCTL: do_ioctl(tp, &tty_mess); break; - case DEV_OPEN: do_open(tp, &tty_mess); break; - case DEV_CLOSE: do_close(tp, &tty_mess); break; - case CANCEL: do_cancel(tp, &tty_mess); break; + case DEV_READ: do_read(tp, &tty_mess); break; + case DEV_WRITE: do_write(tp, &tty_mess); break; + case DEV_IOCTL: do_ioctl(tp, &tty_mess); break; + case DEV_OPEN: do_open(tp, &tty_mess); break; + case DEV_CLOSE: do_close(tp, &tty_mess); break; + case DEV_SELECT: do_select(tp, &tty_mess); break; + case CANCEL: do_cancel(tp, &tty_mess); break; default: printf("Warning, TTY got unexpected request %d from %d\n", tty_mess.m_type, tty_mess.m_source); @@ -335,8 +343,11 @@ register message *m_ptr; /* pointer to message sent to the task */ in_transfer(tp); /* ...then go back for more. */ handle_events(tp); - if (tp->tty_inleft == 0) + if (tp->tty_inleft == 0) { + if(tp->tty_select_ops) + select_retry(tp); return; /* already done */ + } /* There were no bytes in the input queue available, so either suspend * the caller or break off the read if nonblocking. @@ -350,6 +361,8 @@ register message *m_ptr; /* pointer to message sent to the task */ } } tty_reply(TASK_REPLY, m_ptr->m_source, m_ptr->PROC_NR, r); + if(tp->tty_select_ops) + select_retry(tp); } @@ -386,7 +399,11 @@ register message *m_ptr; /* pointer to message sent to the task */ /* Try to write. */ handle_events(tp); - if (tp->tty_outleft == 0) return; /* already done */ + if (tp->tty_outleft == 0) { + if(tp->tty_select_ops) + select_retry(tp); + return; /* already done */ + } /* None or not all the bytes could be written, so either suspend the * caller or break off the write if nonblocking. @@ -400,6 +417,8 @@ register message *m_ptr; /* pointer to message sent to the task */ } } tty_reply(TASK_REPLY, m_ptr->m_source, m_ptr->PROC_NR, r); + if(tp->tty_select_ops) + select_retry(tp); } @@ -509,8 +528,8 @@ message *m_ptr; /* pointer to message sent to task */ if (r != OK) break; switch (param.i) { case TCIFLUSH: tty_icancel(tp); break; - case TCOFLUSH: (*tp->tty_ocancel)(tp); break; - case TCIOFLUSH: tty_icancel(tp); (*tp->tty_ocancel)(tp);break; + case TCOFLUSH: (*tp->tty_ocancel)(tp, 0); break; + case TCIOFLUSH: tty_icancel(tp); (*tp->tty_ocancel)(tp, 0);break; default: r = EINVAL; } break; @@ -537,7 +556,7 @@ message *m_ptr; /* pointer to message sent to task */ break; case TCSBRK: - if (tp->tty_break != NULL) (*tp->tty_break)(tp); + if (tp->tty_break != NULL) (*tp->tty_break)(tp,0); break; case TIOCGWINSZ: @@ -658,8 +677,8 @@ message *m_ptr; /* pointer to message sent to task */ if (m_ptr->TTY_LINE != LOG_MINOR && --tp->tty_openct == 0) { tp->tty_pgrp = 0; tty_icancel(tp); - (*tp->tty_ocancel)(tp); - (*tp->tty_close)(tp); + (*tp->tty_ocancel)(tp, 0); + (*tp->tty_close)(tp, 0); tp->tty_termios = termios_defaults; tp->tty_winsize = winsize_defaults; setattr(tp); @@ -692,7 +711,7 @@ message *m_ptr; /* pointer to message sent to task */ } if ((mode & W_BIT) && tp->tty_outleft != 0 && proc_nr == tp->tty_outproc) { /* Process was writing when killed. Clean up output. */ - (*tp->tty_ocancel)(tp); + (*tp->tty_ocancel)(tp, 0); tp->tty_outleft = tp->tty_outcum = 0; } if (tp->tty_ioreq != 0 && proc_nr == tp->tty_ioproc) { @@ -703,6 +722,60 @@ message *m_ptr; /* pointer to message sent to task */ tty_reply(TASK_REPLY, m_ptr->m_source, proc_nr, EINTR); } +PUBLIC int select_try(struct tty *tp, int ops) +{ + int ready_ops = 0; + + /* special case. if line is hung up, no operations will block. + * (and it can be seen as an exceptional condition.) + */ + if (tp->tty_termios.c_ospeed == B0) { + printf("tty: hangup always ok\n"); + ready_ops |= ops; + } + + if(ops & SEL_RD) { + /* will i/o not block on read? */ + if (tp->tty_inleft > 0) { + ready_ops |= SEL_RD; /* EIO - no blocking */ + } else if(tp->tty_incount > 0) { + /* is a regular read possible? tty_incount + * says there is data. but a read will only succeed + * in canonical mode if a newline has been seen. + */ + if(!(tp->tty_termios.c_lflag & ICANON) || + tp->tty_eotct > 0) { + ready_ops |= SEL_RD; + } + } + } + + if(ops & SEL_WR) { + if (tp->tty_outleft > 0) { + ready_ops |= SEL_WR; /* EIO - no blocking */ + } + if((*tp->tty_devwrite)(tp, 1)) { + ready_ops |= SEL_WR; /* real write possible */ + } + } + + return ready_ops; +} + +PUBLIC int select_retry(struct tty *tp) +{ + int ops; + if((ops = select_try(tp, tp->tty_select_ops))) { + message m; + m.NOTIFY_TYPE = DEV_SELECTED; + m.NOTIFY_ARG = tp->tty_index; + m.NOTIFY_FLAGS = ops; + notify(tp->tty_select_proc, &m); + tp->tty_select_ops &= ~ops; + } + + return OK; +} /*===========================================================================* * handle_events * @@ -731,10 +804,10 @@ tty_t *tp; /* TTY to check for events. */ tp->tty_events = 0; /* Read input and perform input processing. */ - (*tp->tty_devread)(tp); + (*tp->tty_devread)(tp, 0); /* Perform output processing and write output. */ - (*tp->tty_devwrite)(tp); + (*tp->tty_devwrite)(tp, 0); /* Ioctl waiting for some event? */ if (tp->tty_ioreq != 0) dev_ioctl(tp); @@ -1288,7 +1361,7 @@ tty_t *tp; if (tp->tty_termios.c_ospeed == B0) sigchar(tp, SIGHUP); /* Set new line speed, character size, etc at the device level. */ - (*tp->tty_ioctl)(tp); + (*tp->tty_ioctl)(tp, 0); } @@ -1335,7 +1408,7 @@ int sig; /* SIGINT, SIGQUIT, SIGKILL or SIGHUP */ if (!(tp->tty_termios.c_lflag & NOFLSH)) { tp->tty_incount = tp->tty_eotct = 0; /* kill earlier input */ tp->tty_intail = tp->tty_inhead; - (*tp->tty_ocancel)(tp); /* kill all output */ + (*tp->tty_ocancel)(tp, 0); /* kill all output */ tp->tty_inhibited = RUNNING; tp->tty_events = 1; } @@ -1352,7 +1425,7 @@ register tty_t *tp; tp->tty_incount = tp->tty_eotct = 0; tp->tty_intail = tp->tty_inhead; - (*tp->tty_icancel)(tp); + (*tp->tty_icancel)(tp, 0); } @@ -1411,7 +1484,7 @@ PRIVATE void expire_timers(void) /* Scan the queue of timers for expired timers. This dispatch the watchdog * functions of expired timers. Possibly a new alarm call must be scheduled. */ - tmrs_exptimers(&tty_timers, now); + tmrs_exptimers(&tty_timers, now, NULL); if (tty_timers == NULL) tty_next_timeout = TMR_NEVER; else { /* set new sync alarm */ tty_next_timeout = tty_timers->tmr_exp_time; @@ -1438,10 +1511,10 @@ int enable; /* set timer if true, otherwise unset */ exp_time = now + tty_ptr->tty_termios.c_cc[VTIME] * (HZ/10); /* Set a new timer for enabling the TTY events flags. */ tmrs_settimer(&tty_timers, &tty_ptr->tty_tmr, - exp_time, tty_timed_out); + exp_time, tty_timed_out, NULL); } else { /* Remove the timer from the active and expired lists. */ - tmrs_clrtimer(&tty_timers, &tty_ptr->tty_tmr); + tmrs_clrtimer(&tty_timers, &tty_ptr->tty_tmr, NULL); } /* Now check if a new alarm must be scheduled. This happens when the front @@ -1460,12 +1533,39 @@ int enable; /* set timer if true, otherwise unset */ /*==========================================================================* * tty_devnop * *==========================================================================*/ -PUBLIC void tty_devnop(tp) +PUBLIC int tty_devnop(tp, try) tty_t *tp; +int try; { /* Some functions need not be implemented at the device level. */ } +/*===========================================================================* + * do_select * + *===========================================================================*/ +PRIVATE void do_select(tp, m_ptr) +register tty_t *tp; /* pointer to tty struct */ +register message *m_ptr; /* pointer to message sent to the task */ +{ + int ops, ready_ops = 0, watch; + printf("doing select..\n"); + + ops = m_ptr->PROC_NR & (SEL_RD|SEL_WR|SEL_ERR); + watch = (m_ptr->PROC_NR & SEL_NOTIFY) ? 1 : 0; + + ready_ops = select_try(tp, ops); + + if(!ready_ops && ops && watch) { + printf("doing select.. ops %d\n", ops); + tp->tty_select_ops |= ops; + tp->tty_select_proc = m_ptr->m_source; + } else printf("not doing select.. ready_ops %d ops %d watch %d\n", + ready_ops, ops, watch); + + tty_reply(TASK_REPLY, m_ptr->m_source, m_ptr->PROC_NR, ready_ops); + + return; +} #if ENABLE_SRCCOMPAT || ENABLE_BINCOMPAT /*===========================================================================* diff --git a/drivers/tty/tty.h b/drivers/tty/tty.h index d931cb4fa..436ccdf21 100644 --- a/drivers/tty/tty.h +++ b/drivers/tty/tty.h @@ -13,7 +13,7 @@ #define O_NONBLOCK 04000 struct tty; -typedef _PROTOTYPE( void (*devfun_t), (struct tty *tp) ); +typedef _PROTOTYPE( int (*devfun_t), (struct tty *tp, int try_only) ); typedef _PROTOTYPE( void (*devfunarg_t), (struct tty *tp, int c) ); typedef struct tty { @@ -62,6 +62,10 @@ typedef struct tty { int tty_ioreq; /* ioctl request code */ vir_bytes tty_iovir; /* virtual address of ioctl buffer */ + /* select() data */ + int tty_select_ops; /* which operations are interesting */ + int tty_select_proc; /* which process wants notification */ + /* Miscellaneous. */ devfun_t tty_ioctl; /* set line speed, etc. at the device level */ devfun_t tty_close; /* tell the device that the tty is closed */ @@ -70,6 +74,7 @@ typedef struct tty { struct winsize tty_winsize; /* window size (#lines and #columns) */ u16_t tty_inbuf[TTY_IN_BYTES];/* tty input buffer */ + } tty_t; /* Memory allocated in tty.c, so extern here. */ @@ -116,7 +121,8 @@ _PROTOTYPE( void out_process, (struct tty *tp, char *bstart, char *bpos, _PROTOTYPE( void tty_wakeup, (clock_t now) ); _PROTOTYPE( void tty_reply, (int code, int replyee, int proc_nr, int status) ); -_PROTOTYPE( void tty_devnop, (struct tty *tp) ); +_PROTOTYPE( int tty_devnop, (struct tty *tp, int try) ); +_PROTOTYPE( int select_retry, (struct tty *tp) ); /* rs232.c */ _PROTOTYPE( void rs_init, (struct tty *tp) );