./usr/include/minix/sysutil.h minix-sys
./usr/include/minix/termios.h minix-sys
./usr/include/minix/timers.h minix-sys
-./usr/include/minix/tty.h minix-sys
+./usr/include/minix/tty.h minix-sys obsolete
./usr/include/minix/type.h minix-sys
./usr/include/minix/types.h minix-sys obsolete
./usr/include/minix/u64.h minix-sys
SRCS += tty.c pty.c
-DPADD+= ${LIBSYS} ${LIBTIMERS}
-LDADD+= -lsys -ltimers
+DPADD+= ${LIBCHARDRIVER} ${LIBSYS} ${LIBTIMERS}
+LDADD+= -lchardriver -lsys -ltimers
MAN=
#include "tty.h"
void
-do_video(message *m)
+do_video(message *m, int ipc_status)
{
}
}
int
-con_loadfont(message *m)
+con_loadfont(endpoint_t endpt, cp_grant_id_t grant)
{
return 0;
}
}
void
-do_kbd(message *m)
-{
-}
-
-void
-do_kbdaux(message *m)
+do_kbd(message *m, int ipc_status)
{
}
}
int
-kbd_loadmap(message *m)
+kbd_loadmap(endpoint_t endpt, cp_grant_id_t grant)
{
return 0;
}
if (tp->tty_outcaller == KERNEL) {
/* We're trying to print on kernel's behalf */
memcpy(rs->ohead,
- (void *) tp->tty_outgrant + tp->tty_outoffset,
+ (char *) tp->tty_outgrant + tp->tty_outcum,
count);
} else {
if ((r = sys_safecopyfrom(tp->tty_outcaller,
- tp->tty_outgrant, tp->tty_outoffset,
+ tp->tty_outgrant, tp->tty_outcum,
(vir_bytes) rs->ohead, count)) != OK) {
return 0;
}
rs_ostart(rs);
if ((rs->ohead += ocount) >= bufend(rs->obuf))
rs->ohead -= buflen(rs->obuf);
- tp->tty_outoffset += count;
tp->tty_outcum += count;
if ((tp->tty_outleft -= count) == 0) {
/* Output is finished, reply to the writer. */
- tty_reply(DEV_REVIVE, tp->tty_outcaller,
- tp->tty_outproc, tp->tty_outgrant,
+ chardriver_reply_task(tp->tty_outcaller, tp->tty_outid,
tp->tty_outcum);
tp->tty_outcum = 0;
- tp->tty_outgrant = GRANT_INVALID;
+ tp->tty_outcaller = NONE;
}
}
if (tp->tty_outleft > 0 && tp->tty_termios.c_ospeed == B0) {
/* Oops, the line has hung up. */
- tty_reply(DEV_REVIVE, tp->tty_outcaller, tp->tty_outproc,
- tp->tty_outgrant, EIO);
+ chardriver_reply_task(tp->tty_outcaller, tp->tty_outid, EIO);
tp->tty_outleft = tp->tty_outcum = 0;
- tp->tty_outgrant = GRANT_INVALID;
+ tp->tty_outcaller = NONE;
}
return 1;
#include <minix/drivers.h>
#include <termios.h>
-#include <assert.h>
#include <sys/ioctl.h>
#include <sys/vm.h>
#include <sys/video.h>
#include <sys/mman.h>
-#include <minix/tty.h>
-#include <minix/callnr.h>
-#include <minix/com.h>
-#include <minix/sys_config.h>
-#include <minix/vm.h>
#include "tty.h"
/* Set this to 1 if you want console output duplicated on the first
static void get_6845(int reg, unsigned *val);
#endif
+static int video_open(devminor_t minor, int access, endpoint_t user_endpt);
+static int video_close(devminor_t minor);
+static int video_ioctl(devminor_t minor, unsigned long request,
+ endpoint_t endpt, cp_grant_id_t grant, int flags,
+ endpoint_t user_endpt, cdev_id_t id);
+
+static struct chardriver video_tab = {
+ .cdr_open = video_open,
+ .cdr_close = video_close,
+ .cdr_ioctl = video_ioctl
+};
+
/*===========================================================================*
* cons_write *
*===========================================================================*/
if (count > sizeof(buf)) count = sizeof(buf);
if (tp->tty_outcaller == KERNEL) {
/* We're trying to print on kernel's behalf */
- memcpy(buf, (void *) tp->tty_outgrant + tp->tty_outoffset,
- count);
+ memcpy(buf, (char *) tp->tty_outgrant + tp->tty_outcum, count);
} else {
if ((result = sys_safecopyfrom(tp->tty_outcaller,
- tp->tty_outgrant, tp->tty_outoffset,
+ tp->tty_outgrant, tp->tty_outcum,
(vir_bytes) buf, count)) != OK) {
break;
}
}
- tp->tty_outoffset += count;
tbuf = buf;
/* Update terminal data structure. */
/* Reply to the writer if all output is finished or if an error occured. */
if (tp->tty_outleft == 0 || result != OK) {
- tty_reply(DEV_REVIVE, tp->tty_outcaller, tp->tty_outproc,
- tp->tty_outgrant, result != OK ? result : tp->tty_outcum);
+ chardriver_reply_task(tp->tty_outcaller, tp->tty_outid,
+ result != OK ? result : tp->tty_outcum);
tp->tty_outcum = tp->tty_outleft = 0;
- tp->tty_outgrant = GRANT_INVALID;
+ tp->tty_outcaller = NONE;
}
return 0;
}
}
-
/*===========================================================================*
- * do_video *
+ * video_open *
*===========================================================================*/
-void do_video(message *m)
+static int video_open(devminor_t minor, int UNUSED(access),
+ endpoint_t UNUSED(user_endpt))
{
- int r;
-
- /* Execute the requested device driver function. */
- r= EINVAL; /* just in case */
- switch (m->m_type) {
- case DEV_OPEN:
- /* Should grant IOPL */
- disable_console();
- tty_reply(DEV_OPEN_REPL, m->m_source, m->USER_ENDPT,
- (cp_grant_id_t) m->IO_GRANT, OK);
- return;
- case DEV_CLOSE:
- reenable_console();
- tty_reply(DEV_CLOSE_REPL, m->m_source, m->USER_ENDPT,
- (cp_grant_id_t) m->IO_GRANT, OK);
- return;
- case DEV_IOCTL_S:
- switch(m->REQUEST) {
- case TIOCMAPMEM:
- case TIOCUNMAPMEM: {
- int r, do_map;
- struct mapreqvm mapreqvm;
-
- do_map= (m->REQUEST == TIOCMAPMEM); /* else unmap */
-
- r = sys_safecopyfrom(m->m_source,
- (cp_grant_id_t) m->IO_GRANT, 0,
- (vir_bytes) &mapreqvm, sizeof(mapreqvm));
-
- if (r != OK)
- {
- printf("tty: sys_safecopyfrom failed\n");
- break;
- }
+ /* Should grant IOPL */
+ disable_console();
+ return OK;
+}
- /* In safe ioctl mode, the POSITION field contains
- * the endpt number of the original requestor.
- * USER_ENDPT is always FS.
- */
-
- if(do_map) {
- mapreqvm.vaddr_ret = vm_map_phys(m->POSITION,
- (void *) mapreqvm.phys_offset, mapreqvm.size);
- if((r = sys_safecopyto(m->m_source,
- (cp_grant_id_t) m->IO_GRANT, 0,
- (vir_bytes) &mapreqvm,
- sizeof(mapreqvm))) != OK) {
- printf("tty: sys_safecopyto failed\n");
- }
- } else {
- r = vm_unmap_phys(m->POSITION,
- mapreqvm.vaddr, mapreqvm.size);
- }
- break;
- }
- default:
- r= ENOTTY;
- break;
- }
- break;
+/*===========================================================================*
+ * video_close *
+ *===========================================================================*/
+static int video_close(devminor_t minor)
+{
+ reenable_console();
+ return OK;
+}
- default:
- printf(
- "Warning, TTY(video) got unexpected request %d from %d\n",
- m->m_type, m->m_source);
- r= EINVAL;
+/*===========================================================================*
+ * video_ioctl *
+ *===========================================================================*/
+static int video_ioctl(devminor_t minor, unsigned long request,
+ endpoint_t endpt, cp_grant_id_t grant, int flags,
+ endpoint_t user_endpt, cdev_id_t id)
+{
+ struct mapreqvm mapreqvm;
+ int r, do_map;
+
+ switch (request) {
+ case TIOCMAPMEM:
+ case TIOCUNMAPMEM:
+ do_map = (request == TIOCMAPMEM); /* else unmap */
+
+ if ((r = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &mapreqvm,
+ sizeof(mapreqvm))) != OK)
+ return r;
+
+ if (do_map) {
+ mapreqvm.vaddr_ret = vm_map_phys(user_endpt,
+ (void *) mapreqvm.phys_offset, mapreqvm.size);
+ r = sys_safecopyto(endpt, grant, 0, (vir_bytes) &mapreqvm,
+ sizeof(mapreqvm));
+ } else {
+ r = vm_unmap_phys(user_endpt, mapreqvm.vaddr, mapreqvm.size);
}
- tty_reply(DEV_REVIVE, m->m_source, m->USER_ENDPT,
- (cp_grant_id_t) m->IO_GRANT, r);
+
+ return r;
+
+ default:
+ return ENOTTY;
+ }
}
+/*===========================================================================*
+ * do_video *
+ *===========================================================================*/
+void do_video(message *m, int ipc_status)
+{
+ chardriver_process(&video_tab, m, ipc_status);
+}
/*===========================================================================*
* beep_x *
/*===========================================================================*
* con_loadfont *
*===========================================================================*/
-int con_loadfont(m)
-message *m;
+int con_loadfont(endpoint_t endpt, cp_grant_id_t grant)
{
/* Load a font into the EGA or VGA adapter. */
- int result;
+ int r, r2;
static struct sequence seq1[7] = {
{ GA_SEQUENCER_INDEX, 0x00, 0x01 },
{ GA_SEQUENCER_INDEX, 0x02, 0x04 },
seq2[6].value= color ? 0x0E : 0x0A;
- result = ga_program(seq1); /* bring font memory into view */
+ r = ga_program(seq1); /* bring font memory into view */
+ if (r != OK) return r;
- if(sys_safecopyfrom(m->m_source, (cp_grant_id_t) m->IO_GRANT, 0,
- (vir_bytes) font_memory, GA_FONT_SIZE) != OK) {
- printf("tty: copying from %d failed\n", m->m_source);
- return EFAULT;
- }
+ r = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) font_memory, GA_FONT_SIZE);
- result = ga_program(seq2); /* restore */
+ r2 = ga_program(seq2); /* restore */
- return(result);
+ return(r != OK ? r : r2);
}
/*===========================================================================*
static struct kbd
{
- int minor;
+ devminor_t minor;
int nr_open;
char buf[KBD_BUFSZ];
int offset;
int avail;
- int req_size;
- int req_proc;
+ size_t req_size;
+ cdev_id_t req_id;
cp_grant_id_t req_grant;
- vir_bytes req_addr_offset;
- int incaller;
- int select_ops;
- int select_proc;
- int select_minor; /* sanity check only, can be removed */
+ endpoint_t req_caller;
+ unsigned int select_ops;
+ endpoint_t select_proc;
} kbd, kbdaux;
/* Data that is to be sent to the keyboard. Each byte is ACKed by the
static long debug_fkeys = 1;
static timer_t tmr_kbd_wd;
-static void handle_req(struct kbd *kbdp, message *m);
static void kbc_cmd0(int cmd);
static void kbc_cmd1(int cmd, int data);
static int kbc_read(void);
static unsigned map_key(int scode);
static void kbd_watchdog(timer_t *tmrp);
-int micro_delay(u32_t usecs)
+static int kbd_open(devminor_t minor, int access, endpoint_t user_endpt);
+static int kbd_close(devminor_t minor);
+static ssize_t kbd_read(devminor_t minor, u64_t position, endpoint_t endpt,
+ cp_grant_id_t grant, size_t size, int flags, cdev_id_t id);
+static ssize_t kbd_write(devminor_t minor, u64_t position, endpoint_t endpt,
+ cp_grant_id_t grant, size_t size, int flags, cdev_id_t id);
+static int kbd_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt,
+ cp_grant_id_t grant, int flags, endpoint_t user_endpt, cdev_id_t id);
+static int kbd_cancel(devminor_t minor, endpoint_t endpt, cdev_id_t id);
+static int kbd_select(devminor_t minor, unsigned int ops, endpoint_t endpt);
+
+static struct chardriver kbd_tab = {
+ .cdr_open = kbd_open,
+ .cdr_close = kbd_close,
+ .cdr_read = kbd_read,
+ .cdr_write = kbd_write,
+ .cdr_ioctl = kbd_ioctl,
+ .cdr_cancel = kbd_cancel,
+ .cdr_select = kbd_select
+};
+
+/*===========================================================================*
+ * line2kbd *
+ *===========================================================================*/
+static struct kbd *
+line2kbd(devminor_t minor)
{
- /* TTY can't use the library micro_delay() as that calls PM. */
- tickdelay(micros_to_ticks(usecs));
- return OK;
+ switch (minor) {
+ case KBD_MINOR: return &kbd;
+ case KBDAUX_MINOR: return &kbdaux;
+ default: return NULL;
+ }
}
/*===========================================================================*
- * do_kbd *
+ * kbd_open *
*===========================================================================*/
-void do_kbd(message *m)
+static int
+kbd_open(devminor_t minor, int UNUSED(access), endpoint_t UNUSED(user_endpt))
{
- handle_req(&kbd, m);
-}
+ struct kbd *kbdp;
+
+ if ((kbdp = line2kbd(minor)) == NULL)
+ return ENXIO;
+ kbdp->nr_open++;
+ return OK;
+}
/*===========================================================================*
- * do_kbdaux *
+ * kbd_close *
*===========================================================================*/
-void do_kbdaux(message *m)
+static int
+kbd_close(devminor_t minor)
{
- handle_req(&kbdaux, m);
+ struct kbd *kbdp;
+
+ if ((kbdp = line2kbd(minor)) == NULL)
+ return ENXIO;
+
+ kbdp->nr_open--;
+ if (kbdp->nr_open < 0) {
+ printf("TTY(kbd): open count is negative\n");
+ kbdp->nr_open= 0;
+ }
+ if (kbdp->nr_open == 0)
+ kbdp->avail= 0;
+
+ return OK;
}
+/*===========================================================================*
+ * kbd_read *
+ *===========================================================================*/
+static ssize_t
+kbd_read(devminor_t minor, u64_t UNUSED(position), endpoint_t endpt,
+ cp_grant_id_t grant, size_t size, int flags, cdev_id_t id)
+{
+ ssize_t n, r;
+ struct kbd *kbdp;
+
+ if ((kbdp = line2kbd(minor)) == NULL)
+ return ENXIO;
+
+ /* We handle only one request at a time. */
+ if (kbdp->req_size)
+ return EIO;
+
+ if ((ssize_t) size <= 0)
+ return EINVAL;
+
+ /* If no data is available, suspend the caller. */
+ if (kbdp->avail == 0) {
+ if (flags & FLG_OP_NONBLOCK)
+ return EAGAIN;
+ kbdp->req_size = size;
+ kbdp->req_id = id;
+ kbdp->req_grant = grant;
+ kbdp->req_caller = endpt;
+ return EDONTREPLY;
+ }
+
+ /* Handle read request. */
+ n = kbdp->avail;
+ if (n > (ssize_t) size)
+ n = size;
+ if (kbdp->offset + n > KBD_BUFSZ)
+ n = KBD_BUFSZ - kbdp->offset;
+ if (n <= 0)
+ panic("do_kbd(READ): bad n: %d", n);
+ r = sys_safecopyto(endpt, grant, 0,
+ (vir_bytes) &kbdp->buf[kbdp->offset], n);
+ if (r == OK) {
+ kbdp->offset = (kbdp->offset + n) % KBD_BUFSZ;
+ kbdp->avail -= n;
+ r = n;
+ } else
+ printf("TTY(kbd): copy in read kbd failed: %d\n", r);
+
+ return r;
+}
/*===========================================================================*
- * handle_req *
+ * kbd_write *
*===========================================================================*/
-static void handle_req(kbdp, m)
-struct kbd *kbdp;
-message *m;
+static ssize_t
+kbd_write(devminor_t minor, u64_t UNUSED(position), endpoint_t endpt,
+ cp_grant_id_t grant, size_t size, int flags, cdev_id_t id)
{
- int i, n, r, ops, watch;
+ struct kbd *kbdp;
unsigned char c;
+ size_t i;
+ int r;
- /* Execute the requested device driver function. */
- r= EINVAL; /* just in case */
- switch (m->m_type) {
- case DEV_OPEN:
- kbdp->nr_open++;
- tty_reply(DEV_OPEN_REPL, m->m_source, m->USER_ENDPT,
- (cp_grant_id_t) m->IO_GRANT, OK);
- return;
- case DEV_CLOSE:
- kbdp->nr_open--;
- if (kbdp->nr_open < 0)
- {
- printf("TTY(kbd): open count is negative\n");
- kbdp->nr_open= 0;
- }
- if (kbdp->nr_open == 0)
- kbdp->avail= 0;
- tty_reply(DEV_CLOSE_REPL, m->m_source, m->USER_ENDPT,
- (cp_grant_id_t) m->IO_GRANT, OK);
- return;
- case DEV_READ_S:
- if (kbdp->req_size)
- {
- /* We handle only request at a time */
- r= EIO;
- break;
- }
- if (kbdp->avail == 0)
- {
- if (m->FLAGS & FLG_OP_NONBLOCK) {
- r = EAGAIN;
- break;
- }
- /* Should record proc */
- kbdp->req_size= m->COUNT;
- kbdp->req_proc= m->USER_ENDPT;
- kbdp->req_grant= (cp_grant_id_t) m->IO_GRANT;
- kbdp->req_addr_offset= 0;
- kbdp->incaller= m->m_source;
- return;
- }
+ if ((kbdp = line2kbd(minor)) == NULL)
+ return ENXIO;
+ if (kbdp != &kbdaux) {
+ printf("TTY(kbd): write to keyboard not implemented\n");
+ return EINVAL;
+ }
- /* Handle read request */
- n= kbdp->avail;
- if (n > m->COUNT)
- n= m->COUNT;
- if (kbdp->offset + n > KBD_BUFSZ)
- n= KBD_BUFSZ-kbdp->offset;
- if (n <= 0)
- panic("do_kbd(READ): bad n: %d", n);
- r= sys_safecopyto(m->m_source, (cp_grant_id_t) m->IO_GRANT, 0,
- (vir_bytes) &kbdp->buf[kbdp->offset], n);
- if (r == OK)
- {
- kbdp->offset= (kbdp->offset+n) % KBD_BUFSZ;
- kbdp->avail -= n;
- r= n;
+ /*
+ * Assume that output to AUX only happens during initialization and we
+ * can afford to lose input. This should be fixed at a later time.
+ */
+ for (i = 0; i < size; i++) {
+ r = sys_safecopyfrom(endpt, grant, i, (vir_bytes) &c, 1);
+ if (r != OK)
+ return i ? i : r;
+ kbc_cmd1(KBC_WRITE_AUX, c);
+ }
+
+ return r;
+}
+
+/*===========================================================================*
+ * kbd_ioctl *
+ *===========================================================================*/
+static int
+kbd_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt,
+ cp_grant_id_t grant, int flags, endpoint_t UNUSED(user_endpt),
+ cdev_id_t id)
+{
+ struct kbd *kbdp;
+ kio_leds_t leds;
+ kio_bell_t bell;
+ clock_t ticks;
+ unsigned char b;
+ int r;
+
+ if ((kbdp = line2kbd(minor)) == NULL)
+ return ENXIO;
+ if (kbdp != &kbd)
+ return ENOTTY; /* we only support ioctls on keyboards now */
+
+ switch (request) {
+ case KIOCSLEDS:
+ r = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &leds,
+ sizeof(leds));
+ if (r != OK)
+ return r;
+
+ b = 0;
+ if (leds.kl_bits & KBD_LEDS_NUM) b |= NUM_LOCK;
+ if (leds.kl_bits & KBD_LEDS_CAPS) b |= CAPS_LOCK;
+ if (leds.kl_bits & KBD_LEDS_SCROLL) b |= SCROLL_LOCK;
+ if (kbdout.avail == 0)
+ kbdout.offset = 0;
+ if (kbdout.offset + kbdout.avail + 2 > KBD_OUT_BUFSZ) {
+ /* Output buffer is full. Ignore this command.
+ * Reset ACK flag.
+ */
+ kbdout.expect_ack = 0;
} else {
- printf("copy in read kbd failed: %d\n", r);
+ kbdout.buf[kbdout.offset+kbdout.avail] = LED_CODE;
+ kbdout.buf[kbdout.offset+kbdout.avail+1] = b;
+ kbdout.avail += 2;
}
+ if (!kbdout.expect_ack)
+ kbd_send();
- break;
+ return OK;
- case DEV_WRITE_S:
- if (kbdp != &kbdaux)
- {
- printf("write to keyboard not implemented\n");
- r= EINVAL;
- break;
- }
+ case KIOCBELL:
+ r = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &bell,
+ sizeof(bell));
+ if (r != OK)
+ return r;
- /* Assume that output to AUX only happens during
- * initialization and we can afford to lose input. This should
- * be fixed at a later time.
- */
- for (i= 0; i<m->COUNT; i++)
- {
- r= sys_safecopyfrom(m->m_source, (cp_grant_id_t)
- m->IO_GRANT, i, (vir_bytes) &c, 1);
- if (r != OK)
- break;
- kbc_cmd1(KBC_WRITE_AUX, c);
- }
- r= i;
- break;
+ ticks = bell.kb_duration.tv_usec * system_hz / 1000000;
+ ticks += bell.kb_duration.tv_sec * system_hz;
+ if (!ticks)
+ ticks++;
+ beep_x(bell.kb_pitch, ticks);
- case CANCEL:
- kbdp->req_size= 0;
- r= EAGAIN;
- break;
- case DEV_SELECT:
- ops = m->DEV_SEL_OPS & (SEL_RD|SEL_WR|SEL_ERR);
- watch = (m->DEV_SEL_OPS & SEL_NOTIFY) ? 1 : 0;
-
- r= 0;
- if (kbdp->avail && (ops & SEL_RD))
- {
- r |= SEL_RD;
- break;
- }
+ return OK;
- if (ops && watch)
- {
- kbdp->select_ops |= ops;
- kbdp->select_proc= m->m_source;
- kbdp->select_minor= m->DEV_MINOR;
- }
- assert(kbdp->minor == m->DEV_MINOR);
- select_reply(DEV_SEL_REPL1, m->m_source, m->DEV_MINOR, r);
- return;
- case DEV_IOCTL_S:
- if (kbdp == &kbd && m->REQUEST == KIOCSLEDS)
- {
- kio_leds_t leds;
- unsigned char b;
-
-
- r= sys_safecopyfrom(m->m_source, (cp_grant_id_t)
- m->IO_GRANT, 0, (vir_bytes) &leds,
- sizeof(leds));
- if (r != OK)
- break;
- b= 0;
- if (leds.kl_bits & KBD_LEDS_NUM) b |= NUM_LOCK;
- if (leds.kl_bits & KBD_LEDS_CAPS) b |= CAPS_LOCK;
- if (leds.kl_bits & KBD_LEDS_SCROLL) b |= SCROLL_LOCK;
- if (kbdout.avail == 0)
- kbdout.offset= 0;
- if (kbdout.offset + kbdout.avail + 2 > KBD_OUT_BUFSZ)
- {
- /* Output buffer is full. Ignore this command.
- * Reset ACK flag.
- */
- kbdout.expect_ack= 0;
- }
- else
- {
- kbdout.buf[kbdout.offset+kbdout.avail]=
- LED_CODE;
- kbdout.buf[kbdout.offset+kbdout.avail+1]= b;
- kbdout.avail += 2;
- }
- if (!kbdout.expect_ack)
- kbd_send();
- r= OK;
- break;
- }
- if (kbdp == &kbd && m->REQUEST == KIOCBELL)
- {
- kio_bell_t bell;
- clock_t ticks;
-
- r = sys_safecopyfrom(m->m_source, (cp_grant_id_t)
- m->IO_GRANT, 0, (vir_bytes) &bell,
- sizeof(bell));
- if (r != OK)
- break;
-
- ticks= bell.kb_duration.tv_usec * system_hz / 1000000;
- ticks += bell.kb_duration.tv_sec * system_hz;
- if (!ticks)
- ticks++;
- beep_x(bell.kb_pitch, ticks);
-
- r= OK;
- break;
- }
- r= ENOTTY;
- break;
+ default:
+ return ENOTTY;
+ }
+}
+
+/*===========================================================================*
+ * kbd_cancel *
+ *===========================================================================*/
+static int
+kbd_cancel(devminor_t minor, endpoint_t endpt, cdev_id_t id)
+{
+ struct kbd *kbdp;
+
+ if ((kbdp = line2kbd(minor)) == NULL)
+ return ENXIO;
+
+ if (kbdp->req_size > 0 && endpt == kbdp->req_caller &&
+ id == kbdp->req_id)
+ return EINTR;
+
+ return EDONTREPLY;
+}
+
+/*===========================================================================*
+ * kbd_select *
+ *===========================================================================*/
+static int
+kbd_select(devminor_t minor, unsigned int ops, endpoint_t endpt)
+{
+ struct kbd *kbdp;
+ int watch, ready_ops;
+
+ if ((kbdp = line2kbd(minor)) == NULL)
+ return ENXIO;
+
+ watch = (ops & SEL_NOTIFY);
+ ops &= (SEL_RD | SEL_WR | SEL_ERR);
+
+ ready_ops = 0;
+ if (kbdp->avail && (ops & SEL_RD))
+ ready_ops |= SEL_RD;
+ if (ops & SEL_WR)
+ ready_ops |= SEL_WR; /* writes never block */
- default:
- printf("Warning, TTY(kbd) got unexpected request %d from %d\n",
- m->m_type, m->m_source);
- r= EINVAL;
+ ops &= ~ready_ops;
+ if (ops && watch) {
+ kbdp->select_ops |= ops;
+ kbdp->select_proc = endpt;
}
- tty_reply(DEV_REVIVE, m->m_source, m->USER_ENDPT,
- (cp_grant_id_t) m->IO_GRANT, r);
+
+ return ready_ops;
}
+/*===========================================================================*
+ * do_kbd *
+ *===========================================================================*/
+void
+do_kbd(message *m, int ipc_status)
+{
+ chardriver_process(&kbd_tab, m, ipc_status);
+}
/*===========================================================================*
* map_key *
if (n <= 0)
panic("kbd_interrupt: bad n: %d", n);
kbdp->req_size= 0;
- r= sys_safecopyto(kbdp->incaller, kbdp->req_grant, 0,
+ r= sys_safecopyto(kbdp->req_caller, kbdp->req_grant, 0,
(vir_bytes)&kbdp->buf[kbdp->offset], n);
if (r == OK)
{
r= n;
} else printf("copy in revive kbd failed: %d\n", r);
- tty_reply(DEV_REVIVE, kbdp->incaller, kbdp->req_proc,
- kbdp->req_grant, r);
- kbdp->req_grant = GRANT_INVALID;
+ chardriver_reply_task(kbdp->req_caller, kbdp->req_id, r);
+ kbdp->req_caller = NONE;
}
/* Only satisfy pending select if characters weren't just read. */
if (kbdp->avail && (kbdp->select_ops & SEL_RD)) {
- assert(kbdp->select_minor == kbdp->minor);
- select_reply(DEV_SEL_REPL2, kbdp->select_proc, kbdp->minor,
+ chardriver_reply_select(kbdp->select_proc, kbdp->minor,
SEL_RD);
kbdp->select_ops &= ~SEL_RD;
}
/*===========================================================================*
* kbd_loadmap *
*===========================================================================*/
-int kbd_loadmap(m)
-message *m;
+int kbd_loadmap(endpoint_t endpt, cp_grant_id_t grant)
{
/* Load a new keymap. */
- return sys_safecopyfrom(m->m_source, (cp_grant_id_t) m->IO_GRANT,
- 0, (vir_bytes) keymap, (vir_bytes) sizeof(keymap));
+ return sys_safecopyfrom(endpt, grant, 0, (vir_bytes) keymap, sizeof(keymap));
}
/*===========================================================================*
/* Copy from user space to the RS232 output buffer. */
if (tp->tty_outcaller == KERNEL) {
/* We're trying to print on kernel's behalf */
- memcpy(rs->ohead, (void *) tp->tty_outgrant + tp->tty_outoffset, count);
+ memcpy(rs->ohead, (char *) tp->tty_outgrant + tp->tty_outcum,
+ count);
} else {
if ((r = sys_safecopyfrom(tp->tty_outcaller, tp->tty_outgrant,
- tp->tty_outoffset, (vir_bytes) rs->ohead, count)) != OK)
+ tp->tty_outcum, (vir_bytes) rs->ohead, count)) != OK)
printf("TTY: sys_safecopyfrom() failed: %d", r);
}
rs_ostart(rs);
if ((rs->ohead += ocount) >= bufend(rs->obuf))
rs->ohead -= buflen(rs->obuf);
- tp->tty_outoffset += count;
tp->tty_outcum += count;
if ((tp->tty_outleft -= count) == 0) {
/* Output is finished, reply to the writer. */
- tty_reply(DEV_REVIVE, tp->tty_outcaller, tp->tty_outproc,
- tp->tty_outgrant, tp->tty_outcum);
+ chardriver_reply_task(tp->tty_outcaller, tp->tty_outid,
+ tp->tty_outcum);
tp->tty_outcum = 0;
- tp->tty_outgrant = GRANT_INVALID;
+ tp->tty_outcaller = NONE;
}
}
if (tp->tty_outleft > 0 && tp->tty_termios.c_ospeed == B0) {
/* Oops, the line has hung up. */
- tty_reply(DEV_REVIVE, tp->tty_outcaller, tp->tty_outproc,
- tp->tty_outgrant, EIO);
+ chardriver_reply_task(tp->tty_outcaller, tp->tty_outid, EIO);
tp->tty_outleft = tp->tty_outcum = 0;
- tp->tty_outgrant = GRANT_INVALID;
+ tp->tty_outcaller = NONE;
}
return 1;
* This file takes care of copying data between the tty/pty device pairs and
* the open/read/write/close calls on the pty devices. The TTY task takes
* care of the input and output processing (interrupt, backspace, raw I/O,
- * etc.) using the pty_read() and pty_write() functions as the "keyboard" and
- * "screen" functions of the ttypX devices.
+ * etc.) using the pty_slave_read() and pty_slave_write() functions as the
+ * "keyboard" and "screen" functions of the ttypX devices.
* Be careful when reading this code, the terms "reading" and "writing" are
- * used both for the tty and the pty end of the pseudo tty. Writes to one
- * end are to be read at the other end and vice-versa.
+ * used both for the tty (slave) and the pty (master) end of the pseudo tty.
+ * Writes to one end are to be read at the other end and vice-versa.
*/
#include <minix/drivers.h>
-#include <assert.h>
#include <termios.h>
#include <signal.h>
-#include <minix/com.h>
-#include <minix/callnr.h>
-#include <sys/select.h>
#include "tty.h"
#if NR_PTYS > 0
tty_t *tty; /* associated TTY structure */
char state; /* flags: busy, closed, ... */
- /* Read call on /dev/ptypX. */
- int rdcaller; /* process making the call (usually FS) */
- int rdproc; /* process that wants to read from the pty */
- cp_grant_id_t rdgrant; /* grant for readers address space */
- vir_bytes rdoffset; /* offset in above grant */
- int rdleft; /* # bytes yet to be read */
- int rdcum; /* # bytes written so far */
-
- /* Write call to /dev/ptypX. */
- int wrcaller; /* process making the call (usually FS) */
- int wrproc; /* process that wants to write to the pty */
- cp_grant_id_t wrgrant; /* grant for writers address space */
- vir_bytes wroffset; /* offset in above grant */
- int wrleft; /* # bytes yet to be written */
- int wrcum; /* # bytes written so far */
+ /* Read call on master (/dev/ptypX). */
+ endpoint_t rdcaller; /* process making the call, or NONE if none */
+ cdev_id_t rdid; /* ID of suspended read request */
+ cp_grant_id_t rdgrant; /* grant for reader's address space */
+ size_t rdleft; /* # bytes yet to be read */
+ size_t rdcum; /* # bytes written so far */
+
+ /* Write call to master (/dev/ptypX). */
+ endpoint_t wrcaller; /* process making the call, or NONE if none*/
+ cdev_id_t wrid; /* ID of suspended write request */
+ cp_grant_id_t wrgrant; /* grant for writer's address space */
+ size_t wrleft; /* # bytes yet to be written */
+ size_t wrcum; /* # bytes written so far */
/* Output buffer. */
int ocount; /* # characters in the buffer */
char obuf[2048]; /* buffer for bytes going to the pty reader */
/* select() data. */
- int select_ops; /* Which operations do we want to know about? */
- int select_proc; /* Who wants to know about it? */
- dev_t select_minor; /* sanity check only, can be removed */
+ unsigned int select_ops; /* Which operations do we want to know about? */
+ endpoint_t select_proc; /* Who wants to know about it? */
} pty_t;
#define TTY_ACTIVE 0x01 /* tty is open/active */
static pty_t pty_table[NR_PTYS]; /* PTY bookkeeping */
-static int pty_write(tty_t *tp, int try);
-static void pty_echo(tty_t *tp, int c);
static void pty_start(pty_t *pp);
static void pty_finish(pty_t *pp);
-static int pty_read(tty_t *tp, int try);
-static int pty_close(tty_t *tp, int try);
-static int pty_icancel(tty_t *tp, int try);
-static int pty_ocancel(tty_t *tp, int try);
-static void pty_select(tty_t *tp, message *m);
+
+static int pty_master_open(devminor_t minor, int access,
+ endpoint_t user_endpt);
+static int pty_master_close(devminor_t minor);
+static ssize_t pty_master_read(devminor_t minor, u64_t position,
+ endpoint_t endpt, cp_grant_id_t grant, size_t size, int flags,
+ cdev_id_t id);
+static ssize_t pty_master_write(devminor_t minor, u64_t position,
+ endpoint_t endpt, cp_grant_id_t grant, size_t size, int flags,
+ cdev_id_t id);
+static int pty_master_cancel(devminor_t minor, endpoint_t endpt, cdev_id_t id);
+static int pty_master_select(devminor_t minor, unsigned int ops,
+ endpoint_t endpt);
+
+static struct chardriver pty_master_tab = {
+ .cdr_open = pty_master_open,
+ .cdr_close = pty_master_close,
+ .cdr_read = pty_master_read,
+ .cdr_write = pty_master_write,
+ .cdr_cancel = pty_master_cancel,
+ .cdr_select = pty_master_select
+};
/*===========================================================================*
- * do_pty *
+ * pty_master_open *
*===========================================================================*/
-void do_pty(tty_t *tp, message *m_ptr)
+static int pty_master_open(devminor_t minor, int UNUSED(access),
+ endpoint_t UNUSED(user_endpt))
{
-/* Perform an open/close/read/write call on a /dev/ptypX device. */
- pty_t *pp = tp->tty_priv;
+ tty_t *tp;
+ pty_t *pp;
+
+ if ((tp = line2tty(minor)) == NULL)
+ return ENXIO;
+ pp = tp->tty_priv;
+
+ if (pp->state & PTY_ACTIVE)
+ return EIO;
+
+ pp->state |= PTY_ACTIVE;
+ pp->rdcum = 0;
+ pp->wrcum = 0;
+
+ return OK;
+}
+
+/*===========================================================================*
+ * pty_master_close *
+ *===========================================================================*/
+static int pty_master_close(devminor_t minor)
+{
+ tty_t *tp;
+ pty_t *pp;
+
+ if ((tp = line2tty(minor)) == NULL)
+ return ENXIO;
+ pp = tp->tty_priv;
+
+ if ((pp->state & (TTY_ACTIVE | TTY_CLOSED)) != TTY_ACTIVE) {
+ pp->state = 0;
+ } else {
+ pp->state |= PTY_CLOSED;
+ sigchar(tp, SIGHUP, 1);
+ }
+
+ return OK;
+}
+
+/*===========================================================================*
+ * pty_master_read *
+ *===========================================================================*/
+static ssize_t pty_master_read(devminor_t minor, u64_t UNUSED(position),
+ endpoint_t endpt, cp_grant_id_t grant, size_t size, int flags,
+ cdev_id_t id)
+{
+ tty_t *tp;
+ pty_t *pp;
+ ssize_t r;
+
+ if ((tp = line2tty(minor)) == NULL)
+ return ENXIO;
+ pp = tp->tty_priv;
+
+ /* Check, store information on the reader, do I/O. */
+ if (pp->state & TTY_CLOSED)
+ return 0; /* EOF */
+
+ if (pp->rdcaller != NONE || pp->rdleft != 0 || pp->rdcum != 0)
+ return EIO;
+
+ if (size <= 0)
+ return EINVAL;
+
+ pp->rdcaller = endpt;
+ pp->rdid = id;
+ pp->rdgrant = grant;
+ pp->rdleft = size;
+ pty_start(pp);
+
+ handle_events(tp);
+
+ if (pp->rdleft == 0) {
+ pp->rdcaller = NONE;
+ return EDONTREPLY; /* already done */
+ }
+
+ if (flags & FLG_OP_NONBLOCK) {
+ r = pp->rdcum > 0 ? pp->rdcum : EAGAIN;
+ pp->rdleft = pp->rdcum = 0;
+ pp->rdcaller = NONE;
+ return r;
+ }
+
+ return EDONTREPLY; /* do suspend */
+}
+
+/*===========================================================================*
+ * pty_master_write *
+ *===========================================================================*/
+static ssize_t pty_master_write(devminor_t minor, u64_t UNUSED(position),
+ endpoint_t endpt, cp_grant_id_t grant, size_t size, int flags,
+ cdev_id_t id)
+{
+ tty_t *tp;
+ pty_t *pp;
+ ssize_t r;
+
+ if ((tp = line2tty(minor)) == NULL)
+ return ENXIO;
+ pp = tp->tty_priv;
+
+ /* Check, store information on the writer, do I/O. */
+ if (pp->state & TTY_CLOSED)
+ return EIO;
+
+ if (pp->wrcaller != NONE || pp->wrleft != 0 || pp->wrcum != 0)
+ return EIO;
+
+ if (size <= 0)
+ return EINVAL;
+
+ pp->wrcaller = endpt;
+ pp->wrid = id;
+ pp->wrgrant = grant;
+ pp->wrleft = size;
+
+ handle_events(tp);
+
+ if (pp->wrleft == 0) {
+ pp->wrcaller = NONE;
+ return EDONTREPLY; /* already done */
+ }
+
+ if (flags & FLG_OP_NONBLOCK) {
+ r = pp->wrcum > 0 ? pp->wrcum : EAGAIN;
+ pp->wrleft = pp->wrcum = 0;
+ pp->wrcaller = NONE;
+ return r;
+ }
+
+ return EDONTREPLY; /* do suspend */
+}
+
+/*===========================================================================*
+ * pty_master_cancel *
+ *===========================================================================*/
+static int pty_master_cancel(devminor_t minor, endpoint_t endpt, cdev_id_t id)
+{
+ tty_t *tp;
+ pty_t *pp;
int r;
- switch (m_ptr->m_type) {
- case DEV_READ_S:
- /* Check, store information on the reader, do I/O. */
- if (pp->state & TTY_CLOSED) {
- r = 0;
- break;
- }
- if (pp->rdleft != 0 || pp->rdcum != 0) {
- r = EIO;
- break;
- }
- if (m_ptr->COUNT <= 0) {
- r = EINVAL;
- break;
- }
- if (pp->rdgrant != GRANT_INVALID) {
- r = ENOBUFS;
- break;
- }
- pp->rdcaller = m_ptr->m_source;
- pp->rdproc = m_ptr->USER_ENDPT;
- pp->rdgrant = (cp_grant_id_t) m_ptr->IO_GRANT;
- pp->rdoffset = 0;
- pp->rdleft = m_ptr->COUNT;
- pty_start(pp);
- handle_events(tp);
- if (pp->rdleft == 0) {
- pp->rdgrant = GRANT_INVALID;
- return; /* already done */
- }
+ if ((tp = line2tty(minor)) == NULL)
+ return ENXIO;
+ pp = tp->tty_priv;
- if (m_ptr->FLAGS & FLG_OP_NONBLOCK) {
- r = pp->rdcum > 0 ? pp->rdcum : EAGAIN;
- pp->rdleft = pp->rdcum = 0;
- pp->rdgrant = GRANT_INVALID;
- } else {
- return; /* do suspend */
- }
- break;
+ if (pp->rdcaller == endpt && pp->rdid == id) {
+ /* Cancel a read from a PTY. */
+ r = pp->rdcum > 0 ? pp->rdcum : EINTR;
+ pp->rdleft = pp->rdcum = 0;
+ pp->rdcaller = NONE;
+ return r;
+ }
- case DEV_WRITE_S:
- /* Check, store information on the writer, do I/O. */
- if (pp->state & TTY_CLOSED) {
- r = EIO;
- break;
- }
- if (pp->wrleft != 0 || pp->wrcum != 0) {
- r = EIO;
- break;
- }
- if (m_ptr->COUNT <= 0) {
- r = EINVAL;
- break;
- }
- if (pp->wrgrant != GRANT_INVALID) {
- r = ENOBUFS;
- break;
- }
- pp->wrcaller = m_ptr->m_source;
- pp->wrproc = m_ptr->USER_ENDPT;
- pp->wrgrant = (cp_grant_id_t) m_ptr->IO_GRANT;
- pp->wroffset = 0;
- pp->wrleft = m_ptr->COUNT;
- handle_events(tp);
- if (pp->wrleft == 0) {
- pp->wrgrant = GRANT_INVALID;
- return; /* already done */
- }
+ if (pp->wrcaller == endpt && pp->wrid == id) {
+ /* Cancel a write to a PTY. */
+ r = pp->wrcum > 0 ? pp->wrcum : EINTR;
+ pp->wrleft = pp->wrcum = 0;
+ pp->wrcaller = NONE;
+ return r;
+ }
- if (m_ptr->FLAGS & FLG_OP_NONBLOCK) {
- r = pp->wrcum > 0 ? pp->wrcum : EAGAIN;
- pp->wrleft = pp->wrcum = 0;
- pp->wrgrant = GRANT_INVALID;
- r = EAGAIN;
- } else {
- return; /* do suspend */
- }
- break;
+ /* Request not found. */
+ return EDONTREPLY;
+}
- case DEV_OPEN:
- if (!(pp->state & PTY_ACTIVE)) {
- pp->state |= PTY_ACTIVE;
- pp->rdcum = 0;
- pp->wrcum = 0;
- r = OK;
- } else {
- r = EIO;
- }
- tty_reply(DEV_OPEN_REPL, m_ptr->m_source, m_ptr->USER_ENDPT,
- (cp_grant_id_t) m_ptr->IO_GRANT, r);
- return;
+/*===========================================================================*
+ * select_try_pty *
+ *===========================================================================*/
+static int select_try_pty(tty_t *tp, int ops)
+{
+ pty_t *pp = tp->tty_priv;
+ int r = 0;
- case DEV_CLOSE:
- if ((pp->state & (TTY_ACTIVE | TTY_CLOSED)) != TTY_ACTIVE) {
- pp->state = 0;
- } else {
- pp->state |= PTY_CLOSED;
- sigchar(tp, SIGHUP, 1);
- }
- tty_reply(DEV_CLOSE_REPL, m_ptr->m_source, m_ptr->USER_ENDPT,
- (cp_grant_id_t) m_ptr->IO_GRANT, OK);
- return;
-
- case DEV_SELECT:
- pty_select(tp, m_ptr);
- return;
-
- case CANCEL:
- r = EINTR;
- if (m_ptr->USER_ENDPT == pp->rdproc) {
- /* Cancel a read from a PTY. */
- r = pp->rdcum > 0 ? pp->rdcum : EAGAIN;
- pp->rdleft = pp->rdcum = 0;
- pp->rdgrant = GRANT_INVALID;
- }
- if (m_ptr->USER_ENDPT == pp->wrproc) {
- /* Cancel a write to a PTY. */
- r = pp->wrcum > 0 ? pp->wrcum : EAGAIN;
- pp->wrleft = pp->wrcum = 0;
- pp->wrgrant = GRANT_INVALID;
- }
- break;
+ if (ops & SEL_WR) {
+ /* Write won't block on error. */
+ if (pp->state & TTY_CLOSED) r |= SEL_WR;
+ else if (pp->wrleft != 0 || pp->wrcum != 0) r |= SEL_WR;
+ else if (tp->tty_inleft > 0) r |= SEL_WR; /* There's a reader. */
+ }
- default:
- r = EINVAL;
+ if (ops & SEL_RD) {
+ /* Read won't block on error. */
+ if (pp->state & TTY_CLOSED) r |= SEL_RD;
+ else if (pp->rdleft != 0 || pp->rdcum != 0) r |= SEL_RD;
+ else if (pp->ocount > 0) r |= SEL_RD; /* Actual data. */
}
- tty_reply(DEV_REVIVE, m_ptr->m_source, m_ptr->USER_ENDPT,
- (cp_grant_id_t) m_ptr->IO_GRANT, r);
+
+ return r;
}
/*===========================================================================*
- * pty_write *
+ * select_retry_pty *
*===========================================================================*/
-static int pty_write(tty_t *tp, int try)
+void select_retry_pty(tty_t *tp)
+{
+ pty_t *pp = tp->tty_priv;
+ devminor_t minor;
+ int r;
+
+ /* See if the pty side of a pty is ready to return a select. */
+ if (pp->select_ops && (r = select_try_pty(tp, pp->select_ops))) {
+ minor = PTYPX_MINOR + (int) (pp - pty_table);
+ chardriver_reply_select(pp->select_proc, minor, r);
+ pp->select_ops &= ~r;
+ }
+}
+
+/*===========================================================================*
+ * pty_master_select *
+ *===========================================================================*/
+static int pty_master_select(devminor_t minor, unsigned int ops,
+ endpoint_t endpt)
+{
+ tty_t *tp;
+ pty_t *pp;
+ int ready_ops, watch;
+
+ if ((tp = line2tty(minor)) == NULL)
+ return ENXIO;
+ pp = tp->tty_priv;
+
+ watch = (ops & SEL_NOTIFY);
+ ops &= (SEL_RD | SEL_WR | SEL_ERR);
+
+ ready_ops = select_try_pty(tp, ops);
+
+ ops &= ~ready_ops;
+ if (ops && watch) {
+ pp->select_ops |= ops;
+ pp->select_proc = endpt;
+ }
+
+ return ready_ops;
+}
+
+/*===========================================================================*
+ * do_pty *
+ *===========================================================================*/
+void do_pty(message *m_ptr, int ipc_status)
+{
+/* Process a request for a PTY master (/dev/ptypX) device. */
+
+ chardriver_process(&pty_master_tab, m_ptr, ipc_status);
+}
+
+/*===========================================================================*
+ * pty_slave_write *
+ *===========================================================================*/
+static int pty_slave_write(tty_t *tp, int try)
{
/* (*dev_write)() routine for PTYs. Transfer bytes from the writer on
* /dev/ttypX to the output buffer.
pty_t *pp = tp->tty_priv;
int count, ocount, s;
-
/* PTY closed down? */
if (pp->state & PTY_CLOSED) {
if (try) return 1;
if (tp->tty_outleft > 0) {
- tty_reply(DEV_REVIVE, tp->tty_outcaller, tp->tty_outproc,
- tp->tty_outgrant, EIO);
+ chardriver_reply_task(tp->tty_outcaller, tp->tty_outid, EIO);
tp->tty_outleft = tp->tty_outcum = 0;
- tp->tty_outgrant = GRANT_INVALID;
+ tp->tty_outcaller = NONE;
}
return 0;
}
/* Copy from user space to the PTY output buffer. */
if (tp->tty_outcaller == KERNEL) {
/* We're trying to print on kernel's behalf */
- memcpy(pp->ohead, (void *) tp->tty_outgrant + tp->tty_outoffset,
+ memcpy(pp->ohead, (void *) tp->tty_outgrant + tp->tty_outcum,
count);
} else {
if ((s = sys_safecopyfrom(tp->tty_outcaller, tp->tty_outgrant,
- tp->tty_outoffset, (vir_bytes) pp->ohead,
+ tp->tty_outcum, (vir_bytes) pp->ohead,
count)) != OK) {
break;
}
pp->ohead -= buflen(pp->obuf);
pty_start(pp);
- tp->tty_outoffset += count;
-
tp->tty_outcum += count;
if ((tp->tty_outleft -= count) == 0) {
/* Output is finished, reply to the writer. */
- tty_reply(DEV_REVIVE, tp->tty_outcaller, tp->tty_outproc,
- tp->tty_outgrant, tp->tty_outcum);
+ chardriver_reply_task(tp->tty_outcaller, tp->tty_outid,
+ tp->tty_outcum);
tp->tty_outcum = 0;
- tp->tty_outgrant = GRANT_INVALID;
+ tp->tty_outcaller = NONE;
}
}
pty_finish(pp);
}
/*===========================================================================*
- * pty_echo *
+ * pty_slave_echo *
*===========================================================================*/
-static void pty_echo(tty_t *tp, int c)
+static void pty_slave_echo(tty_t *tp, int c)
{
/* Echo one character. (Like pty_write, but only one character, optionally.) */
if (count == 0) break;
/* Copy from the output buffer to the readers address space. */
- if((s = sys_safecopyto(pp->rdcaller, pp->rdgrant,
- pp->rdoffset, (vir_bytes) pp->otail, count)) != OK) {
+ if((s = sys_safecopyto(pp->rdcaller, pp->rdgrant, pp->rdcum,
+ (vir_bytes) pp->otail, count)) != OK) {
break;
}
- pp->rdoffset += count;
/* Bookkeeping. */
pp->ocount -= count;
/* Finish the read request of a PTY reader if there is at least one byte
* transferred.
*/
+
if (pp->rdcum > 0) {
- tty_reply(DEV_REVIVE, pp->rdcaller, pp->rdproc, pp->rdgrant,
- pp->rdcum);
+ chardriver_reply_task(pp->rdcaller, pp->rdid, pp->rdcum);
pp->rdleft = pp->rdcum = 0;
- pp->rdgrant = GRANT_INVALID;
+ pp->rdcaller = NONE;
}
-
}
/*===========================================================================*
- * pty_read *
+ * pty_slave_read *
*===========================================================================*/
-static int pty_read(tty_t *tp, int try)
+static int pty_slave_read(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.)
if (pp->state & PTY_CLOSED) {
if (try) return 1;
if (tp->tty_inleft > 0) {
- tty_reply(DEV_REVIVE, tp->tty_incaller, tp->tty_inproc,
- tp->tty_ingrant, tp->tty_incum);
+ chardriver_reply_task(tp->tty_incaller, tp->tty_inid,
+ tp->tty_incum);
tp->tty_inleft = tp->tty_incum = 0;
- tp->tty_ingrant = GRANT_INVALID;
+ tp->tty_incaller = NONE;
}
return 1;
}
int s;
/* Transfer one character to 'c'. */
- if ((s = sys_safecopyfrom(pp->wrcaller, pp->wrgrant, pp->wroffset,
+ if ((s = sys_safecopyfrom(pp->wrcaller, pp->wrgrant, pp->wrcum,
(vir_bytes) &c, 1)) != OK) {
printf("pty: safecopy failed (error %d)\n", s);
break;
}
- pp->wroffset++;
/* Input processing. */
if (in_process(tp, &c, 1, -1) == 0) break;
/* PTY writer bookkeeping. */
pp->wrcum++;
if (--pp->wrleft == 0) {
- tty_reply(DEV_REVIVE, pp->wrcaller, pp->wrproc, pp->wrgrant,
- pp->wrcum);
+ chardriver_reply_task(pp->wrcaller, pp->wrid, pp->wrcum);
pp->wrcum = 0;
- pp->wrgrant = GRANT_INVALID;
+ pp->wrcaller = NONE;
}
}
}
/*===========================================================================*
- * pty_open *
+ * pty_slave_open *
*===========================================================================*/
-static int pty_open(tty_t *tp, int UNUSED(try))
+static int pty_slave_open(tty_t *tp, int UNUSED(try))
{
/* The tty side has been opened. */
pty_t *pp = tp->tty_priv;
}
/*===========================================================================*
- * pty_close *
+ * pty_slave_close *
*===========================================================================*/
-static int pty_close(tty_t *tp, int UNUSED(try))
+static int pty_slave_close(tty_t *tp, int UNUSED(try))
{
/* The tty side has closed, so shut down the pty side. */
pty_t *pp = tp->tty_priv;
if (!(pp->state & PTY_ACTIVE)) return 0;
if (pp->rdleft > 0) {
- tty_reply(DEV_REVIVE, pp->rdcaller, pp->rdproc, pp->rdgrant,
- pp->rdcum);
+ chardriver_reply_task(pp->rdcaller, pp->rdid, pp->rdcum);
pp->rdleft = pp->rdcum = 0;
- pp->rdgrant = GRANT_INVALID;
+ pp->rdcaller = NONE;
}
if (pp->wrleft > 0) {
- tty_reply(DEV_REVIVE, pp->wrcaller, pp->wrproc, pp->wrgrant,
- pp->wrcum);
- pp->wrcum = 0;
- pp->wrgrant = GRANT_INVALID;
+ chardriver_reply_task(pp->wrcaller, pp->wrid, pp->wrcum);
+ pp->wrleft = pp->wrcum = 0;
+ pp->wrcaller = NONE;
}
if (pp->state & PTY_CLOSED) pp->state = 0;
}
/*===========================================================================*
- * pty_icancel *
+ * pty_slave_icancel *
*===========================================================================*/
-static int pty_icancel(tty_t *tp, int UNUSED(try))
+static int pty_slave_icancel(tty_t *tp, int UNUSED(try))
{
/* Discard waiting input. */
pty_t *pp = tp->tty_priv;
if (pp->wrleft > 0) {
- tty_reply(DEV_REVIVE, pp->wrcaller, pp->wrproc, pp->wrgrant,
- pp->wrcum + pp->wrleft);
+ chardriver_reply_task(pp->wrcaller, pp->wrid, pp->wrcum + pp->wrleft);
pp->wrcum = pp->wrleft = 0;
- pp->wrgrant = GRANT_INVALID;
+ pp->wrcaller = NONE;
}
return 0;
}
/*===========================================================================*
- * pty_ocancel *
+ * pty_slave_ocancel *
*===========================================================================*/
-static int pty_ocancel(tty_t *tp, int UNUSED(try))
+static int pty_slave_ocancel(tty_t *tp, int UNUSED(try))
{
/* Drain the output buffer. */
pty_t *pp = tp->tty_priv;
pp = tp->tty_priv = &pty_table[line];
pp->tty = tp;
pp->select_ops = 0;
- pp->rdgrant = GRANT_INVALID;
- pp->wrgrant = GRANT_INVALID;
+ pp->rdcaller = NONE;
+ pp->wrcaller = NONE;
/* Set up output queue. */
pp->ohead = pp->otail = pp->obuf;
/* Fill in TTY function hooks. */
- tp->tty_devread = pty_read;
- tp->tty_devwrite = pty_write;
- tp->tty_echo = pty_echo;
- tp->tty_icancel = pty_icancel;
- tp->tty_ocancel = pty_ocancel;
- tp->tty_open = pty_open;
- tp->tty_close = pty_close;
+ tp->tty_devread = pty_slave_read;
+ tp->tty_devwrite = pty_slave_write;
+ tp->tty_echo = pty_slave_echo;
+ tp->tty_icancel = pty_slave_icancel;
+ tp->tty_ocancel = pty_slave_ocancel;
+ tp->tty_open = pty_slave_open;
+ tp->tty_close = pty_slave_close;
tp->tty_select_ops = 0;
}
-/*===========================================================================*
- * select_try_pty *
- *===========================================================================*/
-static int select_try_pty(tty_t *tp, int ops)
-{
- pty_t *pp = tp->tty_priv;
- int r = 0;
-
- if (ops & SEL_WR) {
- /* Write won't block on error. */
- if (pp->state & TTY_CLOSED) r |= SEL_WR;
- else if (pp->wrleft != 0 || pp->wrcum != 0) r |= SEL_WR;
- else r |= SEL_WR;
- }
-
- if (ops & SEL_RD) {
- /* Read won't block on error. */
- if (pp->state & TTY_CLOSED) r |= SEL_RD;
- else if (pp->rdleft != 0 || pp->rdcum != 0) r |= SEL_RD;
- else if (pp->ocount > 0) r |= SEL_RD; /* Actual data. */
- }
-
- return r;
-}
-
-/*===========================================================================*
- * select_retry_pty *
- *===========================================================================*/
-void select_retry_pty(tty_t *tp)
-{
- pty_t *pp = tp->tty_priv;
- dev_t minor;
- int r;
-
- /* See if the pty side of a pty is ready to return a select. */
- if (pp->select_ops && (r=select_try_pty(tp, pp->select_ops))) {
- minor = PTYPX_MINOR + (int) (pp - pty_table);
- assert(minor == pp->select_minor);
- select_reply(DEV_SEL_REPL2, pp->select_proc, minor, r);
- pp->select_ops &= ~r;
- }
-}
-
-/*===========================================================================*
- * pty_select *
- *===========================================================================*/
-static void pty_select(tty_t *tp, message *m)
-{
- pty_t *pp = tp->tty_priv;
- int ops, ready_ops = 0, watch;
-
- ops = m->DEV_SEL_OPS & (SEL_RD|SEL_WR|SEL_ERR);
- watch = (m->DEV_SEL_OPS & SEL_NOTIFY) ? 1 : 0;
-
- ready_ops = select_try_pty(tp, ops);
-
- if (!ready_ops && ops && watch) {
- pp->select_ops |= ops;
- pp->select_proc = m->m_source;
- pp->select_minor = m->DEV_MINOR;
- }
-
- select_reply(DEV_SEL_REPL1, m->m_source, m->DEV_MINOR, ready_ops);
-}
-
#endif /* NR_PTYS > 0 */
#include <termios.h>
#include <sys/ioc_tty.h>
#include <signal.h>
-#include <minix/callnr.h>
-#include <minix/sys_config.h>
-#include <minix/tty.h>
#include <minix/keymap.h>
-#include <minix/endpoint.h>
#include "tty.h"
#include <sys/time.h>
static void tty_timed_out(timer_t *tp);
static void settimer(tty_t *tty_ptr, int enable);
-static void do_cancel(tty_t *tp, message *m_ptr);
-static void do_ioctl(tty_t *tp, message *m_ptr);
-static void do_open(tty_t *tp, message *m_ptr);
-static void do_close(tty_t *tp, message *m_ptr);
-static void do_read(tty_t *tp, message *m_ptr);
-static void do_write(tty_t *tp, message *m_ptr);
-static void do_select(tty_t *tp, message *m_ptr);
static void in_transfer(tty_t *tp);
static int tty_echo(tty_t *tp, int ch);
static void rawecho(tty_t *tp, int ch);
static void tty_icancel(tty_t *tp);
static void tty_init(void);
static void do_new_kmess(void);
-static tty_t * line2tty(int line);
static void set_console_line(char term[CONS_ARG]);
static void set_kernel_color(char color[CONS_ARG]);
static void set_color(tty_t *tp, int color);
static void reset_color(tty_t *tp);
+static int do_open(devminor_t minor, int access, endpoint_t user_endpt);
+static int do_close(devminor_t minor);
+static ssize_t do_read(devminor_t minor, u64_t position, endpoint_t endpt,
+ cp_grant_id_t grant, size_t size, int flags, cdev_id_t id);
+static ssize_t do_write(devminor_t minor, u64_t position, endpoint_t endpt,
+ cp_grant_id_t grant, size_t size, int flags, cdev_id_t id);
+static int do_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt,
+ cp_grant_id_t grant, int flags, endpoint_t user_endpt, cdev_id_t id);
+static int do_cancel(devminor_t minor, endpoint_t endpt, cdev_id_t id);
+static int do_select(devminor_t minor, unsigned int ops, endpoint_t endpt);
+
+static struct chardriver tty_tab = {
+ .cdr_open = do_open,
+ .cdr_close = do_close,
+ .cdr_read = do_read,
+ .cdr_write = do_write,
+ .cdr_ioctl = do_ioctl,
+ .cdr_cancel = do_cancel,
+ .cdr_select = do_select
+};
+
/* Default attributes. */
static struct termios termios_defaults = {
TINPUT_DEF, TOUTPUT_DEF, TCTRL_DEF, TLOCAL_DEF,
message tty_mess; /* buffer for all incoming messages */
int ipc_status;
unsigned line;
- int r, code;
+ int r;
register tty_t *tp;
/* SEF local startup. */
switch (tty_mess.m_type) {
case TTY_FKEY_CONTROL: /* (un)register a fkey observer */
- case OLD_FKEY_CONTROL: /* old number */
do_fkey_ctl(&tty_mess);
continue;
case INPUT_EVENT:
; /* do nothing; end switch */
}
+ if (!IS_DEV_RQ(tty_mess.m_type)) {
+ chardriver_process(&tty_tab, &tty_mess, ipc_status);
+ continue;
+ }
+
/* Only device requests should get to this point.
* All requests have a minor device number.
*/
line = tty_mess.DEVICE;
- if (line == CONS_MINOR || line == LOG_MINOR) {
- /* /dev/log output goes to /dev/console */
- if (consoleline != CONS_MINOR) {
- /* Console output must redirected */
- line = consoleline;
- tty_mess.DEVICE = line;
- }
- }
- if (line == KBD_MINOR) {
- do_kbd(&tty_mess);
- continue;
- } else if (line == KBDAUX_MINOR) {
- do_kbdaux(&tty_mess);
+ if (line == KBD_MINOR || line == KBDAUX_MINOR) {
+ do_kbd(&tty_mess, ipc_status);
continue;
} else if (line == VIDEO_MINOR) {
- do_video(&tty_mess);
+ do_video(&tty_mess, ipc_status);
continue;
- } else {
- tp = line2tty(line);
-
+ } else if (line - PTYPX_MINOR < NR_PTYS &&
+ tty_mess.m_type != DEV_IOCTL_S) {
/* Terminals and pseudo terminals belong together. We can only
* make a distinction between the two based on position in the
* tty_table and not on minor number (i.e., use ispty macro).
* Hence this special case.
*/
- if (line - PTYPX_MINOR < NR_PTYS &&
- tty_mess.m_type != DEV_IOCTL_S){
- do_pty(tp, &tty_mess);
- continue;
- }
- }
-
- /* If the device doesn't exist or is not configured return ENXIO. */
- if (tp == NULL || ! tty_active(tp)) {
- if (tty_mess.m_source == LOG_PROC_NR)
- continue;
-
- /* Can all of these occur? Probably not. We're by far most
- * likely to see DEV_OPEN, but better safe than sorry..
- */
- switch (tty_mess.m_type) {
- case DEV_OPEN: code = DEV_OPEN_REPL; break;
- case DEV_CLOSE: code = DEV_CLOSE_REPL; break;
- default: code = DEV_REVIVE; break;
- }
-
- tty_reply(code, tty_mess.m_source, tty_mess.USER_ENDPT,
- (cp_grant_id_t) tty_mess.IO_GRANT, ENXIO);
+ do_pty(&tty_mess, ipc_status);
continue;
}
/* Execute the requested device driver function. */
- switch (tty_mess.m_type) {
- case DEV_READ_S: do_read(tp, &tty_mess); break;
- case DEV_WRITE_S: do_write(tp, &tty_mess); break;
- case DEV_IOCTL_S: 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);
- tty_reply(DEV_REVIVE, tty_mess.m_source, tty_mess.USER_ENDPT,
- (cp_grant_id_t) tty_mess.IO_GRANT, EINVAL);
- }
+ chardriver_process(&tty_tab, &tty_mess, ipc_status);
}
return 0;
static void
set_color(tty_t *tp, int color)
{
- message msg;
char buf[8];
buf[0] = '\033';
snprintf(&buf[1], sizeof(buf) - 1, "[1;%dm", color);
- memset(&msg, 0, sizeof(msg));
- msg.m_source = KERNEL;
- msg.IO_GRANT = buf;
- msg.COUNT = sizeof(buf);
- do_write(tp, &msg);
+ do_write(tp->tty_minor, 0, KERNEL, (cp_grant_id_t) buf, sizeof(buf),
+ FLG_OP_NONBLOCK, 0);
}
static void
reset_color(tty_t *tp)
{
- message msg;
char buf[8];
#define SGR_COLOR_RESET 39
buf[0] = '\033';
snprintf(&buf[1], sizeof(buf) - 1, "[0;%dm", SGR_COLOR_RESET);
- memset(&msg, 0, sizeof(msg));
- msg.m_source = KERNEL;
- msg.IO_GRANT = buf;
- msg.COUNT = sizeof(buf);
- do_write(tp, &msg);
+ do_write(tp->tty_minor, 0, KERNEL, (cp_grant_id_t) buf, sizeof(buf),
+ FLG_OP_NONBLOCK, 0);
}
-static tty_t *
-line2tty(int line)
+tty_t *
+line2tty(devminor_t line)
{
/* Convert a terminal line to tty_table pointer */
tty_t* tp;
+ /* /dev/log goes to /dev/console, and both may be redirected. */
+ if (line == CONS_MINOR || line == LOG_MINOR)
+ line = consoleline;
+
if (line == KBD_MINOR || line == KBDAUX_MINOR || line == VIDEO_MINOR) {
return(NULL);
} else if ((line - CONS_MINOR) < NR_CONS) {
tp = tty_addr(line - CONS_MINOR);
- } else if (line == LOG_MINOR) {
- tp = tty_addr(consoleline);
} else if ((line - RS232_MINOR) < NR_RS_LINES) {
tp = tty_addr(line - RS232_MINOR + NR_CONS);
} else if ((line - TTYPX_MINOR) < NR_PTYS) {
tp = NULL;
}
+ if (tp != NULL && !tty_active(tp))
+ tp = NULL;
+
return(tp);
}
}
/* Serial lines */
- assert(NR_RS_LINES <= 9);/* bellow assumes this is the case */
+ assert(NR_RS_LINES <= 9);/* below assumes this is the case */
for (i = 0; i < NR_RS_LINES; i++) {
char sercons[6];
strlcpy(sercons, "tty00", sizeof(sercons));
static int prev_next = 0;
int next, bytes, copy, restore = 0;
tty_t *tp, rtp;
- message print_kmsg;
assert(_minix_kerninfo);
kmess_ptr = _minix_kerninfo->kmessages;
}
tp = line2tty(consoleline);
- if (tp == NULL || !tty_active(tp))
+ if (tp == NULL)
panic("Don't know where to send kernel messages");
if (tp->tty_outleft > 0) {
/* Terminal is already printing */
if (kernel_msg_color != 0)
set_color(tp, kernel_msg_color);
- memset(&print_kmsg, 0, sizeof(print_kmsg));
- print_kmsg.m_source = KERNEL;
- print_kmsg.IO_GRANT = kernel_buf_copy;
- print_kmsg.COUNT = bytes;
- do_write(tp, &print_kmsg);
+ do_write(tp->tty_minor, 0, KERNEL,
+ (cp_grant_id_t) kernel_buf_copy, bytes,
+ FLG_OP_NONBLOCK, 0);
if (kernel_msg_color != 0)
reset_color(tp);
if (restore) {
/*===========================================================================*
* do_read *
*===========================================================================*/
-static void do_read(tp, m_ptr)
-register tty_t *tp; /* pointer to tty struct */
-register message *m_ptr; /* pointer to message sent to the task */
+static ssize_t do_read(devminor_t minor, u64_t UNUSED(position),
+ endpoint_t endpt, cp_grant_id_t grant, size_t size, int flags,
+ cdev_id_t id)
{
/* A process wants to read from a terminal. */
+ tty_t *tp;
int r;
+ if ((tp = line2tty(minor)) == NULL)
+ return ENXIO;
+
/* Check if there is already a process hanging in a read, check if the
* parameters are correct, do I/O.
*/
- if (tp->tty_inleft > 0) {
- r = EIO;
- } else
- if (m_ptr->COUNT <= 0) {
- r = EINVAL;
- } else if (tp->tty_ingrant != GRANT_INVALID) {
- /* This is actually a fundamental problem with TTY; it can handle
- * only one reader per minor device. If we don't return an error,
- * we'll overwrite the previous reader and that process will get
- * stuck forever. */
- r = ENOBUFS;
- } else {
- /* Copy information from the message to the tty struct. */
- tp->tty_incaller = m_ptr->m_source;
- tp->tty_inproc = m_ptr->USER_ENDPT;
- tp->tty_ingrant = (cp_grant_id_t) m_ptr->IO_GRANT;
- tp->tty_inoffset = 0;
- tp->tty_inleft = m_ptr->COUNT;
-
- if (!(tp->tty_termios.c_lflag & ICANON)
- && tp->tty_termios.c_cc[VTIME] > 0) {
- if (tp->tty_termios.c_cc[VMIN] == 0) {
- /* MIN & TIME specify a read timer that finishes the
- * read in TIME/10 seconds if no bytes are available.
- */
- settimer(tp, TRUE);
- tp->tty_min = 1;
- } else {
- /* MIN & TIME specify an inter-byte timer that may
- * have to be cancelled if there are no bytes yet.
- */
- if (tp->tty_eotct == 0) {
- settimer(tp, FALSE);
- tp->tty_min = tp->tty_termios.c_cc[VMIN];
- }
+ if (tp->tty_incaller != NONE || tp->tty_inleft > 0)
+ return EIO;
+ if (size <= 0)
+ return EINVAL;
+
+ /* Copy information from the message to the tty struct. */
+ tp->tty_incaller = endpt;
+ tp->tty_inid = id;
+ tp->tty_ingrant = grant;
+ assert(tp->tty_incum == 0);
+ tp->tty_inleft = size;
+
+ if (!(tp->tty_termios.c_lflag & ICANON) && tp->tty_termios.c_cc[VTIME] > 0) {
+ if (tp->tty_termios.c_cc[VMIN] == 0) {
+ /* MIN & TIME specify a read timer that finishes the
+ * read in TIME/10 seconds if no bytes are available.
+ */
+ settimer(tp, TRUE);
+ tp->tty_min = 1;
+ } else {
+ /* MIN & TIME specify an inter-byte timer that may
+ * have to be cancelled if there are no bytes yet.
+ */
+ if (tp->tty_eotct == 0) {
+ settimer(tp, FALSE);
+ tp->tty_min = tp->tty_termios.c_cc[VMIN];
}
}
+ }
- /* Anything waiting in the input buffer? Clear it out... */
- in_transfer(tp);
- /* ...then go back for more. */
- handle_events(tp);
- if (tp->tty_inleft == 0) {
- return; /* already done */
- }
+ /* Anything waiting in the input buffer? Clear it out... */
+ in_transfer(tp);
+ /* ...then go back for more. */
+ handle_events(tp);
+ if (tp->tty_inleft == 0)
+ return EDONTREPLY; /* already done */
- /* There were no bytes in the input queue available. */
- if (m_ptr->FLAGS & FLG_OP_NONBLOCK) {
- tty_icancel(tp);
- r = tp->tty_incum > 0 ? tp->tty_incum : EAGAIN;
- tp->tty_inleft = tp->tty_incum = 0;
- tp->tty_ingrant = GRANT_INVALID;
- } else {
- return; /* suspend the caller */
- }
+ /* There were no bytes in the input queue available. */
+ if (flags & FLG_OP_NONBLOCK) {
+ tty_icancel(tp);
+ r = tp->tty_incum > 0 ? tp->tty_incum : EAGAIN;
+ tp->tty_inleft = tp->tty_incum = 0;
+ tp->tty_incaller = NONE;
+ return r;
}
- tty_reply(DEV_REVIVE, m_ptr->m_source, m_ptr->USER_ENDPT,
- (cp_grant_id_t) m_ptr->IO_GRANT, r);
+
if (tp->tty_select_ops)
- select_retry(tp);
+ select_retry(tp);
+
+ return EDONTREPLY; /* suspend the caller */
}
/*===========================================================================*
* do_write *
*===========================================================================*/
-static void do_write(tp, m_ptr)
-register tty_t *tp;
-register message *m_ptr; /* pointer to message sent to the task */
+static ssize_t do_write(devminor_t minor, u64_t UNUSED(position),
+ endpoint_t endpt, cp_grant_id_t grant, size_t size, int flags,
+ cdev_id_t id)
{
/* A process wants to write on a terminal. */
+ tty_t *tp;
int r;
+ if ((tp = line2tty(minor)) == NULL)
+ return ENXIO;
+
/* Check if there is already a process hanging in a write, check if the
* parameters are correct, do I/O.
*/
- if (tp->tty_outleft > 0) {
- r = EIO;
- } else
- if (m_ptr->COUNT <= 0) {
- r = EINVAL;
- } else {
- /* Copy message parameters to the tty structure. */
- tp->tty_outcaller = m_ptr->m_source;
- tp->tty_outproc = m_ptr->USER_ENDPT;
- tp->tty_outgrant = (cp_grant_id_t) m_ptr->IO_GRANT;
- tp->tty_outoffset = 0;
- tp->tty_outleft = m_ptr->COUNT;
-
- /* Try to write. */
- handle_events(tp);
- if (tp->tty_outleft == 0)
- return; /* already done */
-
- /* None or not all the bytes could be written. */
- if (m_ptr->FLAGS & FLG_OP_NONBLOCK) {
- r = tp->tty_outcum > 0 ? tp->tty_outcum : EAGAIN;
- tp->tty_outleft = tp->tty_outcum = 0;
- tp->tty_outgrant = GRANT_INVALID;
- } else {
- return; /* suspend the caller */
- }
+ if (tp->tty_outcaller != NONE || tp->tty_outleft > 0)
+ return EIO;
+ if (size <= 0)
+ return EINVAL;
+
+ /* Copy message parameters to the tty structure. */
+ tp->tty_outcaller = endpt;
+ tp->tty_outid = id;
+ tp->tty_outgrant = grant;
+ assert(tp->tty_outcum == 0);
+ tp->tty_outleft = size;
+
+ /* Try to write. */
+ handle_events(tp);
+ if (tp->tty_outleft == 0)
+ return EDONTREPLY; /* already done */
+
+ /* None or not all the bytes could be written. */
+ if (flags & FLG_OP_NONBLOCK) {
+ r = tp->tty_outcum > 0 ? tp->tty_outcum : EAGAIN;
+ tp->tty_outleft = tp->tty_outcum = 0;
+ tp->tty_outcaller = NONE;
+ return r;
}
- tty_reply(DEV_REVIVE, m_ptr->m_source, m_ptr->USER_ENDPT,
- (cp_grant_id_t) m_ptr->IO_GRANT, r);
+
+ if (tp->tty_select_ops)
+ select_retry(tp);
+
+ return EDONTREPLY; /* suspend the caller */
}
/*===========================================================================*
* do_ioctl *
*===========================================================================*/
-static void do_ioctl(tp, m_ptr)
-register tty_t *tp;
-message *m_ptr; /* pointer to message sent to task */
+static int do_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt,
+ cp_grant_id_t grant, int flags, endpoint_t user_endpt, cdev_id_t id)
{
-/* Perform an IOCTL on this terminal. Posix termios calls are handled
- * by the IOCTL system call
+/* Perform an IOCTL on this terminal. POSIX termios calls are handled
+ * by the IOCTL system call.
*/
-
- int r;
- union {
- int i;
- } param;
+ tty_t *tp;
+ int i, r;
size_t size;
+ if ((tp = line2tty(minor)) == NULL)
+ return ENXIO;
+
/* Size of the ioctl parameter. */
- switch (m_ptr->REQUEST) {
+ switch (request) {
case TCGETS: /* Posix tcgetattr function */
case TCSETS: /* Posix tcsetattr function, TCSANOW option */
case TCSETSW: /* Posix tcsetattr function, TCSADRAIN option */
}
r = OK;
- switch (m_ptr->REQUEST) {
+ switch (request) {
case TCGETS:
/* Get the termios attributes. */
- r = sys_safecopyto(m_ptr->m_source, (cp_grant_id_t) m_ptr->IO_GRANT, 0,
- (vir_bytes) &tp->tty_termios, (vir_bytes) size);
+ r = sys_safecopyto(endpt, grant, 0, (vir_bytes) &tp->tty_termios,
+ size);
break;
case TCSETSW:
case TCSETSF:
case TCDRAIN:
if (tp->tty_outleft > 0) {
- if (m_ptr->FLAGS & FLG_OP_NONBLOCK) {
- r = EAGAIN;
- } else {
- /* Wait for all ongoing output processing to finish. */
- tp->tty_iocaller = m_ptr->m_source;
- tp->tty_ioproc = m_ptr->USER_ENDPT;
- tp->tty_ioreq = m_ptr->REQUEST;
- tp->tty_iogrant = (cp_grant_id_t) m_ptr->IO_GRANT;
- return;
- }
- break;
+ if (flags & FLG_OP_NONBLOCK)
+ return EAGAIN;
+ /* Wait for all ongoing output processing to finish. */
+ tp->tty_iocaller = endpt;
+ tp->tty_ioid = id;
+ tp->tty_ioreq = request;
+ tp->tty_iogrant = grant;
+ return EDONTREPLY; /* suspend the caller */
}
- if (m_ptr->REQUEST == TCDRAIN) break;
- if (m_ptr->REQUEST == TCSETSF) tty_icancel(tp);
+ if (request == TCDRAIN) break;
+ if (request == TCSETSF) tty_icancel(tp);
/*FALL THROUGH*/
case TCSETS:
/* Set the termios attributes. */
- r = sys_safecopyfrom(m_ptr->m_source, (cp_grant_id_t) m_ptr->IO_GRANT,
- 0, (vir_bytes) &tp->tty_termios, (vir_bytes) size);
+ r = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &tp->tty_termios,
+ size);
if (r != OK) break;
setattr(tp);
break;
case TCFLSH:
- r = sys_safecopyfrom(m_ptr->m_source, (cp_grant_id_t) m_ptr->IO_GRANT,
- 0, (vir_bytes) ¶m.i, (vir_bytes) size);
+ r = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &i, size);
if (r != OK) break;
- switch (param.i) {
- case TCIFLUSH: tty_icancel(tp); break;
- case TCOFLUSH: (*tp->tty_ocancel)(tp, 0); break;
- case TCIOFLUSH: tty_icancel(tp); (*tp->tty_ocancel)(tp, 0); break;
- default: r = EINVAL;
+ switch (i) {
+ case TCIFLUSH: tty_icancel(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;
case TCFLOW:
- r = sys_safecopyfrom(m_ptr->m_source, (cp_grant_id_t) m_ptr->IO_GRANT,
- 0, (vir_bytes) ¶m.i, (vir_bytes) size);
+ r = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &i, size);
if (r != OK) break;
- switch (param.i) {
+ switch (i) {
case TCOOFF:
case TCOON:
- tp->tty_inhibited = (param.i == TCOOFF);
+ tp->tty_inhibited = (i == TCOOFF);
tp->tty_events = 1;
break;
case TCIOFF:
break;
case TIOCGWINSZ:
- r = sys_safecopyto(m_ptr->m_source, (cp_grant_id_t) m_ptr->IO_GRANT, 0,
- (vir_bytes) &tp->tty_winsize, (vir_bytes) size);
+ r = sys_safecopyto(endpt, grant, 0, (vir_bytes) &tp->tty_winsize,
+ size);
break;
case TIOCSWINSZ:
- r = sys_safecopyfrom(m_ptr->m_source, (cp_grant_id_t) m_ptr->IO_GRANT,
- 0, (vir_bytes) &tp->tty_winsize, (vir_bytes) size);
+ r = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &tp->tty_winsize,
+ size);
sigchar(tp, SIGWINCH, 0);
break;
case KIOCSMAP:
/* Load a new keymap (only /dev/console). */
- if (isconsole(tp)) r = kbd_loadmap(m_ptr);
+ if (isconsole(tp)) r = kbd_loadmap(endpt, grant);
break;
- case TIOCSFON_OLD:
- printf("TTY: old TIOCSFON ignored.\n");
- break;
case TIOCSFON:
/* Load a font into an EGA or VGA card (hs@hck.hr) */
- if (isconsole(tp)) r = con_loadfont(m_ptr);
+ if (isconsole(tp)) r = con_loadfont(endpt, grant);
break;
/* These Posix functions are allowed to fail if _POSIX_JOB_CONTROL is
r = ENOTTY;
}
- /* Send the reply. */
- tty_reply(DEV_REVIVE, m_ptr->m_source, m_ptr->USER_ENDPT,
- (cp_grant_id_t) m_ptr->IO_GRANT, r);
+ return r;
}
/*===========================================================================*
* do_open *
*===========================================================================*/
-static void do_open(tp, m_ptr)
-register tty_t *tp;
-message *m_ptr; /* pointer to message sent to task */
+static int do_open(devminor_t minor, int access, endpoint_t user_endpt)
{
/* A tty line has been opened. Make it the callers controlling tty if
* O_NOCTTY is *not* set and it is not the log device. 1 is returned if
* the tty is made the controlling tty, otherwise OK or an error code.
*/
+ tty_t *tp;
int r = OK;
- if (m_ptr->DEVICE == LOG_MINOR) {
+ if ((tp = line2tty(minor)) == NULL)
+ return ENXIO;
+
+ if (minor == LOG_MINOR) {
/* The log device is a write-only diagnostics device. */
- if (m_ptr->COUNT & R_BIT) r = EACCES;
+ if (access & R_BIT) return EACCES;
} else {
- if (!(m_ptr->COUNT & O_NOCTTY)) {
- tp->tty_pgrp = m_ptr->USER_ENDPT;
+ if (!(access & O_NOCTTY)) {
+ tp->tty_pgrp = user_endpt;
r = 1;
}
tp->tty_openct++;
(*tp->tty_open)(tp, 0);
}
}
- tty_reply(DEV_OPEN_REPL, m_ptr->m_source, m_ptr->USER_ENDPT,
- (cp_grant_id_t) m_ptr->IO_GRANT, r);
+
+ return r;
}
/*===========================================================================*
* do_close *
*===========================================================================*/
-static void do_close(tp, m_ptr)
-register tty_t *tp;
-message *m_ptr; /* pointer to message sent to task */
+static int do_close(devminor_t minor)
{
/* A tty line has been closed. Clean up the line if it is the last close. */
+ tty_t *tp;
+
+ if ((tp = line2tty(minor)) == NULL)
+ return ENXIO;
- if (m_ptr->DEVICE != LOG_MINOR && --tp->tty_openct == 0) {
+ if (minor != LOG_MINOR && --tp->tty_openct == 0) {
tp->tty_pgrp = 0;
tty_icancel(tp);
(*tp->tty_ocancel)(tp, 0);
tp->tty_winsize = winsize_defaults;
setattr(tp);
}
- tty_reply(DEV_CLOSE_REPL, m_ptr->m_source, m_ptr->USER_ENDPT,
- (cp_grant_id_t) m_ptr->IO_GRANT, OK);
+
+ return OK;
}
/*===========================================================================*
* do_cancel *
*===========================================================================*/
-static void do_cancel(tp, m_ptr)
-register tty_t *tp;
-message *m_ptr; /* pointer to message sent to task */
+static int do_cancel(devminor_t minor, endpoint_t endpt, cdev_id_t id)
{
/* A signal has been sent to a process that is hanging trying to read or write.
* The pending read or write must be finished off immediately.
*/
- endpoint_t proc_nr;
- cp_grant_id_t grant;
- int mode;
- int r = EDONTREPLY;
+ tty_t *tp;
+ int r;
+
+ if ((tp = line2tty(minor)) == NULL)
+ return ENXIO;
/* Check the parameters carefully, to avoid cancelling twice. */
- proc_nr = m_ptr->USER_ENDPT;
- grant = (cp_grant_id_t) m_ptr->IO_GRANT;
- mode = m_ptr->COUNT;
- if ((mode & R_BIT) && tp->tty_inleft != 0 && proc_nr == tp->tty_inproc &&
- tp->tty_ingrant == grant) {
+ r = EDONTREPLY;
+ if (tp->tty_inleft != 0 && endpt == tp->tty_incaller && id == tp->tty_inid) {
/* Process was reading when killed. Clean up input. */
tty_icancel(tp);
r = tp->tty_incum > 0 ? tp->tty_incum : EAGAIN;
tp->tty_inleft = tp->tty_incum = 0;
- tp->tty_ingrant = GRANT_INVALID;
- }
- if ((mode & W_BIT) && tp->tty_outleft != 0 && proc_nr == tp->tty_outproc &&
- tp->tty_outgrant == grant) {
+ tp->tty_incaller = NONE;
+ } else if (tp->tty_outleft != 0 && endpt == tp->tty_outcaller &&
+ id == tp->tty_outid) {
/* Process was writing when killed. Clean up output. */
r = tp->tty_outcum > 0 ? tp->tty_outcum : EAGAIN;
tp->tty_outleft = tp->tty_outcum = 0;
- tp->tty_outgrant = GRANT_INVALID;
- }
- if (tp->tty_ioreq != 0 && proc_nr == tp->tty_ioproc) {
+ tp->tty_outcaller = NONE;
+ } else if (tp->tty_ioreq != 0 && endpt == tp->tty_iocaller &&
+ id == tp->tty_ioid) {
/* Process was waiting for output to drain. */
- tp->tty_ioreq = 0;
r = EINTR;
+ tp->tty_ioreq = 0;
+ tp->tty_iocaller = NONE;
}
- tp->tty_events = 1;
- /* Only reply if we found a matching request. */
if (r != EDONTREPLY)
- tty_reply(DEV_REVIVE, m_ptr->m_source, proc_nr, grant, r);
+ tp->tty_events = 1;
+ /* Only reply if we found a matching request. */
+ return r;
}
int select_try(struct tty *tp, int ops)
int ops;
if (tp->tty_select_ops && (ops = select_try(tp, tp->tty_select_ops))) {
- assert(tp->tty_select_minor == tp->tty_minor);
- select_reply(DEV_SEL_REPL2, tp->tty_select_proc, tp->tty_minor,
+ chardriver_reply_select(tp->tty_select_proc, tp->tty_minor,
ops);
tp->tty_select_ops &= ~ops;
}
return OK;
}
+/*===========================================================================*
+ * do_select *
+ *===========================================================================*/
+static int do_select(devminor_t minor, unsigned int ops, endpoint_t endpt)
+{
+ tty_t *tp;
+ int ready_ops, watch;
+
+ if ((tp = line2tty(minor)) == NULL)
+ return ENXIO;
+
+ /* Translated minor numbers are a problem when sending late replies. */
+ if (tp->tty_minor != minor)
+ return EBADF;
+
+ watch = (ops & SEL_NOTIFY);
+ ops &= (SEL_RD | SEL_WR | SEL_ERR);
+
+ ready_ops = select_try(tp, ops);
+
+ ops &= ~ready_ops;
+ if (ops && watch) {
+ tp->tty_select_ops |= ops;
+ tp->tty_select_proc = endpt;
+ }
+
+ assert(tp->tty_minor == minor);
+ return ready_ops;
+}
+
/*===========================================================================*
* handle_events *
*===========================================================================*/
* to avoid swamping the TTY task. Messages may be overwritten when the
* lines are fast or when there are races between different lines, input
* and output, because MINIX only provides single buffering for interrupt
- * messages (in proc.c). This is handled by explicitly checking each line
- * for fresh input and completed output on each interrupt.
+ * messages. This is handled by explicitly checking each line for fresh input
+ * and completed output on each interrupt.
*/
do {
/* Reply if enough bytes are available. */
if (tp->tty_incum >= tp->tty_min && tp->tty_inleft > 0) {
- tty_reply(DEV_REVIVE, tp->tty_incaller, tp->tty_inproc,
- tp->tty_ingrant, tp->tty_incum);
+ chardriver_reply_task(tp->tty_incaller, tp->tty_inid, tp->tty_incum);
tp->tty_inleft = tp->tty_incum = 0;
- tp->tty_ingrant = GRANT_INVALID;
+ tp->tty_incaller = NONE;
}
if (tp->tty_select_ops)
{
if (++bp == bufend(buf)) {
/* Temp buffer full, copy to user space. */
sys_safecopyto(tp->tty_incaller,
- tp->tty_ingrant, tp->tty_inoffset,
- (vir_bytes) buf,
- (vir_bytes) buflen(buf));
- tp->tty_inoffset += buflen(buf);
+ tp->tty_ingrant, tp->tty_incum,
+ (vir_bytes) buf, (vir_bytes) buflen(buf));
tp->tty_incum += buflen(buf);
bp = buf;
}
if (bp > buf) {
/* Leftover characters in the buffer. */
count = bp - buf;
- sys_safecopyto(tp->tty_incaller,
- tp->tty_ingrant, tp->tty_inoffset,
+ sys_safecopyto(tp->tty_incaller, tp->tty_ingrant, tp->tty_incum,
(vir_bytes) buf, (vir_bytes) count);
- tp->tty_inoffset += count;
tp->tty_incum += count;
}
/* Usually reply to the reader, possibly even if incum == 0 (EOF). */
if (tp->tty_inleft == 0) {
- tty_reply(DEV_REVIVE, tp->tty_incaller, tp->tty_inproc,
- tp->tty_ingrant, tp->tty_incum);
+ chardriver_reply_task(tp->tty_incaller, tp->tty_inid, tp->tty_incum);
tp->tty_inleft = tp->tty_incum = 0;
- tp->tty_ingrant = GRANT_INVALID;
+ tp->tty_incaller = NONE;
}
}
if (result == OK) setattr(tp);
}
tp->tty_ioreq = 0;
- tty_reply(DEV_REVIVE, tp->tty_iocaller, tp->tty_ioproc, tp->tty_iogrant,
- result);
- tp->tty_iogrant = GRANT_INVALID;
+ chardriver_reply_task(tp->tty_iocaller, tp->tty_ioid, result);
+ tp->tty_iocaller = NONE;
}
/*===========================================================================*
(*tp->tty_ioctl)(tp, 0);
}
-/*===========================================================================*
- * tty_reply *
- *===========================================================================*/
-void
-tty_reply_f(
-file, line, code, replyee, proc_nr, grant, status)
-char *file;
-int line;
-int code; /* DEV_OPEN_REPL, DEV_CLOSE_REPL, DEV_REVIVE */
-endpoint_t replyee; /* destination address for the reply */
-endpoint_t proc_nr; /* to whom should the reply go? */
-cp_grant_id_t grant; /* which grant was involved? */
-int status; /* reply code */
-{
- message m;
-
- assert(code == DEV_OPEN_REPL || code == DEV_CLOSE_REPL || code == DEV_REVIVE);
-
- /* Don't reply to KERNEL (kernel messages) */
- if (replyee == KERNEL) return;
-
- memset(&m, 0, sizeof(m));
-
- m.REP_ENDPT = proc_nr;
- m.REP_IO_GRANT = grant;
- m.REP_STATUS = status;
-
- status = _sendcall(replyee, code, &m);
- if (status != OK)
- printf("tty`tty_reply: send to %d failed: %d\n", replyee, status);
-}
-
-/*===========================================================================*
- * select_reply *
- *===========================================================================*/
-void select_reply(int code, endpoint_t replyee, dev_t minor, int ops)
-{
- message m;
- int status;
-
- memset(&m, 0, sizeof(m));
-
- m.DEV_MINOR = minor;
- m.DEV_SEL_OPS = ops;
-
- status = _sendcall(replyee, code, &m);
- if (status != OK)
- printf("tty`select_reply: send to %d failed: %d\n", replyee, status);
-}
-
-
/*===========================================================================*
* sigchar *
*===========================================================================*/
tp->tty_intail = tp->tty_inhead = tp->tty_inbuf;
tp->tty_min = 1;
- tp->tty_ingrant = tp->tty_outgrant = tp->tty_iogrant = GRANT_INVALID;
+ tp->tty_incaller = tp->tty_outcaller = tp->tty_iocaller = NONE;
tp->tty_termios = termios_defaults;
tp->tty_icancel = tp->tty_ocancel = tp->tty_ioctl = tp->tty_close =
tp->tty_open = tty_devnop;
cancel_timer(&tty_ptr->tty_tmr);
}
}
-
-/*===========================================================================*
- * do_select *
- *===========================================================================*/
-static 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;
-
- ops = m_ptr->DEV_SEL_OPS & (SEL_RD|SEL_WR|SEL_ERR);
- watch = (m_ptr->DEV_SEL_OPS & SEL_NOTIFY) ? 1 : 0;
-
- ready_ops = select_try(tp, ops);
-
- if (!ready_ops && ops && watch) {
- tp->tty_select_ops |= ops;
- tp->tty_select_proc = m_ptr->m_source;
- tp->tty_select_minor = m_ptr->DEV_MINOR;
- }
-
- assert(tp->tty_minor == m_ptr->DEV_MINOR);
- select_reply(DEV_SEL_REPL1, m_ptr->m_source, tp->tty_minor, ready_ops);
-}
/* tty.h - Terminals */
+#include <minix/chardriver.h>
#include <timers.h>
#undef lock
typedef struct tty {
int tty_events; /* set when TTY should inspect this line */
int tty_index; /* index into TTY table */
- int tty_minor; /* device minor number */
+ devminor_t tty_minor; /* device minor number */
/* Input queue. Typed characters are stored here until read by a program. */
u16_t *tty_inhead; /* pointer to place where next char goes */
char tty_openct; /* count of number of opens of this tty */
/* Information about incomplete I/O requests is stored here. */
- endpoint_t tty_incaller; /* process that made the call (usually VFS) */
- endpoint_t tty_inproc; /* process that wants to read from tty */
+ endpoint_t tty_incaller; /* process that made the call, or NONE */
+ cdev_id_t tty_inid; /* ID of suspended read request */
cp_grant_id_t tty_ingrant; /* grant where data is to go */
- vir_bytes tty_inoffset; /* offset into grant */
- int tty_inleft; /* how many chars are still needed */
- int tty_incum; /* # chars input so far */
- endpoint_t tty_outcaller; /* process that made the call (usually VFS) */
- endpoint_t tty_outproc; /* process that wants to write to tty */
+ size_t tty_inleft; /* how many chars are still needed */
+ size_t tty_incum; /* # chars input so far */
+ endpoint_t tty_outcaller; /* process that made the call, or NONE */
+ cdev_id_t tty_outid; /* ID of suspended write request */
cp_grant_id_t tty_outgrant; /* grant where data comes from */
- vir_bytes tty_outoffset; /* offset into grant */
- int tty_outleft; /* # chars yet to be output */
- int tty_outcum; /* # chars output so far */
- endpoint_t tty_iocaller; /* process that made the call (usually VFS) */
- endpoint_t tty_ioproc; /* process that wants to do an ioctl */
- int tty_ioreq; /* ioctl request code */
+ size_t tty_outleft; /* # chars yet to be output */
+ size_t tty_outcum; /* # chars output so far */
+ endpoint_t tty_iocaller; /* process that made the call, or NONE */
+ cdev_id_t tty_ioid; /* ID of suspended ioctl request */
+ unsigned int tty_ioreq; /* ioctl request code */
cp_grant_id_t tty_iogrant; /* virtual address of ioctl buffer or grant */
/* select() data */
int tty_select_ops; /* which operations are interesting */
endpoint_t tty_select_proc; /* which process wants notification */
- dev_t tty_select_minor; /* sanity check only, can be removed */
/* Miscellaneous. */
devfun_t tty_ioctl; /* set line speed, etc. at the device level */
void handle_events(struct tty *tp);
void sigchar(struct tty *tp, int sig, int mayflush);
void tty_task(void);
+tty_t *line2tty(devminor_t minor);
int in_process(struct tty *tp, char *buf, int count, int scode);
void out_process(struct tty *tp, char *bstart, char *bpos, char *bend,
int *icount, int *ocount);
void tty_wakeup(clock_t now);
-#define tty_reply(c, r, p, g, s) tty_reply_f(__FILE__, __LINE__, (c), (r), (p), (g), (s))
-void tty_reply_f(char *f, int l, int code, endpoint_t replyee,
- endpoint_t proc_nr, cp_grant_id_t grant, int status);
-void select_reply(int code, endpoint_t replyee, dev_t minor, int ops);
int select_try(struct tty *tp, int ops);
int select_retry(struct tty *tp);
void cons_stop(void);
void scr_init(struct tty *tp);
void toggle_scroll(void);
-int con_loadfont(message *m);
+int con_loadfont(endpoint_t endpt, cp_grant_id_t grant);
void select_console(int cons_line);
void beep_x( unsigned freq, clock_t dur);
-void do_video(message *m);
+void do_video(message *m, int ipc_status);
/* keyboard.c */
void kb_init(struct tty *tp);
void kb_init_once(void);
-int kbd_loadmap(message *m);
+int kbd_loadmap(endpoint_t endpt, cp_grant_id_t grant);
void do_fkey_ctl(message *m);
void kbd_interrupt(message *m);
-void do_kbd(message *m);
+void do_kbd(message *m, int ipc_status);
void do_kb_inject(message *m);
-void do_kbdaux(message *m);
/* pty.c */
-void do_pty(struct tty *tp, message *m_ptr);
+void do_pty(message *m_ptr, int ipc_status);
void pty_init(struct tty *tp);
void select_retry_pty(struct tty *tp);
reboot.h rs.h safecopies.h sched.h sef.h sffs.h \
sound.h spin.h sys_config.h sysinfo.h \
syslib.h sysutil.h termios.h timers.h type.h \
- tty.h u64.h usb.h usb_ch9.h vbox.h \
+ u64.h usb.h usb_ch9.h vbox.h \
vboxfs.h vboxif.h vboxtype.h vm.h \
vfsif.h vtreefs.h libminixfs.h netsock.h \
virtio.h
#define TTY_FKEY_CONTROL (TTY_RQ_BASE + 1) /* control an F-key at TTY */
-#define OLD_FKEY_CONTROL 98 /* previously used for TTY_FKEY_CONTROL */
# define FKEY_REQUEST m2_i1 /* request to perform at TTY */
# define FKEY_MAP 10 /* observe function key */
# define FKEY_UNMAP 11 /* stop observing function key */
+++ /dev/null
-
-#ifndef _MINIX_TTY_H
-#define _MINIX_TTY_H
-
-#include <sys/types.h>
-
-#define TTYMAGIC 0xb105
-
-/* A struct that the tty driver can use to pass values to the boot monitor.
- * Currently only the value of the origin of the first vty (console), so the
- * boot monitor can properly display it when panicing (tty isn't scheduled
- * to switch to the first vty). It's written at the end of video memory
- * (video memory base + video memory size - sizeof(struct boot_tty_info).
- */
-
-struct boot_tty_info {
- u16_t reserved[30]; /* reserved, set to 0 */
- u16_t consorigin; /* origin in video memory of console */
- u16_t conscursor; /* position of cursor of console */
- u16_t flags; /* flags indicating which fields are valid */
- u16_t magic; /* magic number indicating struct is valid */
-};
-
-#define BTIF_CONSORIGIN 0x01 /* consorigin is set */
-#define BTIF_CONSCURSOR 0x02 /* conscursor is set */
-
-#endif
-
#define TIOCSWINSZ _IOW('T', 17, struct winsize)
#define TIOCGPGRP _IOW('T', 18, int)
#define TIOCSPGRP _IOW('T', 19, int)
-#define TIOCSFON_OLD _IOW('T', 20, u8_t [8192])
#define TIOCSFON _IOW_BIG(1, u8_t [8192])
/* Keyboard ioctls. */