From 665198b4c26ad7bde84f4b8e5836ff4dc7d26622 Mon Sep 17 00:00:00 2001 From: David van Moolenbroek Date: Tue, 10 Sep 2013 20:25:01 +0200 Subject: [PATCH] Rewrite character driver protocol As a side effect, remove the clone style, as the normal device style supports device cloning now. Change-Id: Ie82d1ef0385514a04a8faa139129a617895780b5 --- commands/service/service.c | 4 +- drivers/log/log.c | 20 +- drivers/printer/printer.c | 23 +- drivers/tty/arch/i386/keyboard.c | 24 +- drivers/tty/pty.c | 24 +- drivers/tty/tty.c | 76 ++----- drivers/tty/tty.h | 3 - etc/rs.inet | 4 +- etc/usr/rc | 4 +- include/minix/com.h | 136 ++++++------ include/minix/dmap.h | 4 +- lib/libaudiodriver/audio_fw.c | 17 -- lib/libblockdriver/driver.c | 8 +- lib/libchardriver/chardriver.c | 187 ++++++++-------- lib/libnetsock/socket.c | 29 ++- servers/inet/sr.c | 26 +-- servers/is/dmp_fs.c | 1 - servers/lwip/tcp.c | 40 ++-- servers/pfs/dev_uds.c | 44 ++-- servers/pfs/main.c | 2 +- servers/pfs/uds.c | 6 +- servers/pfs/uds.h | 2 +- servers/rs/table.c | 2 +- servers/vfs/comm.c | 4 +- servers/vfs/const.h | 15 +- servers/vfs/device.c | 369 +++++++++++++------------------ servers/vfs/dmap.c | 9 +- servers/vfs/dmap.h | 2 +- servers/vfs/filedes.c | 2 +- servers/vfs/fproc.h | 2 - servers/vfs/main.c | 36 +-- servers/vfs/misc.c | 2 +- servers/vfs/open.c | 4 +- servers/vfs/pipe.c | 4 +- servers/vfs/proto.h | 16 +- servers/vfs/read.c | 8 +- servers/vfs/select.c | 8 +- sys/sys/select.h | 9 - 38 files changed, 515 insertions(+), 661 deletions(-) diff --git a/commands/service/service.c b/commands/service/service.c index 0d504cf79..b20b65a14 100644 --- a/commands/service/service.c +++ b/commands/service/service.c @@ -335,9 +335,9 @@ static int parse_arguments(int argc, char **argv, u32_t *rss_flags) } else if (strcmp(argv[i], ARG_DEVSTYLE)==0) { char* dev_style_keys[] = { "STYLE_DEV", "STYLE_TTY", - "STYLE_CTTY", "STYLE_CLONE", NULL }; + "STYLE_CTTY", NULL }; int dev_style_values[] = { STYLE_DEV, STYLE_TTY, - STYLE_CTTY, STYLE_CLONE }; + STYLE_CTTY }; for(j=0;dev_style_keys[j]!=NULL;j++) { if(!strcmp(dev_style_keys[j], argv[i+1])) { break; diff --git a/drivers/log/log.c b/drivers/log/log.c index 67c466053..45b5e620d 100644 --- a/drivers/log/log.c +++ b/drivers/log/log.c @@ -167,17 +167,17 @@ subwrite(struct logdevice *log, size_t size, endpoint_t endpt, log->log_source = NONE; } - if (log->log_size > 0 && (log->log_selected & SEL_RD)) { + if (log->log_size > 0 && (log->log_selected & CDEV_OP_RD)) { /* Someone(s) who was/were select()ing can now be awoken. If there was * a blocking read (above), this can only happen if the blocking read * didn't swallow all the data (log_size > 0). */ minor = log-logdevices; #if LOG_DEBUG - printf("select sending DEV_SEL_REPL2\n"); + printf("select sending CDEV_SEL2_REPLY\n"); #endif - chardriver_reply_select(log->log_select_proc, minor, SEL_RD); - log->log_selected &= ~SEL_RD; + chardriver_reply_select(log->log_select_proc, minor, CDEV_OP_RD); + log->log_selected &= ~CDEV_OP_RD; } return r; @@ -248,7 +248,7 @@ static ssize_t log_read(devminor_t minor, u64_t UNUSED(position), if (log->log_source != NONE) return OK; if (!log->log_size && size > 0) { - if (flags & FLG_OP_NONBLOCK) return EAGAIN; + if (flags & CDEV_NONBLOCK) return EAGAIN; /* No data available; let caller block. */ log->log_source = endpt; @@ -319,24 +319,24 @@ static int log_select(devminor_t minor, unsigned int ops, endpoint_t endpt) if (minor < 0 || minor >= NR_DEVS) return ENXIO; - want_ops = ops & (SEL_RD|SEL_WR|SEL_ERR); + want_ops = ops & (CDEV_OP_RD | CDEV_OP_WR | CDEV_OP_ERR); /* Read blocks when there is no log. */ - if ((want_ops & SEL_RD) && logdevices[minor].log_size > 0) { + if ((want_ops & CDEV_OP_RD) && logdevices[minor].log_size > 0) { #if LOG_DEBUG printf("log can read; size %d\n", logdevices[minor].log_size); #endif - ready_ops |= SEL_RD; + ready_ops |= CDEV_OP_RD; } /* Write never blocks. */ - if (want_ops & SEL_WR) ready_ops |= SEL_WR; + if (want_ops & CDEV_OP_WR) ready_ops |= CDEV_OP_WR; /* Enable select calback if not all requested operations were ready to go, * and notify was enabled. */ want_ops &= ~ready_ops; - if ((ops & SEL_NOTIFY) && want_ops) { + if ((ops & CDEV_NOTIFY) && want_ops) { logdevices[minor].log_selected |= want_ops; logdevices[minor].log_select_proc = endpt; #if LOG_DEBUG diff --git a/drivers/printer/printer.c b/drivers/printer/printer.c index 6b75aadd1..47abec238 100644 --- a/drivers/printer/printer.c +++ b/drivers/printer/printer.c @@ -5,27 +5,6 @@ * Changes: * May 07, 2004 fix: wait until printer is ready (Jorrit N. Herder) * May 06, 2004 printer driver moved to user-space (Jorrit N. Herder) - * - * The valid messages and their parameters are: - * - * DEV_OPEN: initializes the printer - * DEV_CLOSE: does nothing - * HARD_INT: interrupt handler has finished current chunk of output - * DEV_WRITE: a process wants to write on a terminal - * CANCEL: terminate a previous incomplete system call immediately - * - * m_type DEVICE USER_ENDPT COUNT ADDRESS - * |-------------+---------+---------+---------+---------| - * | DEV_OPEN | | | | | - * |-------------+---------+---------+---------+---------| - * | DEV_CLOSE | | proc nr | | | - * |-------------+---------+---------+---------+---------| - * | HARD_INT | | | | | - * |-------------+---------+---------+---------+---------| - * | DEV_WRITE |minor dev| proc nr | count | buf ptr | - * |-------------+---------+---------+---------+---------| - * | CANCEL |minor dev| proc nr | | | - * ------------------------------------------------------- * * Note: since only 1 printer is supported, minor dev is not used at present. */ @@ -192,7 +171,7 @@ static ssize_t printer_write(devminor_t UNUSED(minor), u64_t UNUSED(position), */ if (writing) return EIO; if (size <= 0) return EINVAL; - if (flags & FLG_OP_NONBLOCK) return EAGAIN; /* not supported */ + if (flags & CDEV_NONBLOCK) return EAGAIN; /* not supported */ /* If no errors occurred, continue printing with the caller. * First wait until the printer is online to prevent stupid errors. diff --git a/drivers/tty/arch/i386/keyboard.c b/drivers/tty/arch/i386/keyboard.c index 3b601da33..60e98378d 100644 --- a/drivers/tty/arch/i386/keyboard.c +++ b/drivers/tty/arch/i386/keyboard.c @@ -261,7 +261,7 @@ kbd_read(devminor_t minor, u64_t UNUSED(position), endpoint_t endpt, /* If no data is available, suspend the caller. */ if (kbdp->avail == 0) { - if (flags & FLG_OP_NONBLOCK) + if (flags & CDEV_NONBLOCK) return EAGAIN; kbdp->req_size = size; kbdp->req_id = id; @@ -420,14 +420,14 @@ kbd_select(devminor_t minor, unsigned int ops, endpoint_t endpt) if ((kbdp = line2kbd(minor)) == NULL) return ENXIO; - watch = (ops & SEL_NOTIFY); - ops &= (SEL_RD | SEL_WR | SEL_ERR); + watch = (ops & CDEV_NOTIFY); + ops &= (CDEV_OP_RD | CDEV_OP_WR | CDEV_OP_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 */ + if (kbdp->avail && (ops & CDEV_OP_RD)) + ready_ops |= CDEV_OP_RD; + if (ops & CDEV_OP_WR) + ready_ops |= CDEV_OP_WR; /* writes never block */ ops &= ~ready_ops; if (ops && watch) { @@ -543,10 +543,10 @@ void kbd_interrupt(message *UNUSED(m_ptr)) kbdp->req_caller = NONE; } /* Only satisfy pending select if characters weren't just read. */ - if (kbdp->avail && (kbdp->select_ops & SEL_RD)) { + if (kbdp->avail && (kbdp->select_ops & CDEV_OP_RD)) { chardriver_reply_select(kbdp->select_proc, kbdp->minor, - SEL_RD); - kbdp->select_ops &= ~SEL_RD; + CDEV_OP_RD); + kbdp->select_ops &= ~CDEV_OP_RD; } return; } @@ -557,7 +557,7 @@ void kbd_interrupt(message *UNUSED(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) { + if (tty_table[ccurrent].tty_select_ops & CDEV_OP_RD) { select_retry(&tty_table[ccurrent]); } } @@ -581,7 +581,7 @@ void do_kb_inject(message *msg) if (injhead == injbuf + KB_IN_BYTES) injhead = injbuf; injcount++; tty_table[ccurrent].tty_events = 1; - if (tty_table[ccurrent].tty_select_ops & SEL_RD) { + if (tty_table[ccurrent].tty_select_ops & CDEV_OP_RD) { select_retry(&tty_table[ccurrent]); } } diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index f59de6374..2a16fd074 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -167,7 +167,7 @@ static ssize_t pty_master_read(devminor_t minor, u64_t UNUSED(position), return EDONTREPLY; /* already done */ } - if (flags & FLG_OP_NONBLOCK) { + if (flags & CDEV_NONBLOCK) { r = pp->rdcum > 0 ? pp->rdcum : EAGAIN; pp->rdleft = pp->rdcum = 0; pp->rdcaller = NONE; @@ -214,7 +214,7 @@ static ssize_t pty_master_write(devminor_t minor, u64_t UNUSED(position), return EDONTREPLY; /* already done */ } - if (flags & FLG_OP_NONBLOCK) { + if (flags & CDEV_NONBLOCK) { r = pp->wrcum > 0 ? pp->wrcum : EAGAIN; pp->wrleft = pp->wrcum = 0; pp->wrcaller = NONE; @@ -265,18 +265,18 @@ static int select_try_pty(tty_t *tp, int ops) pty_t *pp = tp->tty_priv; int r = 0; - if (ops & SEL_WR) { + if (ops & CDEV_OP_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. */ + if (pp->state & TTY_CLOSED) r |= CDEV_OP_WR; + else if (pp->wrleft != 0 || pp->wrcum != 0) r |= CDEV_OP_WR; + else if (tp->tty_inleft > 0) r |= CDEV_OP_WR; /* There's a reader. */ } - if (ops & SEL_RD) { + if (ops & CDEV_OP_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. */ + if (pp->state & TTY_CLOSED) r |= CDEV_OP_RD; + else if (pp->rdleft != 0 || pp->rdcum != 0) r |= CDEV_OP_RD; + else if (pp->ocount > 0) r |= CDEV_OP_RD; /* Actual data. */ } return r; @@ -313,8 +313,8 @@ static int pty_master_select(devminor_t minor, unsigned int ops, return ENXIO; pp = tp->tty_priv; - watch = (ops & SEL_NOTIFY); - ops &= (SEL_RD | SEL_WR | SEL_ERR); + watch = (ops & CDEV_NOTIFY); + ops &= (CDEV_OP_RD | CDEV_OP_WR | CDEV_OP_ERR); ready_ops = select_try_pty(tp, ops); diff --git a/drivers/tty/tty.c b/drivers/tty/tty.c index 5bcc05b7f..cd61f21e7 100644 --- a/drivers/tty/tty.c +++ b/drivers/tty/tty.c @@ -16,38 +16,6 @@ * to, you guessed it, wake up the TTY to check if input or output can * continue. * - * The valid messages and their parameters are: - * - * notify from HARDWARE: output has been completed or input has arrived - * notify from SYSTEM : e.g., 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 - * CANCEL: terminate a previous incomplete system call immediately - * - * m_type DEVICE USER_ENDPT COUNT POSITION IO_GRANT - * ----------------------------------------------------------------- - * | HARD_INT | | | | | | - * |-------------+---------+---------+---------+---------+---------| - * | DEV_READ |minor dev| proc nr | count | | grant | - * |-------------+---------+---------+---------+---------+---------| - * | DEV_WRITE |minor dev| proc nr | count | | grant | - * |-------------+---------+---------+---------+---------+---------| - * | DEV_IOCTL |minor dev| proc nr |func code|user proc| | - * |-------------+---------+---------+---------+---------+---------| - * | DEV_OPEN |minor dev| proc nr | O_NOCTTY| | | - * |-------------+---------+---------+---------+---------+---------| - * | DEV_CLOSE |minor dev| proc nr | | | | - * |-------------+---------+---------+---------+---------+---------| - * | CANCEL |minor dev| proc nr | | | | - * |-------------+---------+---------+---------+---------+---------| - * | DEV_SELECT |minor dev| sel ops | | | | - * ----------------------------------------------------------------- - * * Changes: * Jan 20, 2004 moved TTY driver to user-space (Jorrit N. Herder) * Sep 20, 2004 local timer management/ sync alarms (Jorrit N. Herder) @@ -235,7 +203,7 @@ int main(void) ; /* do nothing; end switch */ } - if (!IS_DEV_RQ(tty_mess.m_type)) { + if (!IS_CDEV_RQ(tty_mess.m_type)) { chardriver_process(&tty_tab, &tty_mess, ipc_status); continue; } @@ -243,7 +211,7 @@ int main(void) /* Only device requests should get to this point. * All requests have a minor device number. */ - line = tty_mess.DEVICE; + line = tty_mess.CDEV_MINOR; if (line == KBD_MINOR || line == KBDAUX_MINOR) { do_kbd(&tty_mess, ipc_status); continue; @@ -251,7 +219,7 @@ int main(void) do_video(&tty_mess, ipc_status); continue; } else if (line - PTYPX_MINOR < NR_PTYS && - tty_mess.m_type != DEV_IOCTL_S) { + tty_mess.m_type != CDEV_IOCTL) { /* 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). @@ -276,7 +244,7 @@ set_color(tty_t *tp, int color) buf[0] = '\033'; snprintf(&buf[1], sizeof(buf) - 1, "[1;%dm", color); do_write(tp->tty_minor, 0, KERNEL, (cp_grant_id_t) buf, sizeof(buf), - FLG_OP_NONBLOCK, 0); + CDEV_NONBLOCK, 0); } static void @@ -288,7 +256,7 @@ reset_color(tty_t *tp) buf[0] = '\033'; snprintf(&buf[1], sizeof(buf) - 1, "[0;%dm", SGR_COLOR_RESET); do_write(tp->tty_minor, 0, KERNEL, (cp_grant_id_t) buf, sizeof(buf), - FLG_OP_NONBLOCK, 0); + CDEV_NONBLOCK, 0); } tty_t * @@ -466,7 +434,7 @@ do_new_kmess(void) set_color(tp, kernel_msg_color); do_write(tp->tty_minor, 0, KERNEL, (cp_grant_id_t) kernel_buf_copy, bytes, - FLG_OP_NONBLOCK, 0); + CDEV_NONBLOCK, 0); if (kernel_msg_color != 0) reset_color(tp); if (restore) { @@ -553,7 +521,7 @@ static ssize_t do_read(devminor_t minor, u64_t UNUSED(position), return EDONTREPLY; /* already done */ /* There were no bytes in the input queue available. */ - if (flags & FLG_OP_NONBLOCK) { + if (flags & CDEV_NONBLOCK) { tty_icancel(tp); r = tp->tty_incum > 0 ? tp->tty_incum : EAGAIN; tp->tty_inleft = tp->tty_incum = 0; @@ -602,7 +570,7 @@ static ssize_t do_write(devminor_t minor, u64_t UNUSED(position), return EDONTREPLY; /* already done */ /* None or not all the bytes could be written. */ - if (flags & FLG_OP_NONBLOCK) { + if (flags & CDEV_NONBLOCK) { r = tp->tty_outcum > 0 ? tp->tty_outcum : EAGAIN; tp->tty_outleft = tp->tty_outcum = 0; tp->tty_outcaller = NONE; @@ -677,7 +645,7 @@ static int do_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt, case TCSETSF: case TCDRAIN: if (tp->tty_outleft > 0) { - if (flags & FLG_OP_NONBLOCK) + if (flags & CDEV_NONBLOCK) return EAGAIN; /* Wait for all ongoing output processing to finish. */ tp->tty_iocaller = endpt; @@ -771,8 +739,8 @@ static int do_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt, 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. + * CDEV_NOCTTY is *not* set and it is not the log device. CDEV_CTTY is returned + * if the tty is made the controlling tty, otherwise OK or an error code. */ tty_t *tp; int r = OK; @@ -782,11 +750,11 @@ static int do_open(devminor_t minor, int access, endpoint_t user_endpt) if (minor == LOG_MINOR && isconsole(tp)) { /* The log device is a write-only diagnostics device. */ - if (access & R_BIT) return EACCES; + if (access & CDEV_R_BIT) return EACCES; } else { - if (!(access & O_NOCTTY)) { + if (!(access & CDEV_NOCTTY)) { tp->tty_pgrp = user_endpt; - r = 1; + r = CDEV_CTTY; } tp->tty_openct++; if (tp->tty_openct == 1) { @@ -874,10 +842,10 @@ int select_try(struct tty *tp, int ops) ready_ops |= ops; } - if (ops & SEL_RD) { + if (ops & CDEV_OP_RD) { /* will i/o not block on read? */ if (tp->tty_inleft > 0) { - ready_ops |= SEL_RD; /* EIO - no blocking */ + ready_ops |= CDEV_OP_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 @@ -885,14 +853,14 @@ int select_try(struct tty *tp, int ops) */ if (!(tp->tty_termios.c_lflag & ICANON) || tp->tty_eotct > 0) { - ready_ops |= SEL_RD; + ready_ops |= CDEV_OP_RD; } } } - if (ops & SEL_WR) { - if (tp->tty_outleft > 0) ready_ops |= SEL_WR; - else if ((*tp->tty_devwrite)(tp, 1)) ready_ops |= SEL_WR; + if (ops & CDEV_OP_WR) { + if (tp->tty_outleft > 0) ready_ops |= CDEV_OP_WR; + else if ((*tp->tty_devwrite)(tp, 1)) ready_ops |= CDEV_OP_WR; } return ready_ops; } @@ -924,8 +892,8 @@ static int do_select(devminor_t minor, unsigned int ops, endpoint_t endpt) if (tp->tty_minor != minor) return EBADF; - watch = (ops & SEL_NOTIFY); - ops &= (SEL_RD | SEL_WR | SEL_ERR); + watch = (ops & CDEV_NOTIFY); + ops &= (CDEV_OP_RD | CDEV_OP_WR | CDEV_OP_ERR); ready_ops = select_try(tp, ops); diff --git a/drivers/tty/tty.h b/drivers/tty/tty.h index baca8dcc3..f83a980f7 100644 --- a/drivers/tty/tty.h +++ b/drivers/tty/tty.h @@ -25,9 +25,6 @@ #define ESC '\33' /* escape */ -#define O_NOCTTY 00400 /* from , or cc will choke */ -#define O_NONBLOCK 04000 - struct tty; typedef int(*devfun_t) (struct tty *tp, int try_only); typedef void(*devfunarg_t) (struct tty *tp, int c); diff --git a/etc/rs.inet b/etc/rs.inet index 8eb1529a0..b4bc3c840 100755 --- a/etc/rs.inet +++ b/etc/rs.inet @@ -65,10 +65,10 @@ kill_by_name syslogd sleep 3 if [ X`/bin/sysenv lwip` = Xyes ] then - service up /usr/sbin/lwip -script /etc/rs.inet -dev /dev/ip -devstyle STYLE_CLONE + service up /usr/sbin/lwip -script /etc/rs.inet -dev /dev/ip dhcpd --lwip & else - service up /usr/sbin/inet -script /etc/rs.inet -dev /dev/ip -devstyle STYLE_CLONE + service up /usr/sbin/inet -script /etc/rs.inet -dev /dev/ip daemonize dhcpd fi daemonize nonamed -L diff --git a/etc/usr/rc b/etc/usr/rc index 67d51c46e..bde7f08ec 100644 --- a/etc/usr/rc +++ b/etc/usr/rc @@ -188,9 +188,9 @@ start) done if [ X`/bin/sysenv lwip` = Xyes ] then - up lwip -script /etc/rs.inet -dev /dev/ip -devstyle STYLE_CLONE + up lwip -script /etc/rs.inet -dev /dev/ip else - up inet -script /etc/rs.inet -dev /dev/ip -devstyle STYLE_CLONE + up inet -script /etc/rs.inet -dev /dev/ip fi up -n ipc diff --git a/include/minix/com.h b/include/minix/com.h index 2cf810573..c7629f0b6 100644 --- a/include/minix/com.h +++ b/include/minix/com.h @@ -8,8 +8,8 @@ * 1 - 0xFF POSIX requests (see callnr.h) * 0x200 - 0x2FF Data link layer requests and responses * 0x300 - 0x3FF Bus controller requests and responses - * 0x400 - 0x4FF Character device requests - * 0x500 - 0x5FF Character device responses + * 0x400 - 0x4FF Character device requests and responses + * 0x500 - 0x5FF Block device requests and responses * 0x600 - 0x6FF Kernel calls to SYSTEM task * 0x700 - 0x7FF Reincarnation Server (RS) requests * 0x800 - 0x8FF Data Store (DS) requests @@ -25,7 +25,7 @@ * 0x1200 - 0x12FF Devman * 0x1300 - 0x13FF TTY Requests * 0x1400 - 0x14FF VFS-FS transaction IDs - * 0x1500 - 0x15FF Block device requests and responses + * 0x1500 - 0x15FF (unused) * 0x1600 - 0x16FF VirtualBox (VBOX) requests (see vboxif.h) * 0x1700 - 0x17FF Real Time Clock requests and responses * @@ -186,58 +186,6 @@ #define BUSC_I2C_EXEC (BUSC_RQ_BASE + 65) /* perform i2c action */ #define BUSC_I2C_GRANT m2_i1 /* grant for request */ -/*===========================================================================* - * Messages for CHARACTER device drivers * - *===========================================================================*/ - -/* Message types for character device drivers. */ -#define DEV_RQ_BASE 0x400 /* base for character device request types */ -#define DEV_RS_BASE 0x500 /* base for character device response types */ - -#define CANCEL (DEV_RQ_BASE + 0) /* force a task to cancel */ -#define DEV_OPEN (DEV_RQ_BASE + 6) /* open a minor device */ -#define DEV_CLOSE (DEV_RQ_BASE + 7) /* close a minor device */ -#define DEV_SELECT (DEV_RQ_BASE + 12) /* request select() attention */ - -#define DEV_READ_S (DEV_RQ_BASE + 20) /* (safecopy) read from minor */ -#define DEV_WRITE_S (DEV_RQ_BASE + 21) /* (safecopy) write to minor */ -#define DEV_SCATTER_S (DEV_RQ_BASE + 22) /* (safecopy) write from a vector */ -#define DEV_GATHER_S (DEV_RQ_BASE + 23) /* (safecopy) read into a vector */ -#define DEV_IOCTL_S (DEV_RQ_BASE + 24) /* (safecopy) I/O control code */ - -#define IS_DEV_RQ(type) (((type) & ~0xff) == DEV_RQ_BASE) - -#define DEV_REVIVE (DEV_RS_BASE + 2) /* driver revives process */ -#define DEV_CLOSE_REPL (DEV_RS_BASE + 6) /* reply to DEV_CLOSE */ -#define DEV_SEL_REPL1 (DEV_RS_BASE + 7) /* first reply to DEV_SELECT */ -#define DEV_SEL_REPL2 (DEV_RS_BASE + 8) /* (opt) second reply to DEV_SELECT */ -#define DEV_OPEN_REPL (DEV_RS_BASE + 9) /* reply to DEV_OPEN */ - -#define IS_DEV_RS(type) (((type) & ~0xff) == DEV_RS_BASE) - -/* Field names for messages to character device drivers. */ -#define DEVICE m2_i1 /* major-minor device */ -#define USER_ENDPT m2_i2 /* which endpoint initiated this call? */ -#define COUNT m2_i3 /* how many bytes to transfer */ -#define REQUEST m2_i3 /* ioctl request code */ -#define POSITION m2_l1 /* file offset (low 4 bytes) */ -#define HIGHPOS m2_l2 /* file offset (high 4 bytes) */ -#define ADDRESS m2_p1 /* core buffer address */ -#define IO_GRANT m2_p1 /* grant id (for DEV_*_S variants) */ -#define FLAGS m2_s1 /* operation flags */ - -#define FLG_OP_NONBLOCK 0x1 /* operation is non blocking */ - -/* Field names for DEV_SELECT messages to character device drivers. */ -#define DEV_MINOR m2_i1 /* minor device */ -#define DEV_SEL_OPS m2_i2 /* which select operations are requested */ - -/* Field names used in reply messages from tasks. */ -#define REP_ENDPT m2_i1 /* # of proc on whose behalf I/O was done */ -#define REP_STATUS m2_i2 /* bytes transferred or error number */ -#define REP_IO_GRANT m2_i3 /* DEV_REVIVE: grant by which I/O was done */ -# define SUSPEND -998 /* status to suspend caller, reply later */ - /*===========================================================================* * Messages for networking layer * *===========================================================================*/ @@ -939,6 +887,11 @@ #define VFS_PFS_FD m2_i3 #define VFS_PFS_FILP m2_p1 +/* Field names for GETRUSAGE related calls */ +#define RU_ENDPT m1_i1 /* indicates a process for sys_getrusage */ +#define RU_WHO m1_i1 /* who argument in getrusage call */ +#define RU_RUSAGE_ADDR m1_p1 /* pointer to struct rusage */ + /*===========================================================================* * Messages for VM server * *===========================================================================*/ @@ -1298,13 +1251,71 @@ #define VFS_TRANSID (VFS_TRANSACTION_BASE + 1) #define IS_VFS_FS_TRANSID(type) (((type) & ~0xff) == VFS_TRANSACTION_BASE) +/*===========================================================================* + * Messages for character devices * + *===========================================================================*/ + +/* Base type for character device requests and responses. */ +#define CDEV_RQ_BASE 0x400 +#define CDEV_RS_BASE 0x480 + +#define IS_CDEV_RQ(type) (((type) & ~0x7f) == CDEV_RQ_BASE) +#define IS_CDEV_RS(type) (((type) & ~0x7f) == CDEV_RS_BASE) + +/* Message types for character device requests. */ +#define CDEV_OPEN (CDEV_RQ_BASE + 0) /* open a minor device */ +#define CDEV_CLOSE (CDEV_RQ_BASE + 1) /* close a minor device */ +#define CDEV_READ (CDEV_RQ_BASE + 2) /* read into a buffer */ +#define CDEV_WRITE (CDEV_RQ_BASE + 3) /* write from a buffer */ +#define CDEV_IOCTL (CDEV_RQ_BASE + 4) /* I/O control operation */ +#define CDEV_CANCEL (CDEV_RQ_BASE + 5) /* cancel suspended request */ +#define CDEV_SELECT (CDEV_RQ_BASE + 6) /* test for ready operations */ + +/* Message types for character device responses. */ +#define CDEV_REPLY (CDEV_RS_BASE + 0) /* general reply code */ +#define CDEV_SEL1_REPLY (CDEV_RS_BASE + 1) /* immediate select reply */ +#define CDEV_SEL2_REPLY (CDEV_RS_BASE + 2) /* select notification reply */ + +/* Field names for block device messages. */ +#define CDEV_MINOR m10_i1 /* minor device number */ +#define CDEV_STATUS m10_i2 /* OK, error code, minor device, operations */ +#define CDEV_ACCESS m10_i2 /* access bits for open requests */ +#define CDEV_GRANT m10_i2 /* grant ID of buffer */ +#define CDEV_OPS m10_i2 /* requested select operations */ +#define CDEV_COUNT m10_i3 /* number of bytes to transfer */ +#define CDEV_USER m10_i3 /* endpoint of user process */ +#define CDEV_FLAGS m10_i4 /* transfer flags */ +#define CDEV_ID m10_l1 /* opaque request ID */ +#define CDEV_REQUEST m10_l2 /* I/O control request */ +#define CDEV_POS_LO m10_l2 /* transfer position (low bits) */ +#define CDEV_POS_HI m10_l3 /* transfer position (high bits) */ + +/* Bits in 'CDEV_ACCESS' field of block device open requests. */ +# define CDEV_R_BIT 0x01 /* open with read access */ +# define CDEV_W_BIT 0x02 /* open with write access */ +# define CDEV_NOCTTY 0x04 /* not to become the controlling TTY */ + +/* Bits in 'CDEV_FLAGS' field of block device transfer requests. */ +# define CDEV_NOFLAGS 0x00 /* no flags are set */ +# define CDEV_NONBLOCK 0x01 /* do not suspend I/O request */ + +/* Bits in 'CDEV_OPS', 'CDEV_STATUS' fields of block device select messages. */ +# define CDEV_OP_RD 0x01 /* selected for read operation */ +# define CDEV_OP_WR 0x02 /* selected for write operation */ +# define CDEV_OP_ERR 0x04 /* selected for error operation */ +# define CDEV_NOTIFY 0x08 /* notification requested */ + +/* Bits in 'CDEV_STATUS' field of block device open responses. */ +# define CDEV_CLONED 0x20000000 /* device is cloned */ +# define CDEV_CTTY 0x40000000 /* device is controlling TTY */ + /*===========================================================================* * Messages for block devices * *===========================================================================*/ /* Base type for block device requests and responses. */ -#define BDEV_RQ_BASE 0x1500 -#define BDEV_RS_BASE 0x1580 +#define BDEV_RQ_BASE 0x500 +#define BDEV_RS_BASE 0x580 #define IS_BDEV_RQ(type) (((type) & ~0x7f) == BDEV_RQ_BASE) #define IS_BDEV_RS(type) (((type) & ~0x7f) == BDEV_RS_BASE) @@ -1343,11 +1354,6 @@ # define BDEV_FORCEWRITE 0x01 /* force write to disk immediately */ # define BDEV_NOPAGE 0x02 /* eeprom: don't send page address */ -/* Field names for GETRUSAGE related calls */ -#define RU_ENDPT m1_i1 /* indicates a process for sys_getrusage */ -#define RU_WHO m1_i1 /* who argument in getrusage call */ -#define RU_RUSAGE_ADDR m1_p1 /* pointer to struct rusage */ - /*===========================================================================* * Messages for Real Time Clocks * *===========================================================================*/ @@ -1382,4 +1388,10 @@ #define RTCDEV_Y2KBUG 0x01 /* Interpret 1980 as 2000 for RTC w/Y2K bug */ #define RTCDEV_CMOSREG 0x02 /* Also set the CMOS clock register bits. */ +/*===========================================================================* + * Internal codes used by several services * + *===========================================================================*/ + +#define SUSPEND -998 /* status to suspend caller, reply later */ + /* _MINIX_COM_H */ diff --git a/include/minix/dmap.h b/include/minix/dmap.h index 2387267fa..087eac85e 100644 --- a/include/minix/dmap.h +++ b/include/minix/dmap.h @@ -4,8 +4,8 @@ #include #include -enum dev_style { STYLE_NDEV, STYLE_DEV, STYLE_TTY, STYLE_CTTY, STYLE_CLONE }; -#define IS_DEV_STYLE(s) (s>=STYLE_NDEV && s<=STYLE_CLONE) +enum dev_style { STYLE_NDEV, STYLE_DEV, STYLE_TTY, STYLE_CTTY }; +#define IS_DEV_STYLE(s) (s>=STYLE_NDEV && s<=STYLE_CTTY) /*===========================================================================* * Major and minor device numbers * diff --git a/lib/libaudiodriver/audio_fw.c b/lib/libaudiodriver/audio_fw.c index 7dfe03046..d70a92d9b 100644 --- a/lib/libaudiodriver/audio_fw.c +++ b/lib/libaudiodriver/audio_fw.c @@ -5,23 +5,6 @@ * extra buffer space beside the dma buffer. * This driver also support sub devices, which can be independently * opened and closed. - * - * The driver supports the following operations: - * - * m_type DEVICE USER_ENDPT COUNT POSITION ADRRESS - * ----------------------------------------------------------------- - * | DEV_OPEN | device | proc nr | | | | - * |-------------+---------+---------+---------+---------+---------| - * | DEV_CLOSE | device | proc nr | | | | - * |-------------+---------+---------+---------+---------+---------| - * | DEV_READ_S | device | proc nr | bytes | | buf ptr | - * |-------------+---------+---------+---------+---------+---------| - * | DEV_WRITE_S | device | proc nr | bytes | | buf ptr | - * |-------------+---------+---------+---------+---------+---------| - * | DEV_IOCTL_S | device | proc nr |func code| | buf ptr | - * |-------------+---------+---------+---------+---------+---------| - * | HARD_INT | | | | | | - * ----------------------------------------------------------------- * * The file contains one entry point: * diff --git a/lib/libblockdriver/driver.c b/lib/libblockdriver/driver.c index a6c002135..932aa576d 100644 --- a/lib/libblockdriver/driver.c +++ b/lib/libblockdriver/driver.c @@ -369,9 +369,9 @@ static void do_char_open(message *m_ptr, int ipc_status) memset(&m_reply, 0, sizeof(m_reply)); - m_reply.m_type = DEV_OPEN_REPL; - m_reply.REP_ENDPT = m_ptr->USER_ENDPT; - m_reply.REP_STATUS = ENXIO; + m_reply.m_type = CDEV_REPLY; + m_reply.CDEV_STATUS = ENXIO; + m_reply.CDEV_ID = m_ptr->CDEV_ID; send_reply(m_ptr->m_source, &m_reply, ipc_status); } @@ -413,7 +413,7 @@ void blockdriver_process_on_thread(struct blockdriver *bdp, message *m_ptr, * someone creates a character device node for a block driver, opening that * device node will cause the corresponding VFS thread to block forever. */ - if (m_ptr->m_type == DEV_OPEN) { + if (m_ptr->m_type == CDEV_OPEN) { do_char_open(m_ptr, ipc_status); return; diff --git a/lib/libchardriver/chardriver.c b/lib/libchardriver/chardriver.c index cf34dd9f3..03d924537 100644 --- a/lib/libchardriver/chardriver.c +++ b/lib/libchardriver/chardriver.c @@ -1,27 +1,36 @@ /* This file contains the device independent character driver interface. * - * The drivers support the following operations (using message format m2): + * Charaxter drivers support the following requests. Message format m10 is + * used. Field names are prefixed with CDEV_. Separate field names are used for + * the "access", "ops", "user", and "request" fields. * - * m_type DEVICE USER_ENDPT COUNT POSITION HIGHPOS IO_GRANT - * ---------------------------------------------------------------------------- - * | DEV_OPEN | device | proc nr | mode | | | | - * |---------------+--------+---------+---------+--------+--------+-----------| - * | DEV_CLOSE | device | proc nr | | | | | - * |---------------+--------+---------+---------+--------+--------+-----------| - * | DEV_READ_S | device | proc nr | bytes | off lo | off hi i buf grant | - * |---------------+--------+---------+---------+--------+--------+-----------| - * | DEV_WRITE_S | device | proc nr | bytes | off lo | off hi | buf grant | - * |---------------+--------+---------+---------+--------+--------+-----------| - * | DEV_GATHER_S | device | proc nr | iov len | off lo | off hi | iov grant | - * |---------------+--------+---------+---------+--------+--------+-----------| - * | DEV_SCATTER_S | device | proc nr | iov len | off lo | off hi | iov grant | - * |---------------+--------+---------+---------+--------+--------+-----------| - * | DEV_IOCTL_S | device | proc nr | request | | | buf grant | - * |---------------+--------+---------+---------+--------+--------+-----------| - * | CANCEL | device | proc nr | r/w | | | grant | - * |---------------+--------+---------+---------+--------+--------+-----------| - * | DEV_SELECT | device | ops | | | | | - * ---------------------------------------------------------------------------- + * m_type MINOR GRANT COUNT FLAGS ID POS_LO POS_HI + * +-------------+-------+--------+-------+-------+------+---------+--------+ + * | CDEV_OPEN | minor | access | user | | id | | | + * |-------------+-------+--------+-------+-------+------+---------+--------| + * | CDEV_CLOSE | minor | | | | id | | | + * |-------------+-------+--------+-------+-------+------+---------+--------| + * | CDEV_READ | minor | grant | bytes | flags | id | position | + * |-------------+-------+--------+-------+-------+------+---------+--------| + * | CDEV_WRITE | minor | grant | bytes | flags | id | position | + * |-------------+-------+--------+-------+-------+------+---------+--------| + * | CDEV_IOCTL | minor | grant | user | flags | id | request | | + * |-------------+-------+--------+-------+-------+------+---------+--------| + * | CDEV_CANCEL | minor | | | | id | | | + * |-------------+-------+--------+-------+-------+------+---------+--------| + * | CDEV_SELECT | minor | ops | | | | | | + * -------------------------------------------------------------------------- + * + * The following reply messages are used. + * + * m_type MINOR STATUS ID + * +-----------------+-------+--------+-----+-----+------+---------+--------+ + * | CDEV_REPLY | | status | | | id | | | + * |-----------------+-------+--------+-----+-----+------+---------+--------| + * | CDEV_SEL1_REPLY | minor | status | | | | | | + * |-----------------+-------+--------+-----+-----+------+---------+--------| + * | CDEV_SEL2_REPLY | minor | status | | | | | | + * -------------------------------------------------------------------------- * * Changes: * Sep 01, 2013 complete rewrite of the API (D.C. van Moolenboek) @@ -110,7 +119,7 @@ void chardriver_announce(void) if ((r = ds_publish_u32(key, DS_DRIVER_UP, DSF_OVERWRITE)) != OK) panic("chardriver_init: unable to publish driver up event: %d", r); - /* Expect a DEV_OPEN for any device before serving regular driver requests. */ + /* Expect an open for any device before serving regular driver requests. */ clear_open_devs(); } @@ -130,10 +139,9 @@ void chardriver_reply_task(endpoint_t endpt, cdev_id_t id, int r) memset(&m_reply, 0, sizeof(m_reply)); - m_reply.m_type = DEV_REVIVE; - m_reply.REP_STATUS = r; - m_reply.REP_ENDPT = endpt; /* XXX FIXME: hack */ - m_reply.REP_IO_GRANT = (cp_grant_id_t) id; + m_reply.m_type = CDEV_REPLY; + m_reply.CDEV_STATUS = r; + m_reply.CDEV_ID = id; if ((r = asynsend3(endpt, &m_reply, AMF_NOREPLY)) != OK) printf("chardriver_reply_task: send to %d failed: %d\n", endpt, r); @@ -155,9 +163,9 @@ void chardriver_reply_select(endpoint_t endpt, devminor_t minor, int r) memset(&m_reply, 0, sizeof(m_reply)); - m_reply.m_type = DEV_SEL_REPL2; - m_reply.DEV_MINOR = minor; - m_reply.DEV_SEL_OPS = r; + m_reply.m_type = CDEV_SEL2_REPLY; + m_reply.CDEV_MINOR = minor; + m_reply.CDEV_STATUS = r; if ((r = asynsend3(endpt, &m_reply, AMF_NOREPLY)) != OK) printf("chardriver_reply_select: send to %d failed: %d\n", endpt, r); @@ -194,15 +202,20 @@ static void chardriver_reply(message *mess, int ipc_status, int r) */ if (r == EDONTREPLY) { switch (mess->m_type) { - case DEV_READ_S: - case DEV_WRITE_S: - case DEV_IOCTL_S: -#if 0 /* XXX doesn't match lwip's model, disabled for now */ - if (mess->FLAGS & FLG_OP_NONBLOCK) + case CDEV_READ: + case CDEV_WRITE: + case CDEV_IOCTL: + /* FIXME: we should be able to check CDEV_FLAGS against + * CDEV_NONBLOCK here, but in practice, several drivers do not + * send a reply through this path (eg TTY) or simply do not + * implement nonblocking calls properly (eg audio, LWIP). + */ +#if 0 + if (mess->CDEV_FLAGS & CDEV_NONBLOCK) panic("chardriver: cannot suspend nonblocking I/O"); #endif /*fall-through*/ - case CANCEL: + case CDEV_CANCEL: return; /* alright */ default: panic("chardriver: cannot suspend request %d", mess->m_type); @@ -222,32 +235,21 @@ static void chardriver_reply(message *mess, int ipc_status, int r) memset(&reply_mess, 0, sizeof(reply_mess)); switch (mess->m_type) { - case DEV_OPEN: - reply_mess.m_type = DEV_OPEN_REPL; - reply_mess.REP_ENDPT = mess->USER_ENDPT; - reply_mess.REP_STATUS = r; - break; - - case DEV_CLOSE: - reply_mess.m_type = DEV_CLOSE_REPL; - reply_mess.REP_ENDPT = mess->USER_ENDPT; - reply_mess.REP_STATUS = r; + case CDEV_OPEN: + case CDEV_CLOSE: + case CDEV_READ: + case CDEV_WRITE: + case CDEV_IOCTL: + case CDEV_CANCEL: /* For cancel, this is a reply to the original request! */ + reply_mess.m_type = CDEV_REPLY; + reply_mess.CDEV_STATUS = r; + reply_mess.CDEV_ID = mess->CDEV_ID; break; - case DEV_READ_S: - case DEV_WRITE_S: - case DEV_IOCTL_S: - case CANCEL: /* For CANCEL, this is a reply to the original request! */ - reply_mess.m_type = DEV_REVIVE; - reply_mess.REP_ENDPT = mess->USER_ENDPT; - reply_mess.REP_IO_GRANT = (cp_grant_id_t) mess->IO_GRANT; - reply_mess.REP_STATUS = r; - break; - - case DEV_SELECT: - reply_mess.m_type = DEV_SEL_REPL1; - reply_mess.DEV_MINOR = mess->DEVICE; - reply_mess.DEV_SEL_OPS = r; + case CDEV_SELECT: + reply_mess.m_type = CDEV_SEL1_REPLY; + reply_mess.CDEV_MINOR = mess->CDEV_MINOR; + reply_mess.CDEV_STATUS = r; break; default: @@ -272,15 +274,18 @@ static int do_open(struct chardriver *cdp, message *m_ptr) return OK; /* Call the open hook. */ - minor = m_ptr->DEVICE; - access = m_ptr->COUNT; - user_endpt = m_ptr->USER_ENDPT; + minor = m_ptr->CDEV_MINOR; + access = m_ptr->CDEV_ACCESS; + user_endpt = m_ptr->CDEV_USER; r = cdp->cdr_open(minor, access, user_endpt); /* If the device has been cloned, mark the new minor as open too. */ - if (r >= 0 && !is_open_dev(r)) /* XXX FIXME */ - set_open_dev(r); + if (r >= 0 && (r & CDEV_CLONED)) { + minor = r & ~(CDEV_CLONED | CDEV_CTTY); + if (!is_open_dev(minor)) + set_open_dev(minor); + } return r; } @@ -298,7 +303,7 @@ static int do_close(struct chardriver *cdp, message *m_ptr) return OK; /* Call the close hook. */ - minor = m_ptr->DEVICE; + minor = m_ptr->CDEV_MINOR; return cdp->cdr_close(minor); } @@ -318,13 +323,13 @@ static int do_transfer(struct chardriver *cdp, message *m_ptr, int do_write) cdev_id_t id; ssize_t r; - minor = m_ptr->DEVICE; - position = make64(m_ptr->POSITION, m_ptr->HIGHPOS); + minor = m_ptr->CDEV_MINOR; + position = make64(m_ptr->CDEV_POS_LO, m_ptr->CDEV_POS_HI); endpt = m_ptr->m_source; - grant = (cp_grant_id_t) m_ptr->IO_GRANT; - size = m_ptr->COUNT; - flags = m_ptr->FLAGS; - id = (cdev_id_t) m_ptr->IO_GRANT; + grant = (cp_grant_id_t) m_ptr->CDEV_GRANT; + size = m_ptr->CDEV_COUNT; + flags = m_ptr->CDEV_FLAGS; + id = m_ptr->CDEV_ID; /* Call the read/write hook, if the appropriate one is in place. */ if (!do_write && cdp->cdr_read != NULL) @@ -355,13 +360,13 @@ static int do_ioctl(struct chardriver *cdp, message *m_ptr) return ENOTTY; /* Call the ioctl hook. */ - minor = m_ptr->DEVICE; - request = m_ptr->REQUEST; + minor = m_ptr->CDEV_MINOR; + request = m_ptr->CDEV_REQUEST; endpt = m_ptr->m_source; - grant = (cp_grant_id_t) m_ptr->IO_GRANT; - flags = m_ptr->FLAGS; - user_endpt = (endpoint_t) m_ptr->POSITION; - id = (cdev_id_t) m_ptr->IO_GRANT; + grant = m_ptr->CDEV_GRANT; + flags = m_ptr->CDEV_FLAGS; + user_endpt = m_ptr->CDEV_USER; + id = m_ptr->CDEV_ID; return cdp->cdr_ioctl(minor, request, endpt, grant, flags, user_endpt, id); } @@ -383,9 +388,9 @@ static int do_cancel(struct chardriver *cdp, message *m_ptr) return EDONTREPLY; /* Call the cancel hook. */ - minor = m_ptr->DEVICE; + minor = m_ptr->CDEV_MINOR; endpt = m_ptr->m_source; - id = (cdev_id_t) m_ptr->IO_GRANT; + id = m_ptr->CDEV_ID; return cdp->cdr_cancel(minor, endpt, id); } @@ -405,8 +410,8 @@ static int do_select(struct chardriver *cdp, message *m_ptr) return EBADF; /* Call the select hook. */ - minor = m_ptr->DEV_MINOR; - ops = m_ptr->DEV_SEL_OPS; + minor = m_ptr->CDEV_MINOR; + ops = m_ptr->CDEV_OPS; endpt = m_ptr->m_source; return cdp->cdr_select(minor, ops, endpt); @@ -473,24 +478,24 @@ void chardriver_process(struct chardriver *cdp, message *m_ptr, int ipc_status) /* We might get spurious requests if the driver has been restarted. Deny any * requests on devices that have not previously been opened. */ - if (IS_DEV_RQ(m_ptr->m_type) && !is_open_dev(m_ptr->DEVICE)) { + if (IS_CDEV_RQ(m_ptr->m_type) && !is_open_dev(m_ptr->CDEV_MINOR)) { /* Ignore spurious requests for unopened devices. */ - if (m_ptr->m_type != DEV_OPEN) + if (m_ptr->m_type != CDEV_OPEN) return; /* do not send a reply */ /* Mark the device as opened otherwise. */ - set_open_dev(m_ptr->DEVICE); + set_open_dev(m_ptr->CDEV_MINOR); } /* Call the appropriate function(s) for this request. */ switch (m_ptr->m_type) { - case DEV_OPEN: r = do_open(cdp, m_ptr); break; - case DEV_CLOSE: r = do_close(cdp, m_ptr); break; - case DEV_READ_S: r = do_transfer(cdp, m_ptr, FALSE); break; - case DEV_WRITE_S: r = do_transfer(cdp, m_ptr, TRUE); break; - case DEV_IOCTL_S: r = do_ioctl(cdp, m_ptr); break; - case CANCEL: r = do_cancel(cdp, m_ptr); break; - case DEV_SELECT: r = do_select(cdp, m_ptr); break; + case CDEV_OPEN: r = do_open(cdp, m_ptr); break; + case CDEV_CLOSE: r = do_close(cdp, m_ptr); break; + case CDEV_READ: r = do_transfer(cdp, m_ptr, FALSE); break; + case CDEV_WRITE: r = do_transfer(cdp, m_ptr, TRUE); break; + case CDEV_IOCTL: r = do_ioctl(cdp, m_ptr); break; + case CDEV_CANCEL: r = do_cancel(cdp, m_ptr); break; + case CDEV_SELECT: r = do_select(cdp, m_ptr); break; default: if (cdp->cdr_other) cdp->cdr_other(m_ptr, ipc_status); diff --git a/lib/libnetsock/socket.c b/lib/libnetsock/socket.c index 912e94f15..bef626ec7 100644 --- a/lib/libnetsock/socket.c +++ b/lib/libnetsock/socket.c @@ -261,7 +261,7 @@ struct socket * get_unused_sock(void) static int socket_request_socket(struct socket * sock, struct sock_req * req) { - int r, blocking = req->flags & FLG_OP_NONBLOCK ? 0 : 1; + int r, blocking = (req->flags & CDEV_NONBLOCK) ? 0 : 1; switch (req->type) { case SOCK_REQ_READ: @@ -292,7 +292,12 @@ static int socket_request_socket(struct socket * sock, struct sock_req * req) static int netsock_open(devminor_t minor, int UNUSED(access), endpoint_t UNUSED(user_endpt)) { - return socket_open(minor); + int r; + + if ((r = socket_open(minor)) < 0) + return r; + + return CDEV_CLONED | r; } static int netsock_close(devminor_t minor) @@ -505,26 +510,26 @@ int generic_op_select(struct socket * sock, unsigned int sel) /* in this case any operation would block, no error */ if (sock->flags & SOCK_FLG_OP_PENDING) { - if (sel & SEL_NOTIFY) { - if (sel & SEL_RD) + if (sel & CDEV_NOTIFY) { + if (sel & CDEV_OP_RD) sock->flags |= SOCK_FLG_SEL_READ; - if (sel & SEL_WR) + if (sel & CDEV_OP_WR) sock->flags |= SOCK_FLG_SEL_WRITE; /* FIXME we do not monitor error */ } return 0; } - if (sel & SEL_RD) { + if (sel & CDEV_OP_RD) { if (sock->recv_head) - retsel |= SEL_RD; - else if (sel & SEL_NOTIFY) + retsel |= CDEV_OP_RD; + else if (sel & CDEV_NOTIFY) sock->flags |= SOCK_FLG_SEL_READ; } /* FIXME generic packet socket never blocks on write */ - if (sel & SEL_WR) - retsel |= SEL_WR; - /* FIXME SEL_ERR is ignored, we do not generate exceptions */ + if (sel & CDEV_OP_WR) + retsel |= CDEV_OP_WR; + /* FIXME CDEV_OP_ERR is ignored, we do not generate exceptions */ return retsel; } @@ -545,7 +550,7 @@ int generic_op_select_reply(struct socket * sock) } if (sock->flags & SOCK_FLG_SEL_READ && sock->recv_head) - sel |= SEL_RD; + sel |= CDEV_OP_RD; if (sel) sock->flags &= ~(SOCK_FLG_SEL_WRITE | SOCK_FLG_SEL_READ | diff --git a/servers/inet/sr.c b/servers/inet/sr.c index c6694231c..fc94f43df 100644 --- a/servers/inet/sr.c +++ b/servers/inet/sr.c @@ -146,7 +146,7 @@ static int sr_open(devminor_t minor, int UNUSED(access), return fd; } sr_fd->srf_fd= fd; - return i; /* cloned! */ + return CDEV_CLONED | i; } static int sr_close(devminor_t minor) @@ -214,7 +214,7 @@ static int sr_rwio(sr_req_t *req) assert(sr_fd->srf_flags & susp_flag); assert(*q_head_ptr); - if (m->mq_req.srr_flags & FLG_OP_NONBLOCK) { + if (m->mq_req.srr_flags & CDEV_NONBLOCK) { mq_free(m); return EAGAIN; } @@ -264,7 +264,7 @@ static int sr_rwio(sr_req_t *req) (printf("r= %d\n", r), 0)); if (r == SUSPEND) { sr_fd->srf_flags |= susp_flag; - if (m->mq_req.srr_flags & FLG_OP_NONBLOCK) { + if (m->mq_req.srr_flags & CDEV_NONBLOCK) { r= sr_cancel(m->mq_req.srr_minor, m->mq_req.srr_endpt, m->mq_req.srr_id); assert(r == EDONTREPLY); /* head of the queue */ @@ -442,19 +442,19 @@ static int sr_select(devminor_t minor, unsigned int ops, endpoint_t endpt) sr_fd->srf_select_proc= endpt; i_ops= 0; - if (ops & SEL_RD) i_ops |= SR_SELECT_READ; - if (ops & SEL_WR) i_ops |= SR_SELECT_WRITE; - if (ops & SEL_ERR) i_ops |= SR_SELECT_EXCEPTION; - if (!(ops & SEL_NOTIFY)) i_ops |= SR_SELECT_POLL; + if (ops & CDEV_OP_RD) i_ops |= SR_SELECT_READ; + if (ops & CDEV_OP_WR) i_ops |= SR_SELECT_WRITE; + if (ops & CDEV_OP_ERR) i_ops |= SR_SELECT_EXCEPTION; + if (!(ops & CDEV_NOTIFY)) i_ops |= SR_SELECT_POLL; r= (*sr_fd->srf_select)(sr_fd->srf_fd, i_ops); if (r < 0) { m_ops= r; } else { m_ops= 0; - if (r & SR_SELECT_READ) m_ops |= SEL_RD; - if (r & SR_SELECT_WRITE) m_ops |= SEL_WR; - if (r & SR_SELECT_EXCEPTION) m_ops |= SEL_ERR; + if (r & SR_SELECT_READ) m_ops |= CDEV_OP_RD; + if (r & SR_SELECT_WRITE) m_ops |= CDEV_OP_WR; + if (r & SR_SELECT_EXCEPTION) m_ops |= CDEV_OP_ERR; } return m_ops; @@ -657,9 +657,9 @@ static void sr_select_res(int fd, unsigned ops) sr_fd= &sr_fd_table[fd]; m_ops= 0; - if (ops & SR_SELECT_READ) m_ops |= SEL_RD; - if (ops & SR_SELECT_WRITE) m_ops |= SEL_WR; - if (ops & SR_SELECT_EXCEPTION) m_ops |= SEL_ERR; + if (ops & SR_SELECT_READ) m_ops |= CDEV_OP_RD; + if (ops & SR_SELECT_WRITE) m_ops |= CDEV_OP_WR; + if (ops & SR_SELECT_EXCEPTION) m_ops |= CDEV_OP_ERR; chardriver_reply_select(sr_fd->srf_select_proc, fd, m_ops); } diff --git a/servers/is/dmp_fs.c b/servers/is/dmp_fs.c index b12bfb268..1230235cd 100644 --- a/servers/is/dmp_fs.c +++ b/servers/is/dmp_fs.c @@ -76,7 +76,6 @@ static char * dmap_style(int dev_style) case STYLE_DEV: return "STYLE_DEV"; case STYLE_TTY: return "STYLE_TTY"; case STYLE_CTTY: return "STYLE_CTTY"; - case STYLE_CLONE: return "STYLE_CLONE"; default: return "UNKNOWN"; } } diff --git a/servers/lwip/tcp.c b/servers/lwip/tcp.c index 0d636fcee..7d0cea26f 100644 --- a/servers/lwip/tcp.c +++ b/servers/lwip/tcp.c @@ -1082,22 +1082,22 @@ static int tcp_op_select(struct socket * sock, unsigned int sel) /* in this case any operation would block, no error */ if (sock->flags & SOCK_FLG_OP_PENDING) { debug_tcp_print("SOCK_FLG_OP_PENDING"); - if (sel & SEL_NOTIFY) { - if (sel & SEL_RD) { + if (sel & CDEV_NOTIFY) { + if (sel & CDEV_OP_RD) { sock->flags |= SOCK_FLG_SEL_READ; debug_tcp_print("monitor read"); } - if (sel & SEL_WR) { + if (sel & CDEV_OP_WR) { sock->flags |= SOCK_FLG_SEL_WRITE; debug_tcp_print("monitor write"); } - if (sel & SEL_ERR) + if (sel & CDEV_OP_ERR) sock->flags |= SOCK_FLG_SEL_ERROR; } return 0; } - if (sel & SEL_RD) { + if (sel & CDEV_OP_RD) { /* * If recv_head is not NULL we can either read or accept a * connection which is the same for select() @@ -1105,38 +1105,38 @@ static int tcp_op_select(struct socket * sock, unsigned int sel) if (sock->pcb) { if (sock->recv_head && !(sock->flags & SOCK_FLG_OP_WRITING)) - retsel |= SEL_RD; + retsel |= CDEV_OP_RD; else if (!(sock->flags & SOCK_FLG_OP_LISTENING) && ((struct tcp_pcb *) sock->pcb)->state != ESTABLISHED) - retsel |= SEL_RD; - else if (sel & SEL_NOTIFY) { + retsel |= CDEV_OP_RD; + else if (sel & CDEV_NOTIFY) { sock->flags |= SOCK_FLG_SEL_READ; debug_tcp_print("monitor read"); } - } else - retsel |= SEL_RD; /* not connected read does not block */ + } else /* not connected read does not block */ + retsel |= CDEV_OP_RD; } - if (sel & SEL_WR) { + if (sel & CDEV_OP_WR) { if (sock->pcb) { if (((struct tcp_pcb *) sock->pcb)->state == ESTABLISHED) - retsel |= SEL_WR; - else if (sel & SEL_NOTIFY) { + retsel |= CDEV_OP_WR; + else if (sel & CDEV_NOTIFY) { sock->flags |= SOCK_FLG_SEL_WRITE; debug_tcp_print("monitor write"); } - } else - retsel |= SEL_WR; /* not connected write does not block */ + } else /* not connected write does not block */ + retsel |= CDEV_OP_WR; } - if (retsel & SEL_RD) { + if (retsel & CDEV_OP_RD) { debug_tcp_print("read won't block"); } - if (retsel & SEL_WR) { + if (retsel & CDEV_OP_WR) { debug_tcp_print("write won't block"); } /* we only monitor if errors will happen in the future */ - if (sel & SEL_ERR && sel & SEL_NOTIFY) + if (sel & CDEV_OP_ERR && sel & CDEV_NOTIFY) sock->flags |= SOCK_FLG_SEL_ERROR; return retsel; @@ -1160,7 +1160,7 @@ static int tcp_op_select_reply(struct socket * sock) (!(sock->flags & SOCK_FLG_OP_LISTENING) && ((struct tcp_pcb *) sock->pcb)->state != ESTABLISHED)) { - sel |= SEL_RD; + sel |= CDEV_OP_RD; debug_tcp_print("read won't block"); } } @@ -1169,7 +1169,7 @@ static int tcp_op_select_reply(struct socket * sock) (sock->pcb == NULL || ((struct tcp_pcb *) sock->pcb)->state == ESTABLISHED)) { - sel |= SEL_WR; + sel |= CDEV_OP_WR; debug_tcp_print("write won't block"); } diff --git a/servers/pfs/dev_uds.c b/servers/pfs/dev_uds.c index 0caba400c..ead39a4f1 100644 --- a/servers/pfs/dev_uds.c +++ b/servers/pfs/dev_uds.c @@ -12,10 +12,9 @@ * * Overview * - * The interface to unix domain sockets is similar to the - * the interface to network sockets. There is a character - * device (/dev/uds) that uses STYLE_CLONE and this server - * is a 'driver' for that device. + * The interface to unix domain sockets is similar to the interface to network + * sockets. There is a character device (/dev/uds) and this server is a + * 'driver' for that device. */ #define DEBUG 0 @@ -190,7 +189,7 @@ static int uds_open(devminor_t UNUSED(orig_minor), int access, /* Process the response */ uds_fd_table[minor].inode_nr = fs_m_out.RES_INODE_NR; - return minor; /* cloned! */ + return CDEV_CLONED | minor; } static int uds_close(devminor_t minor) @@ -271,40 +270,40 @@ static int uds_select(devminor_t minor, unsigned int ops, endpoint_t endpt) return EINVAL; } - watch = (ops & SEL_NOTIFY); - ops &= (SEL_RD | SEL_WR | SEL_ERR); + watch = (ops & CDEV_NOTIFY); + ops &= (CDEV_OP_RD | CDEV_OP_WR | CDEV_OP_ERR); ready_ops = 0; /* check if there is data available to read */ - if (ops & SEL_RD) { + if (ops & CDEV_OP_RD) { bytes = uds_perform_read(minor, NONE, GRANT_INVALID, 1, 1); if (bytes > 0) { /* there is data in the pipe for us to read */ - ready_ops |= SEL_RD; + ready_ops |= CDEV_OP_RD; } else if (uds_fd_table[minor].listening == 1) { /* check for pending connections */ for (i = 0; i < uds_fd_table[minor].backlog_size; i++) { if (uds_fd_table[minor].backlog[i] != -1) { - ready_ops |= SEL_RD; + ready_ops |= CDEV_OP_RD; break; } } } else if (bytes != SUSPEND) { - ready_ops |= SEL_RD; + ready_ops |= CDEV_OP_RD; } } /* check if we can write without blocking */ - if (ops & SEL_WR) { + if (ops & CDEV_OP_WR) { bytes = uds_perform_write(minor, NONE, GRANT_INVALID, PIPE_BUF, 1); if (bytes != 0 && bytes != SUSPEND) { /* There is room to write or there is an error * condition. */ - ready_ops |= SEL_WR; + ready_ops |= CDEV_OP_WR; } } @@ -439,12 +438,12 @@ static ssize_t uds_perform_read(devminor_t minor, endpoint_t endpt, * peer to minor); if the peer wants to know about write being possible * and it doesn't know about it already, then let the peer know. */ - if (peer != -1 && (uds_fd_table[peer].sel_ops & SEL_WR) && + if (peer != -1 && (uds_fd_table[peer].sel_ops & CDEV_OP_WR) && (uds_fd_table[minor].size+uds_fd_table[minor].pos + 1 < PIPE_BUF)){ /* a write on peer is possible now */ chardriver_reply_select(uds_fd_table[peer].sel_endpt, peer, - SEL_WR); - uds_fd_table[peer].sel_ops &= ~SEL_WR; + CDEV_OP_WR); + uds_fd_table[peer].sel_ops &= ~CDEV_OP_WR; } return fs_m_out.RES_NBYTES; /* return number of bytes read */ @@ -604,11 +603,12 @@ static ssize_t uds_perform_write(devminor_t minor, endpoint_t endpt, * data ready to read and it doesn't know about it already, then let * the peer know we have data for it. */ - if ((uds_fd_table[peer].sel_ops & SEL_RD) && fs_m_out.RES_NBYTES > 0) { + if ((uds_fd_table[peer].sel_ops & CDEV_OP_RD) && + fs_m_out.RES_NBYTES > 0) { /* a read on peer is possible now */ chardriver_reply_select(uds_fd_table[peer].sel_endpt, peer, - SEL_RD); - uds_fd_table[peer].sel_ops &= ~SEL_RD; + CDEV_OP_RD); + uds_fd_table[peer].sel_ops &= ~CDEV_OP_RD; } return fs_m_out.RES_NBYTES; /* return number of bytes written */ @@ -644,7 +644,7 @@ static ssize_t uds_read(devminor_t minor, u64_t position, endpoint_t endpt, uds_fd_table[minor].susp_id = id; /* If the call wasn't supposed to block, cancel immediately. */ - if (flags & FLG_OP_NONBLOCK) { + if (flags & CDEV_NONBLOCK) { uds_cancel(minor, endpt, id); rc = EAGAIN; @@ -684,7 +684,7 @@ static ssize_t uds_write(devminor_t minor, u64_t position, endpoint_t endpt, uds_fd_table[minor].susp_id = id; /* If the call wasn't supposed to block, cancel immediately. */ - if (flags & FLG_OP_NONBLOCK) { + if (flags & CDEV_NONBLOCK) { uds_cancel(minor, endpt, id); rc = EAGAIN; @@ -730,7 +730,7 @@ static int uds_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt, uds_fd_table[minor].susp_id = id; /* If the call wasn't supposed to block, cancel immediately. */ - if (flags & FLG_OP_NONBLOCK) { + if (flags & CDEV_NONBLOCK) { uds_cancel(minor, endpt, id); rc = EAGAIN; diff --git a/servers/pfs/main.c b/servers/pfs/main.c index 72b987597..b605b092b 100644 --- a/servers/pfs/main.c +++ b/servers/pfs/main.c @@ -42,7 +42,7 @@ int main(int argc, char *argv[]) get_work(&pfs_m_in, &ipc_status); /* If this is a UDS device request, process it and continue. */ - if (IS_DEV_RQ(pfs_m_in.m_type)) { + if (IS_CDEV_RQ(pfs_m_in.m_type)) { uds_request(&pfs_m_in, ipc_status); continue; diff --git a/servers/pfs/uds.c b/servers/pfs/uds.c index f4800d590..76aa7b518 100644 --- a/servers/pfs/uds.c +++ b/servers/pfs/uds.c @@ -464,7 +464,7 @@ static int do_connect(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant) } /* see if the server is blocked on select() */ - if (uds_fd_table[i].sel_ops & SEL_RD) { + if (uds_fd_table[i].sel_ops & CDEV_OP_RD) { /* if the server wants to know about * data ready to read and it doesn't * doesn't know about it already, then @@ -473,9 +473,9 @@ static int do_connect(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant) */ chardriver_reply_select( uds_fd_table[i].sel_endpt, i, - SEL_RD); + CDEV_OP_RD); - uds_fd_table[i].sel_ops &= ~SEL_RD; + uds_fd_table[i].sel_ops &= ~CDEV_OP_RD; } /* we found our server */ diff --git a/servers/pfs/uds.h b/servers/pfs/uds.h index cc51efdcc..88ce88718 100644 --- a/servers/pfs/uds.h +++ b/servers/pfs/uds.h @@ -179,7 +179,7 @@ struct uds_fd { */ endpoint_t sel_endpt; - /* Options (SEL_RD, SEL_WR, SEL_ERR) that are requested. */ + /* Options (CDEV_OP_RD,WR,ERR) that are requested. */ unsigned int sel_ops; }; diff --git a/servers/rs/table.c b/servers/rs/table.c index 80595dcb1..9ac5c4bee 100644 --- a/servers/rs/table.c +++ b/servers/rs/table.c @@ -48,7 +48,7 @@ struct boot_image_dev boot_image_dev_table[] = { { TTY_PROC_NR, SRV_DF, TTY_MAJOR, STYLE_TTY, STYLE_CTTY }, { MEM_PROC_NR, SRV_DF, MEMORY_MAJOR, STYLE_DEV, STYLE_NDEV }, { LOG_PROC_NR, SRV_DF, LOG_MAJOR, STYLE_DEV, STYLE_NDEV }, - { PFS_PROC_NR, SRV_DF, UDS_MAJOR, STYLE_CLONE,STYLE_NDEV }, + { PFS_PROC_NR, SRV_DF, UDS_MAJOR, STYLE_DEV, STYLE_NDEV }, { DEFAULT_BOOT_NR, SRV_DF, 0, STYLE_NDEV, STYLE_NDEV } /* default * entry */ diff --git a/servers/vfs/comm.c b/servers/vfs/comm.c index 9e8ab8a74..840c96785 100644 --- a/servers/vfs/comm.c +++ b/servers/vfs/comm.c @@ -93,7 +93,7 @@ int drv_sendrec(endpoint_t drv_e, message *reqmp) panic("driver endpoint %d invalid", drv_e); lock_dmap(dp); - if (dp->dmap_servicing != NONE) + if (dp->dmap_servicing != INVALID_THREAD) panic("driver locking inconsistency"); dp->dmap_servicing = self->w_tid; self->w_task = drv_e; @@ -108,7 +108,7 @@ int drv_sendrec(endpoint_t drv_e, message *reqmp) util_stacktrace(); } - dp->dmap_servicing = NONE; + dp->dmap_servicing = INVALID_THREAD; self->w_task = NONE; self->w_drv_sendrec = NULL; unlock_dmap(dp); diff --git a/servers/vfs/const.h b/servers/vfs/const.h index 56731d2ca..bb5bdcaac 100644 --- a/servers/vfs/const.h +++ b/servers/vfs/const.h @@ -26,14 +26,7 @@ /* test if the process is blocked on something */ #define fp_is_blocked(fp) ((fp)->fp_blocked_on != FP_BLOCKED_ON_NONE) -/* test if reply is a driver reply */ -#define IS_DRV_REPLY(x) (IS_DEV_RS(x) || IS_BDEV_RS(x)) -#define DUP_MASK 0100 /* mask to distinguish dup2 from dup */ - -#define LOOK_UP 0 /* tells search_dir to lookup string */ -#define ENTER 1 /* tells search_dir to make dir entry */ -#define DELETE 2 /* tells search_dir to delete entry */ -#define IS_EMPTY 3 /* tells search_dir to ret. OK or ENOTEMPTY */ +#define INVALID_THREAD ((thread_t) -1) /* known-invalid thread ID */ #define SYMLOOP 16 @@ -43,4 +36,10 @@ */ #define FSTYPE_MAX VFS_NAMELEN /* maximum file system type size */ +/* possible select() operation types; read, write, errors */ +#define SEL_RD CDEV_OP_RD +#define SEL_WR CDEV_OP_WR +#define SEL_ERR CDEV_OP_ERR +#define SEL_NOTIFY CDEV_NOTIFY /* not a real select operation */ + #endif diff --git a/servers/vfs/device.c b/servers/vfs/device.c index dd498529b..1e446fe1f 100644 --- a/servers/vfs/device.c +++ b/servers/vfs/device.c @@ -2,24 +2,25 @@ * Special character files also require I/O. The routines for these are here. * * The entry points in this file are: - * dev_open: open a character device - * dev_close: close a character device - * cdev_reply: process the result of a character driver request - * bdev_open: open a block device - * bdev_close: close a block device - * bdev_reply: process the result of a block driver request - * dev_io: FS does a read or write on a device - * gen_opcl: generic call to a character driver to perform an open/close - * gen_io: generic call to a character driver to initiate I/O - * no_dev: open/close processing for devices that don't exist - * no_dev_io: i/o processing for devices that don't exist - * tty_opcl: perform tty-specific processing for open/close - * ctty_opcl: perform controlling-tty-specific processing for open/close - * ctty_io: perform controlling-tty-specific processing for I/O - * pm_setsid: perform VFS's side of setsid system call - * do_ioctl: perform the IOCTL system call - * dev_select: initiate a select call on a device - * dev_cancel: cancel an I/O request, blocking until it has been cancelled + * cdev_open: open a character device + * cdev_close: close a character device + * cdev_io: initiate a read, write, or ioctl to a character device + * cdev_select: initiate a select call on a device + * cdev_cancel: cancel an I/O request, blocking until it has been cancelled + * cdev_reply: process the result of a character driver request + * bdev_open: open a block device + * bdev_close: close a block device + * bdev_reply: process the result of a block driver request + * bdev_up: a block driver has been mapped in + * gen_opcl: generic call to a character driver to perform an open/close + * gen_io: generic call to a character driver to initiate I/O + * no_dev: open/close processing for devices that don't exist + * no_dev_io: i/o processing for devices that don't exist + * tty_opcl: perform tty-specific processing for open/close + * ctty_opcl: perform controlling-tty-specific processing for open/close + * ctty_io: perform controlling-tty-specific processing for I/O + * pm_setsid: perform VFS's side of setsid system call + * do_ioctl: perform the IOCTL system call */ #include "fs.h" @@ -44,15 +45,10 @@ static int block_io(endpoint_t driver_e, message *mess_ptr); static cp_grant_id_t make_grant(endpoint_t driver_e, endpoint_t user_e, int op, void *buf, unsigned long size); -static int dummyproc; - /*===========================================================================* - * dev_open * + * cdev_open * *===========================================================================*/ -int dev_open( - dev_t dev, /* device to open */ - int flags /* mode bits and flags */ -) +int cdev_open(dev_t dev, int flags) { /* Open a character device. */ devmajor_t major_dev; @@ -65,17 +61,15 @@ int dev_open( major_dev = major(dev); if (major_dev < 0 || major_dev >= NR_DEVICES) return(ENXIO); if (dmap[major_dev].dmap_driver == NONE) return(ENXIO); - r = (*dmap[major_dev].dmap_opcl)(DEV_OPEN, dev, fp->fp_endpoint, flags); + r = (*dmap[major_dev].dmap_opcl)(CDEV_OPEN, dev, fp->fp_endpoint, flags); return(r); } /*===========================================================================* - * dev_close * + * cdev_close * *===========================================================================*/ -int dev_close( - dev_t dev /* device to close */ -) +int cdev_close(dev_t dev) { /* Close a character device. */ devmajor_t major_dev; @@ -85,7 +79,7 @@ int dev_close( major_dev = major(dev); if (major_dev < 0 || major_dev >= NR_DEVICES) return(ENXIO); if (dmap[major_dev].dmap_driver == NONE) return(ENXIO); - r = (*dmap[major_dev].dmap_opcl)(DEV_CLOSE, dev, fp->fp_endpoint, 0); + r = (*dmap[major_dev].dmap_opcl)(CDEV_CLOSE, dev, fp->fp_endpoint, 0); return(r); } @@ -204,30 +198,6 @@ static int bdev_ioctl(dev_t dev, endpoint_t proc_e, unsigned long req, } -/*===========================================================================* - * find_suspended_ep * - *===========================================================================*/ -static endpoint_t find_suspended_ep(endpoint_t driver, cp_grant_id_t g) -{ -/* A process is suspended on a driver for which VFS issued a grant. Find out - * which process it was. - */ - struct fproc *rfp; - for (rfp = &fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) { - if(rfp->fp_pid == PID_FREE) - continue; - - if (rfp->fp_task == driver && rfp->fp_grant == g) { - assert(!fp_is_blocked(rfp) || - rfp->fp_blocked_on == FP_BLOCKED_ON_OTHER); - return(rfp->fp_endpoint); - } - } - - return(NONE); -} - - /*===========================================================================* * make_grant * *===========================================================================*/ @@ -240,13 +210,13 @@ static cp_grant_id_t make_grant(endpoint_t driver_e, endpoint_t user_e, int op, size_t size; switch (op) { - case DEV_READ_S: - case DEV_WRITE_S: + case CDEV_READ: + case CDEV_WRITE: gid = cpf_grant_magic(driver_e, user_e, (vir_bytes) buf, - (size_t) bytes, op == DEV_READ_S ? CPF_WRITE : CPF_READ); + (size_t) bytes, op == CDEV_READ ? CPF_WRITE : CPF_READ); break; - case DEV_IOCTL_S: + case CDEV_IOCTL: case BDEV_IOCTL: /* For IOCTLs, the bytes parameter contains the IOCTL request. * This request encodes the requested access method and buffer size. @@ -259,8 +229,9 @@ static cp_grant_id_t make_grant(endpoint_t driver_e, endpoint_t user_e, int op, else size = _MINIX_IOCTL_SIZE(bytes); - /* Grant access to the buffer even if no I/O happens with the ioctl, in - * order to disambiguate requests with DEV_IOCTL_S. + /* Grant access to the buffer even if no I/O happens with the ioctl, + * although now that we no longer identify responses based on grants, + * this is not strictly necessary. */ gid = cpf_grant_magic(driver_e, user_e, (vir_bytes) buf, size, access); break; @@ -277,27 +248,27 @@ static cp_grant_id_t make_grant(endpoint_t driver_e, endpoint_t user_e, int op, /*===========================================================================* - * dev_io * + * cdev_io * *===========================================================================*/ -int dev_io( - int op, /* DEV_READ_S, DEV_WRITE_S, or DEV_IOCTL_S */ +int cdev_io( + int op, /* CDEV_READ, CDEV_WRITE, or CDEV_IOCTL */ dev_t dev, /* major-minor device number */ endpoint_t proc_e, /* in whose address space is buf? */ void *buf, /* virtual address of the buffer */ off_t pos, /* byte position */ - size_t bytes, /* how many bytes to transfer */ + unsigned long bytes, /* how many bytes to transfer, or request */ int flags /* special flags, like O_NONBLOCK */ ) { -/* Initiate a read, write, or ioctl to a device. */ +/* Initiate a read, write, or ioctl to a character device. */ struct dmap *dp; message dev_mess; cp_grant_id_t gid; devmajor_t major_dev; devminor_t minor_dev; - int r; + int r, slot; - assert(op == DEV_READ_S || op == DEV_WRITE_S || op == DEV_IOCTL_S); + assert(op == CDEV_READ || op == CDEV_WRITE || op == CDEV_IOCTL); /* Determine task dmap. */ major_dev = major(dev); @@ -307,7 +278,7 @@ int dev_io( /* See if driver is roughly valid. */ if (dp->dmap_driver == NONE) return(ENXIO); - if(isokendpt(dp->dmap_driver, &dummyproc) != OK) { + if(isokendpt(dp->dmap_driver, &slot) != OK) { printf("VFS: dev_io: old driver for major %x (%d)\n", major_dev, dp->dmap_driver); return(ENXIO); @@ -318,21 +289,21 @@ int dev_io( /* Set up the rest of the message that will be sent to the driver. */ memset(&dev_mess, 0, sizeof(dev_mess)); - dev_mess.m_type = op; - dev_mess.DEVICE = minor_dev; - if (op == DEV_IOCTL_S) { - dev_mess.REQUEST = bytes; - dev_mess.POSITION = proc_e; + dev_mess.m_type = op; + dev_mess.CDEV_MINOR = minor_dev; + if (op == CDEV_IOCTL) { + dev_mess.CDEV_REQUEST = bytes; + dev_mess.CDEV_USER = proc_e; } else { - dev_mess.POSITION = ex64lo(pos); - dev_mess.COUNT = bytes; + dev_mess.CDEV_POS_LO = ex64lo(pos); + dev_mess.CDEV_POS_HI = ex64hi(pos); + dev_mess.CDEV_COUNT = (size_t) bytes; } - dev_mess.HIGHPOS = ex64hi(pos); - dev_mess.USER_ENDPT = VFS_PROC_NR; - dev_mess.IO_GRANT = (void *) gid; - dev_mess.FLAGS = 0; + dev_mess.CDEV_ID = proc_e; + dev_mess.CDEV_GRANT = gid; + dev_mess.CDEV_FLAGS = 0; if (flags & O_NONBLOCK) - dev_mess.FLAGS |= FLG_OP_NONBLOCK; + dev_mess.CDEV_FLAGS |= CDEV_NONBLOCK; /* Send the request to the driver. */ r = (*dp->dmap_io)(dp->dmap_driver, &dev_mess); @@ -347,7 +318,6 @@ int dev_io( wait_for(dp->dmap_driver); assert(!GRANT_VALID(fp->fp_grant)); fp->fp_grant = gid; /* revoke this when unsuspended. */ - fp->fp_ioproc = VFS_PROC_NR; return SUSPEND; } @@ -374,14 +344,14 @@ static int cdev_clone(dev_t dev, endpoint_t proc_e, devminor_t new_minor) r = req_newnode(PFS_PROC_NR, fp->fp_effuid, fp->fp_effgid, ALL_MODES | I_CHAR_SPECIAL, dev, &res); if (r != OK) { - (void) gen_opcl(DEV_CLOSE, dev, proc_e, 0); + (void) gen_opcl(CDEV_CLOSE, dev, proc_e, 0); return r; } /* Drop old node and use the new values */ if ((vp = get_free_vnode()) == NULL) { req_putnode(PFS_PROC_NR, res.inode_nr, 1); /* is this right? */ - (void) gen_opcl(DEV_CLOSE, dev, proc_e, 0); + (void) gen_opcl(CDEV_CLOSE, dev, proc_e, 0); return(err_code); } lock_vnode(vp, VNODE_OPCL); @@ -409,7 +379,7 @@ static int cdev_clone(dev_t dev, endpoint_t proc_e, devminor_t new_minor) * gen_opcl * *===========================================================================*/ int gen_opcl( - int op, /* operation, DEV_OPEN or DEV_CLOSE */ + int op, /* operation, CDEV_OPEN or CDEV_CLOSE */ dev_t dev, /* device to open or close */ endpoint_t proc_e, /* process to open/close for */ int flags /* mode bits and flags */ @@ -417,10 +387,10 @@ int gen_opcl( { /* Called from the dmap struct on opens & closes of special files.*/ devmajor_t major_dev; - devminor_t minor_dev; + devminor_t minor_dev, new_minor; struct dmap *dp; message dev_mess; - int r; + int r, r2; /* Determine task dmap. */ major_dev = major(dev); @@ -435,9 +405,15 @@ int gen_opcl( memset(&dev_mess, 0, sizeof(dev_mess)); dev_mess.m_type = op; - dev_mess.DEVICE = minor_dev; - dev_mess.USER_ENDPT = proc_e; - dev_mess.COUNT = flags; + dev_mess.CDEV_MINOR = minor_dev; + dev_mess.CDEV_ID = proc_e; + if (op == CDEV_OPEN) { + dev_mess.CDEV_USER = proc_e; + dev_mess.CDEV_ACCESS = 0; + if (flags & R_BIT) dev_mess.CDEV_ACCESS |= CDEV_R_BIT; + if (flags & W_BIT) dev_mess.CDEV_ACCESS |= CDEV_W_BIT; + if (flags & O_NOCTTY) dev_mess.CDEV_ACCESS |= CDEV_NOCTTY; + } /* Call the task. */ r = (*dp->dmap_io)(dp->dmap_driver, &dev_mess); @@ -454,15 +430,33 @@ int gen_opcl( self->w_task = NONE; self->w_drv_sendrec = NULL; + r = dev_mess.CDEV_STATUS; + + /* Some devices need special processing upon open. Such a device is "cloned", + * i.e. on a succesful open it is replaced by a new device with a new unique + * minor device number. This new device number identifies a new object (such + * as a new network connection) that has been allocated within a task. + */ + if (op == CDEV_OPEN && r >= 0) { + if (r & CDEV_CLONED) { + new_minor = r & ~(CDEV_CLONED | CDEV_CTTY); + r &= CDEV_CTTY; + if ((r2 = cdev_clone(dev, proc_e, new_minor)) < 0) + r = r2; + } else + r &= CDEV_CTTY; + /* Upon success, we now return either OK or CDEV_CTTY. */ + } + /* Return the result from the driver. */ - return(dev_mess.REP_STATUS); + return(r); } /*===========================================================================* * tty_opcl * *===========================================================================*/ int tty_opcl( - int op, /* operation, DEV_OPEN or DEV_CLOSE */ + int op, /* operation, CDEV_OPEN or CDEV_CLOSE */ dev_t dev, /* device to open or close */ endpoint_t proc_e, /* process to open/close for */ int flags /* mode bits and flags */ @@ -490,7 +484,7 @@ int tty_opcl( r = gen_opcl(op, dev, proc_e, flags); /* Did this call make the tty the controlling tty? */ - if (r == 1) { + if (r >= 0 && (r & CDEV_CTTY)) { fp->fp_tty = dev; r = OK; } @@ -503,7 +497,7 @@ int tty_opcl( * ctty_opcl * *===========================================================================*/ int ctty_opcl( - int op, /* operation, DEV_OPEN or DEV_CLOSE */ + int op, /* operation, CDEV_OPEN or CDEV_CLOSE */ dev_t UNUSED(dev), /* device to open or close */ endpoint_t UNUSED(proc_e), /* process to open/close for */ int UNUSED(flags) /* mode bits and flags */ @@ -569,8 +563,8 @@ int do_ioctl(message *UNUSED(m_out)) if (S_ISBLK(vp->v_mode)) r = bdev_ioctl(dev, who_e, ioctlrequest, argx); else - r = dev_io(DEV_IOCTL_S, dev, who_e, argx, 0, - ioctlrequest, f->filp_flags); + r = cdev_io(CDEV_IOCTL, dev, who_e, argx, 0, ioctlrequest, + f->filp_flags); } unlock_filp(f); @@ -580,9 +574,9 @@ int do_ioctl(message *UNUSED(m_out)) /*===========================================================================* - * dev_select * + * cdev_select * *===========================================================================*/ -int dev_select(dev_t dev, int ops) +int cdev_select(dev_t dev, int ops) { /* Initiate a select call on a device. Return OK iff the request was sent. */ devmajor_t major_dev; @@ -598,9 +592,9 @@ int dev_select(dev_t dev, int ops) memset(&dev_mess, 0, sizeof(dev_mess)); - dev_mess.m_type = DEV_SELECT; - dev_mess.DEV_MINOR = minor_dev; - dev_mess.DEV_SEL_OPS = ops; + dev_mess.m_type = CDEV_SELECT; + dev_mess.CDEV_MINOR = minor_dev; + dev_mess.CDEV_OPS = ops; /* Call the task. */ return (*dp->dmap_io)(dp->dmap_driver, &dev_mess); @@ -608,9 +602,9 @@ int dev_select(dev_t dev, int ops) /*===========================================================================* - * dev_cancel * + * cdev_cancel * *===========================================================================*/ -int dev_cancel(dev_t dev) +int cdev_cancel(dev_t dev) { /* Cancel an I/O request, blocking until it has been cancelled. */ devmajor_t major_dev; @@ -625,14 +619,9 @@ int dev_cancel(dev_t dev) memset(&dev_mess, 0, sizeof(dev_mess)); - dev_mess.m_type = CANCEL; - dev_mess.DEVICE = minor_dev; - dev_mess.USER_ENDPT = fp->fp_ioproc; - dev_mess.IO_GRANT = (char *) fp->fp_grant; - - /* Tell driver R or W. Mode is from current call, not open. */ - /* FIXME: ioctls also pass through here! */ - dev_mess.COUNT = fp->fp_block_callnr == READ ? R_BIT : W_BIT; + dev_mess.m_type = CDEV_CANCEL; + dev_mess.CDEV_MINOR = minor_dev; + dev_mess.CDEV_ID = fp->fp_endpoint; r = (*dp->dmap_io)(fp->fp_task, &dev_mess); if (r != OK) return r; /* ctty_io returned an error? should be impossible */ @@ -653,7 +642,7 @@ int dev_cancel(dev_t dev) fp->fp_grant = GRANT_INVALID; } - r = dev_mess.REP_STATUS; + r = dev_mess.CDEV_STATUS; return (r == EAGAIN) ? EINTR : r; } @@ -721,8 +710,6 @@ int gen_io(endpoint_t drv_e, message *mess_ptr) if (r != OK) panic("VFS: asynsend in gen_io failed: %d", r); - /* Fake a SUSPEND */ - mess_ptr->REP_STATUS = SUSPEND; return(OK); } @@ -740,6 +727,7 @@ int ctty_io( * major/minor pair for /dev/tty itself. */ struct dmap *dp; + int slot; if (fp->fp_tty == 0) { /* No controlling tty present anymore, return an I/O error. */ @@ -747,14 +735,14 @@ int ctty_io( } else { /* Substitute the controlling terminal device. */ dp = &dmap[major(fp->fp_tty)]; - mess_ptr->DEVICE = minor(fp->fp_tty); + mess_ptr->CDEV_MINOR = minor(fp->fp_tty); if (dp->dmap_driver == NONE) { printf("FS: ctty_io: no driver for dev\n"); return(EIO); } - if (isokendpt(dp->dmap_driver, &dummyproc) != OK) { + if (isokendpt(dp->dmap_driver, &slot) != OK) { printf("VFS: ctty_io: old driver %d\n", dp->dmap_driver); return(EIO); } @@ -768,7 +756,7 @@ int ctty_io( * no_dev * *===========================================================================*/ int no_dev( - int UNUSED(op), /* operation, DEV_OPEN or DEV_CLOSE */ + int UNUSED(op), /* operation, CDEV_OPEN or CDEV_CLOSE */ dev_t UNUSED(dev), /* device to open or close */ endpoint_t UNUSED(proc), /* process to open/close for */ int UNUSED(flags) /* mode bits and flags */ @@ -788,35 +776,6 @@ int no_dev_io(endpoint_t UNUSED(proc), message *UNUSED(m)) return(EIO); } -/*===========================================================================* - * clone_opcl * - *===========================================================================*/ -int clone_opcl( - int op, /* operation, DEV_OPEN or DEV_CLOSE */ - dev_t dev, /* device to open or close */ - endpoint_t proc_e, /* process to open/close for */ - int flags /* mode bits and flags */ -) -{ -/* Some devices need special processing upon open. Such a device is "cloned", - * i.e. on a succesful open it is replaced by a new device with a new unique - * minor device number. This new device number identifies a new object (such - * as a new network connection) that has been allocated within a task. - */ - int r; - - r = gen_opcl(op, dev, proc_e, flags); - - if (op == DEV_OPEN && r >= 0) { - if (r != minor(dev)) - r = cdev_clone(dev, proc_e, r); - else - r = OK; - } - - return r; -} - /*===========================================================================* * bdev_up * @@ -881,74 +840,46 @@ void bdev_up(devmajor_t maj) /*===========================================================================* - * opcl_reply * + * cdev_generic_reply * *===========================================================================*/ -static void opcl_reply(message *m_ptr) +static void cdev_generic_reply(message *m_ptr) { -/* A character driver has replied to an open or close request. This function - * MUST NOT block its calling thread. +/* A character driver has results for an open, close, read, write, or ioctl + * call (i.e., everything except select). There may be a thread waiting for + * these results as part of an ongoing open, close, or (for read/write/ioctl) + * cancel call. If so, wake up that thread; if not, send a reply to the + * requesting process. This function MUST NOT block its calling thread. */ struct fproc *rfp; struct worker_thread *wp; endpoint_t proc_e; int slot; - proc_e = m_ptr->REP_ENDPT; - if (isokendpt(proc_e, &slot) != OK) return; - rfp = &fproc[slot]; - wp = rfp->fp_worker; - if (wp == NULL || wp->w_task != who_e) { - printf("VFS: no worker thread waiting for a reply from %d\n", who_e); + proc_e = m_ptr->CDEV_ID; + + if (m_ptr->CDEV_STATUS == SUSPEND) { + printf("VFS: got SUSPEND from %d, not reviving\n", m_ptr->m_source); return; } - *wp->w_drv_sendrec = *m_ptr; - worker_signal(wp); /* Continue open/close */ -} - - -/*===========================================================================* - * task_reply * - *===========================================================================*/ -static void task_reply(message *m_ptr) -{ -/* A character driver has results for a read, write, or ioctl call. There may - * be a thread waiting for these results as part of an ongoing dev_cancel call. - * If so, wake up that thread; if not, send a reply to the requesting process. - * This function MUST NOT block its calling thread. - */ - struct fproc *rfp; - struct worker_thread *wp; - endpoint_t proc_e; - int slot; - proc_e = m_ptr->REP_ENDPT; - if (proc_e == VFS_PROC_NR) - proc_e = find_suspended_ep(m_ptr->m_source, m_ptr->REP_IO_GRANT); - else - printf("VFS: endpoint %u from %u is not VFS\n", - proc_e, m_ptr->m_source); - - if (proc_e == NONE) { - printf("VFS: proc with grant %d from %d not found\n", - m_ptr->REP_IO_GRANT, m_ptr->m_source); - } else if (m_ptr->REP_STATUS == SUSPEND) { - printf("VFS: got SUSPEND on DEV_REVIVE: not reviving proc\n"); - } else { - /* If there is a thread active for this process, we assume that this - * thread aims to cancel the ongoing operation. In that case, wake up - * the thread to let it finish unpausing the process. Otherwise, revive - * the process as usual. + if (isokendpt(proc_e, &slot) != OK) { + printf("VFS: proc %d from %d not found\n", proc_e, m_ptr->m_source); + return; + } + rfp = &fproc[slot]; + wp = rfp->fp_worker; + if (wp != NULL && wp->w_task == who_e) { + assert(!fp_is_blocked(rfp)); + *wp->w_drv_sendrec = *m_ptr; + worker_signal(wp); /* Continue open/close/cancel */ + } else if (rfp->fp_blocked_on != FP_BLOCKED_ON_OTHER || + rfp->fp_task != m_ptr->m_source) { + /* This would typically be caused by a protocol error, i.e. a driver + * not properly following the character driver protocol rules. */ - if (isokendpt(proc_e, &slot) != OK) return; - rfp = &fproc[slot]; - wp = rfp->fp_worker; - if (wp != NULL && wp->w_task == who_e) { - assert(!fp_is_blocked(rfp)); - *wp->w_drv_sendrec = *m_ptr; - worker_signal(wp); /* Continue cancel */ - } else { - revive(proc_e, m_ptr->REP_STATUS); - } + printf("VFS: proc %d not blocked on %d\n", proc_e, m_ptr->m_source); + } else { + revive(proc_e, m_ptr->CDEV_STATUS); } } @@ -960,15 +891,20 @@ void cdev_reply(void) { /* A character driver has results for us. */ + if (get_dmap(who_e) == NULL) { + printf("VFS: ignoring char dev reply from unknown driver %d\n", who_e); + return; + } + switch (call_nr) { - case DEV_OPEN_REPL: - case DEV_CLOSE_REPL: opcl_reply(&m_in); break; - case DEV_REVIVE: task_reply(&m_in); break; - case DEV_SEL_REPL1: - select_reply1(m_in.m_source, m_in.DEV_MINOR, m_in.DEV_SEL_OPS); + case CDEV_REPLY: + cdev_generic_reply(&m_in); + break; + case CDEV_SEL1_REPLY: + select_reply1(m_in.m_source, m_in.CDEV_MINOR, m_in.CDEV_STATUS); break; - case DEV_SEL_REPL2: - select_reply2(m_in.m_source, m_in.DEV_MINOR, m_in.DEV_SEL_OPS); + case CDEV_SEL2_REPLY: + select_reply2(m_in.m_source, m_in.CDEV_MINOR, m_in.CDEV_STATUS); break; default: printf("VFS: char driver %u sent unknown reply %x\n", who_e, call_nr); @@ -979,15 +915,24 @@ void cdev_reply(void) /*===========================================================================* * bdev_reply * *===========================================================================*/ -void bdev_reply(struct dmap *dp) +void bdev_reply(void) { /* A block driver has results for a call. There must be a thread waiting for * these results - wake it up. This function MUST NOT block its calling thread. */ struct worker_thread *wp; + struct dmap *dp; - assert(dp != NULL); - assert(dp->dmap_servicing != NONE); + if ((dp = get_dmap(who_e)) == NULL) { + printf("VFS: ignoring block dev reply from unknown driver %d\n", + who_e); + return; + } + + if (dp->dmap_servicing == INVALID_THREAD) { + printf("VFS: ignoring spurious block dev reply from %d\n", who_e); + return; + } wp = worker_get(dp->dmap_servicing); if (wp == NULL || wp->w_task != who_e) { diff --git a/servers/vfs/dmap.c b/servers/vfs/dmap.c index 54d071754..0221aacb8 100644 --- a/servers/vfs/dmap.c +++ b/servers/vfs/dmap.c @@ -182,9 +182,6 @@ int flags; /* device flags */ dp->dmap_opcl = ctty_opcl; dp->dmap_io = ctty_io; break; - case STYLE_CLONE: - dp->dmap_opcl = clone_opcl; - dp->dmap_io = gen_io; break; default: return(EINVAL); @@ -281,7 +278,7 @@ void init_dmap() dmap[i].dmap_io = no_dev_io; dmap[i].dmap_driver = NONE; dmap[i].dmap_style = STYLE_NDEV; - dmap[i].dmap_servicing = NONE; + dmap[i].dmap_servicing = INVALID_THREAD; } } @@ -344,7 +341,7 @@ void dmap_endpt_up(endpoint_t proc_e, int is_blk) if (dp->dmap_recovering) { printf("VFS: driver recovery failure for" " major %d\n", major); - if (dp->dmap_servicing != NONE) { + if (dp->dmap_servicing != INVALID_THREAD) { worker = worker_get(dp->dmap_servicing); worker_stop(worker); } @@ -355,7 +352,7 @@ void dmap_endpt_up(endpoint_t proc_e, int is_blk) bdev_up(major); dp->dmap_recovering = 0; } else { - if (dp->dmap_servicing != NONE) { + if (dp->dmap_servicing != INVALID_THREAD) { worker = worker_get(dp->dmap_servicing); worker_stop(worker); } diff --git a/servers/vfs/dmap.h b/servers/vfs/dmap.h index 4520d577f..959ecb070 100644 --- a/servers/vfs/dmap.h +++ b/servers/vfs/dmap.h @@ -22,7 +22,7 @@ extern struct dmap { int dmap_style; int dmap_sel_busy; struct filp *dmap_sel_filp; - endpoint_t dmap_servicing; + thread_t dmap_servicing; mutex_t dmap_lock; mutex_t *dmap_lock_ref; int dmap_recovering; diff --git a/servers/vfs/filedes.c b/servers/vfs/filedes.c index 571abaf2c..3167fc01a 100644 --- a/servers/vfs/filedes.c +++ b/servers/vfs/filedes.c @@ -579,7 +579,7 @@ struct filp *f; (void) bdev_close(dev); /* Ignore errors */ } else { - (void) dev_close(dev); /* Ignore errors */ + (void) cdev_close(dev); /* Ignore errors */ } f->filp_mode = FILP_CLOSED; diff --git a/servers/vfs/fproc.h b/servers/vfs/fproc.h index 097bcfaae..1831236ff 100644 --- a/servers/vfs/fproc.h +++ b/servers/vfs/fproc.h @@ -29,8 +29,6 @@ EXTERN struct fproc { int fp_block_callnr; /* blocked call if rd/wr can't finish */ int fp_cum_io_partial; /* partial byte count if rd/wr can't finish */ endpoint_t fp_task; /* which task is proc suspended on */ - endpoint_t fp_ioproc; /* proc no. in suspended-on i/o message */ - cp_grant_id_t fp_grant; /* revoke this grant on unsuspend if > -1 */ uid_t fp_realuid; /* real user id */ diff --git a/servers/vfs/main.c b/servers/vfs/main.c index 56374d78c..619d9839a 100644 --- a/servers/vfs/main.c +++ b/servers/vfs/main.c @@ -124,36 +124,14 @@ int main(void) continue; } - /* At this point we either have results from an asynchronous device - * or a new system call. In both cases a new worker thread has to be - * started and there might not be one available from the pool. This is - * not a problem (requests/replies are simply queued), except when - * they're from an FS endpoint, because these can cause a deadlock. - * handle_work() takes care of the details. */ - if (IS_DRV_REPLY(call_nr)) { - /* We've got results for a device request */ - - struct dmap *dp; - - dp = get_dmap(who_e); - if (dp != NULL) { - if (!IS_BDEV_RS(call_nr)) { - cdev_reply(); - - } else { - if (dp->dmap_servicing == NONE) { - printf("Got spurious dev reply from %d", - who_e); - } else { - bdev_reply(dp); - } - } - continue; - } - printf("VFS: ignoring dev reply from unknown driver %d\n", - who_e); + if (IS_BDEV_RS(call_nr)) { + /* We've got results for a block device request. */ + bdev_reply(); + } else if (IS_CDEV_RS(call_nr)) { + /* We've got results for a character device request. */ + cdev_reply(); } else { - /* Normal syscall. */ + /* Normal syscall. This spawns a new thread. */ handle_work(do_work); } } diff --git a/servers/vfs/misc.c b/servers/vfs/misc.c index 449b366e6..b8cc97778 100644 --- a/servers/vfs/misc.c +++ b/servers/vfs/misc.c @@ -659,7 +659,7 @@ static void free_proc(int flags) if (!S_ISCHR(vp->v_mode)) continue; if ((dev_t) vp->v_sdev != dev) continue; lock_filp(rfilp, VNODE_READ); - (void) dev_close(dev); /* Ignore any errors. */ + (void) cdev_close(dev); /* Ignore any errors. */ rfilp->filp_mode = FILP_CLOSED; unlock_filp(rfilp); diff --git a/servers/vfs/open.c b/servers/vfs/open.c index 2beb489f6..cd8f79375 100644 --- a/servers/vfs/open.c +++ b/servers/vfs/open.c @@ -156,9 +156,9 @@ int common_open(char path[PATH_MAX], int oflags, mode_t omode) /* Invoke the driver for special processing. */ dev = (dev_t) vp->v_sdev; /* TTY needs to know about the O_NOCTTY flag. */ - r = dev_open(dev, bits | (oflags & O_NOCTTY)); + r = cdev_open(dev, bits | (oflags & O_NOCTTY)); vp = filp->filp_vno; /* Might be updated by - * dev_open/clone_opcl */ + * cdev_open after cloning */ break; case S_IFBLK: diff --git a/servers/vfs/pipe.c b/servers/vfs/pipe.c index 88da3ef7c..e21536e06 100644 --- a/servers/vfs/pipe.c +++ b/servers/vfs/pipe.c @@ -527,7 +527,7 @@ void unpause(void) blocked_on = fp->fp_blocked_on; /* Clear the block status now. The procedure below might make blocking calls - * and it is imperative that while at least dev_cancel() is executing, other + * and it is imperative that while at least cdev_cancel() is executing, other * parts of VFS do not perceive this process as blocked on something. */ fp->fp_blocked_on = FP_BLOCKED_ON_NONE; @@ -573,7 +573,7 @@ void unpause(void) } dev = (dev_t) f->filp_vno->v_sdev; /* device hung on */ - status = dev_cancel(dev); + status = cdev_cancel(dev); break; default : diff --git a/servers/vfs/proto.h b/servers/vfs/proto.h index d989429e5..25df2dce4 100644 --- a/servers/vfs/proto.h +++ b/servers/vfs/proto.h @@ -29,14 +29,17 @@ void fs_sendmore(struct vmnt *vmp); void send_work(void); /* device.c */ -int dev_open(dev_t dev, int flags); -int dev_close(dev_t dev); +int cdev_open(dev_t dev, int flags); +int cdev_close(dev_t dev); +int cdev_io(int op, dev_t dev, endpoint_t proc_e, void *buf, off_t pos, + unsigned long bytes, int flags); +int cdev_select(dev_t dev, int ops); +int cdev_cancel(dev_t dev); void cdev_reply(void); int bdev_open(dev_t dev, int access); int bdev_close(dev_t dev); -void bdev_reply(struct dmap *dp); -int dev_io(int op, dev_t dev, endpoint_t proc_e, void *buf, off_t pos, - size_t bytes, int flags); +void bdev_reply(void); +void bdev_up(int major); int gen_opcl(int op, dev_t dev, endpoint_t task_nr, int flags); int gen_io(endpoint_t drv_e, message *mess_ptr); int no_dev(int op, dev_t dev, endpoint_t proc, int flags); @@ -46,10 +49,7 @@ int ctty_opcl(int op, dev_t dev, endpoint_t proc, int flags); int clone_opcl(int op, dev_t dev, endpoint_t proc, int flags); int ctty_io(endpoint_t task_nr, message *mess_ptr); int do_ioctl(message *m_out); -int dev_select(dev_t dev, int ops); -int dev_cancel(dev_t dev); void pm_setsid(endpoint_t proc_e); -void bdev_up(int major); /* dmap.c */ void lock_dmap(struct dmap *dp); diff --git a/servers/vfs/read.c b/servers/vfs/read.c index 1a43d4ad9..436c591c1 100644 --- a/servers/vfs/read.c +++ b/servers/vfs/read.c @@ -137,6 +137,7 @@ int read_write(struct fproc *rfp, int rw_flag, struct filp *f, off_t position, res_pos; unsigned int cum_io, cum_io_incr, res_cum_io; int op, r; + dev_t dev; position = f->filp_pos; vp = f->filp_vno; @@ -147,7 +148,7 @@ int read_write(struct fproc *rfp, int rw_flag, struct filp *f, if (size > SSIZE_MAX) return(EINVAL); - op = (rw_flag == READING ? DEV_READ_S : DEV_WRITE_S); + op = (rw_flag == READING ? CDEV_READ : CDEV_WRITE); if (S_ISFIFO(vp->v_mode)) { /* Pipes */ if (rfp->fp_cum_io_partial != 0) { @@ -159,9 +160,6 @@ int read_write(struct fproc *rfp, int rw_flag, struct filp *f, } r = rw_pipe(rw_flag, for_e, f, buf, size); } else if (S_ISCHR(vp->v_mode)) { /* Character special files. */ - dev_t dev; - int op = (rw_flag == READING ? DEV_READ_S : DEV_WRITE_S); - if(rw_flag == PEEKING) { printf("read_write: peek on char device makes no sense\n"); return EINVAL; @@ -172,7 +170,7 @@ int read_write(struct fproc *rfp, int rw_flag, struct filp *f, dev = (dev_t) vp->v_sdev; - r = dev_io(op, dev, for_e, buf, position, size, f->filp_flags); + r = cdev_io(op, dev, for_e, buf, position, size, f->filp_flags); if (r >= 0) { /* This should no longer happen: all calls are asynchronous. */ printf("VFS: I/O to device %x succeeded immediately!?\n", dev); diff --git a/servers/vfs/select.c b/servers/vfs/select.c index 22f3c555a..e831afc28 100644 --- a/servers/vfs/select.c +++ b/servers/vfs/select.c @@ -406,7 +406,7 @@ static int select_request_char(struct filp *f, int *ops, int block) return(SUSPEND); f->filp_select_flags &= ~FSF_UPDATE; - r = dev_select(f->filp_vno->v_sdev, rops); + r = cdev_select(f->filp_vno->v_sdev, rops); if (r != OK) return(r); @@ -719,7 +719,7 @@ void select_timeout_check(timer_t *timer) if (se->requestor == NULL) return; if (se->expiry <= 0) return; /* Strange, did we even ask for a timeout? */ se->expiry = 0; - if (is_deferred(se)) return; /* Wait for initial replies to DEV_SELECT */ + if (is_deferred(se)) return; /* Wait for initial replies to CDEV_SELECT */ select_return(se); } @@ -771,7 +771,7 @@ endpoint_t driver_e; int minor; int status; { -/* Handle the initial reply to DEV_SELECT request. This function MUST NOT +/* Handle the initial reply to CDEV_SELECT request. This function MUST NOT * block its calling thread. */ int major; @@ -788,7 +788,7 @@ int status; /* Get filp belonging to character special file */ if (!dp->dmap_sel_busy) { - printf("VFS (%s:%d): major %d was not expecting a DEV_SELECT reply\n", + printf("VFS (%s:%d): major %d was not expecting a CDEV_SELECT reply\n", __FILE__, __LINE__, major); return; } diff --git a/sys/sys/select.h b/sys/sys/select.h index fa9d1b4b4..57925821e 100644 --- a/sys/sys/select.h +++ b/sys/sys/select.h @@ -75,13 +75,4 @@ int select(int, fd_set * __restrict, fd_set * __restrict, __END_DECLS #endif /* _KERNEL */ -#if defined(__minix) && defined(_NETBSD_SOURCE) -/* possible select() operation types; read, write, errors */ -/* (FS/driver internal use only) */ -#define SEL_RD (1 << 0) -#define SEL_WR (1 << 1) -#define SEL_ERR (1 << 2) -#define SEL_NOTIFY (1 << 3) /* not a real select operation */ -#endif /* defined(__minix) && defined(_NETBSD_SOURCE) */ - #endif /* !_SYS_SELECT_H_ */ -- 2.44.0