]> Zhao Yanbai Git Server - minix.git/commitdiff
Rewrite character driver protocol 79/979/2
authorDavid van Moolenbroek <david@minix3.org>
Tue, 10 Sep 2013 18:25:01 +0000 (20:25 +0200)
committerLionel Sambuc <lionel@minix3.org>
Sat, 1 Mar 2014 08:04:52 +0000 (09:04 +0100)
As a side effect, remove the clone style, as the normal device style
supports device cloning now.

Change-Id: Ie82d1ef0385514a04a8faa139129a617895780b5

38 files changed:
commands/service/service.c
drivers/log/log.c
drivers/printer/printer.c
drivers/tty/arch/i386/keyboard.c
drivers/tty/pty.c
drivers/tty/tty.c
drivers/tty/tty.h
etc/rs.inet
etc/usr/rc
include/minix/com.h
include/minix/dmap.h
lib/libaudiodriver/audio_fw.c
lib/libblockdriver/driver.c
lib/libchardriver/chardriver.c
lib/libnetsock/socket.c
servers/inet/sr.c
servers/is/dmp_fs.c
servers/lwip/tcp.c
servers/pfs/dev_uds.c
servers/pfs/main.c
servers/pfs/uds.c
servers/pfs/uds.h
servers/rs/table.c
servers/vfs/comm.c
servers/vfs/const.h
servers/vfs/device.c
servers/vfs/dmap.c
servers/vfs/dmap.h
servers/vfs/filedes.c
servers/vfs/fproc.h
servers/vfs/main.c
servers/vfs/misc.c
servers/vfs/open.c
servers/vfs/pipe.c
servers/vfs/proto.h
servers/vfs/read.c
servers/vfs/select.c
sys/sys/select.h

index 0d504cf79d1352238764e16f2c16a86ba1e41b29..b20b65a148b0ef9949926f76ad5b527b4a2038e8 100644 (file)
@@ -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;
index 67c4660533883f3bae06054c1b92b9a739f6c51e..45b5e620dfaad0a7cc0e12afa627dec4ca6603c1 100644 (file)
@@ -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
index 6b75aadd15c0ea941d6e246387bc990a93da993c..47abec2387bc4591236bb97cfcdbd32231a15886 100644 (file)
@@ -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.
index 3b601da3366172d55c03db4d264af6a0ad95eca8..60e98378da617fa2ff71debd02d2150574bdc18a 100644 (file)
@@ -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]);
                        }
                }
index f59de63747f747f9fecac1ab4310d2469417decc..2a16fd074667356fbcb9b5bb13450b57b137ddab 100644 (file)
@@ -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);
 
index 5bcc05b7fe15e10cb3b7d2ae4e5547e197c5a1ff..cd61f21e7d706169f3dd35f8d3db85ccd5db573d 100644 (file)
  * 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);
 
index baca8dcc3c19794656b29ba86620242a189ca6af..f83a980f765629f99b0e7ec43fd39e0db12e2813 100644 (file)
@@ -25,9 +25,6 @@
 
 #define ESC             '\33'  /* escape */
 
-#define O_NOCTTY       00400   /* from <fcntl.h>, 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);
index 8eb1529a070863c4cd2a5554450294dd1d38fe82..b4bc3c840896791a51fa444f246041cad8dd1510 100755 (executable)
@@ -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
index 67d51c46ebd5a1ed7ef2ecd854e4e25a69419640..bde7f08ec62abb3bdf1c25d7e31c07d9a2bbe9fa 100644 (file)
@@ -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
index 2cf8105736eae4f4267bcff84fa6e575f994bb48..c7629f0b637d24f32de771ccf52c2388b10175ae 100644 (file)
@@ -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
  *
 #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                     *
  *===========================================================================*/
 #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                                    *
  *===========================================================================*/
 #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)
 #  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                        *
  *===========================================================================*/
 #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 */
index 2387267fa2a197957eb5edec5d40446d0e961d5a..087eac85e4bdee23b84a0fe3d02d08f874480e78 100644 (file)
@@ -4,8 +4,8 @@
 #include <minix/sys_config.h>
 #include <minix/ipc.h>
 
-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                      *
index 7dfe0304665739db0b18b599fca979950def2309..d70a92d9b6c76f29af273e053481146a9d70dfac 100644 (file)
@@ -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:
  *
index a6c0021354675d2af5ac3f4544d2c96fd87ec4ff..932aa576dd8849bc3917a089cd941d463cbba351 100644 (file)
@@ -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;
index cf34dd9f3a4909b82bba2d36a4ef5a646effadd0..03d924537ccc732c3005d75c8ea698def1b5c300 100644 (file)
@@ -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);
index 912e94f15c9fbbb64d71a0f9bf3a06ba58e11b8a..bef626ec76b3f329e7e8e8895096843a3be36c65 100644 (file)
@@ -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 |
index c6694231ce85f311d83d561af339c5317e7b2962..fc94f43df2fbedf1cf13f77b2adbf86e42cf144f 100644 (file)
@@ -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);
 }
index b12bfb26850648c082a328dca57af9d9001c5b1d..1230235cdcf265985ad9774f0f8921fb6dd1a3c3 100644 (file)
@@ -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";
        }
 }
index 0d636fcee00f1901fb01a3726cf1fe3362ebef9b..7d0cea26ff45d7621f3c89871cd05225a9889da1 100644 (file)
@@ -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");
        }
 
index 0caba400cb8274178561959a60cdbd746941a251..ead39a4f1cbd3bbb1e8a4b8b435177d155b7914e 100644 (file)
  *
  * 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;
index 72b987597b5f191c1906b8e27c8910404005004e..b605b092b39d20bd62bdec9ba1066f4d619768b2 100644 (file)
@@ -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;
index f4800d590b164be54172a0324549553883a1ae1c..76aa7b518ee4032b968add90b067085aba96e438 100644 (file)
@@ -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 */
index cc51efdcc99bd388278687a0b8e7f55509db02a7..88ce88718e70b8f256823d0fcb1d31110519d742 100644 (file)
@@ -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;
 };
 
index 80595dcb1320729962772a5da0930b720cae0a04..9ac5c4bee2ea6ee997f4e3eadb8a528c83c7be59 100644 (file)
@@ -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
                                                                       */
index 9e8ab8a7446cd4f03a259977d7c3a834f80a45b2..840c96785a2e4c3763dbfd08dbbf257493760de9 100644 (file)
@@ -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);
index 56731d2ca69111e4af83c16a173be6e27b82f8ae..bb5bdcaac092d7714d2603c54dfe20f54852c7e2 100644 (file)
 /* 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
 
                                 */
 #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
index dd498529b0395c8348ae63256b769872bd41a0fa..1e446fe1fd256cb8cee24b853568a02b47eeccc3 100644 (file)
@@ -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) {
index 54d071754e7c8aac19fb8b722a8dac160e32f54f..0221aacb8ef422bb8bf9bed87cbaa84473458a32 100644 (file)
@@ -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);
                        }
index 4520d577fd4e4568a13d507d0727c315fd7a1e25..959ecb0702977629099022d4ef1ecceace06795a 100644 (file)
@@ -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;
index 571abaf2c1da3820b68b1719049555089754fede..3167fc01ae2c7d895d25868205f37a2449cdd12b 100644 (file)
@@ -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;
index 097bcfaae4eeeb5329a34eade636c7541517a7f2..1831236ff6f7a00f152c6d3d01cd672fab4e6c5b 100644 (file)
@@ -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 */
index 56374d78c0d561c133234ba18761cbbd7bd85d86..619d9839a29d2e6bff87283a462c53d91f52cc08 100644 (file)
@@ -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);
        }
   }
index 449b366e6040b9347943411c662689232bdd6b0f..b8cc977781dbf7da3e44e4df3afa663160a1b9b0 100644 (file)
@@ -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);
index 2beb489f6dbe37e9cd523b28de01870106135fe6..cd8f79375670eefa29158e03882618c14cb9325b 100644 (file)
@@ -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:
 
index 88da3ef7c5a953ccf2a31de000ce0165accddacd..e21536e06be03d0744320493512978b6a3e4a3e1 100644 (file)
@@ -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 :
index d989429e5c0054628ad9b9570f6611b81304daec..25df2dce45ed131a84fc91bc055dbe70359ed657 100644 (file)
@@ -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);
index 1a43d4ad9b3789e3671fa00333f9b07507c62d68..436c591c11e0959052d13f8d3a949b97d3a46d17 100644 (file)
@@ -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);
index 22f3c555a88cf45820d6b288af7b95b2582275ca..e831afc28f7a698af555694f1e8f8b5a659f0b04 100644 (file)
@@ -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;
   }
index fa9d1b4b413aee1794026873c1a74c67653219bd..57925821efb1ddb431271f9aec054dc3d2ef91fa 100644 (file)
@@ -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_ */