Convert omode to 9p for devmnt [4/7]
[akaros.git] / kern / include / ns.h
index 545778d..ed4f386 100644 (file)
-//INFERNO
-#pragma src "/usr/inferno/lib9"
-#pragma        lib     "libc.a"
+// INFERNO
+
+#ifndef ROS_KERN_NS_H
+#define ROS_KERN_NS_H
+
+#include <err.h>
+#include <rendez.h>
+#include <rwlock.h>
+#include <linker_func.h>
+#include <fdtap.h>
+
+/*
+ * functions (possibly) linked in, complete, from libc.
+ */
+enum {
+       UTFmax = 4,                                     /* maximum bytes per rune */
+       Runesync = 0x80,        /* cannot represent part of a UTF sequence (<) */
+       Runeself = 0x80,        /* rune and UTF sequences are the same (<) */
+       Runeerror = 0xFFFD,     /* decoding error in UTF */
+       Runemax = 0x10FFFF,     /* 21-bit rune */
+       Runemask = 0x1FFFFF,    /* bits used by runes (see grep) */
+       NUMSIZE32 = 9,  /* max size of formatted 32 bit number */
+       NUMSIZE64 = 20, /* max size of formatted 64 bit number */
+};
+
+/*
+ * math
+ */
+extern int isNaN(double);
+extern int isInf(double, int);
+extern double floor(double);
+extern double frexp(double, int *);
+extern double pow10(int);
+
+/*
+ * one-of-a-kind
+ */
+extern char *cleanname(char *unused_char_p_t);
+//extern    uint32_t    getcallerpc(void*);
+static inline uint32_t getcallerpc(void *v)
+{
+       return 0;
+}
+
+extern char etext[];
+extern char edata[];
+extern char end[];
+extern int getfields(char *unused_char_p_t, char **unused_char_pp_t,
+                                        int unused_int, int, char *);
+extern int tokenize(char *unused_char_p_t, char **unused_char_pp_t, int);
+extern int dec64(uint8_t * unused_uint8_p_t, int unused_int,
+                                char *unused_char_p_t, int);
+extern void qsort(void *, long, long, int (*)(void *, void *));
+
+extern int toupper(int);
+extern char *netmkaddr(char *unused_char_p_t, char *, char *);
+extern int myetheraddr(uint8_t * unused_uint8_p_t, char *unused_char_p_t);
+extern int parseether(uint8_t * unused_uint8_p_t, char *unused_char_p_t);
+
+/*
+ * network dialling
+ */
+#define        NETPATHLEN      40
+
+/*
+ * Syscall data structures
+ */
+#define        MORDER  0x0003  /* mask for bits defining order of mounting */
+#define        MREPL   0x0000  /* mount replaces object */
+#define        MBEFORE 0x0001  /* mount goes before others in union directory */
+#define        MAFTER  0x0002  /* mount goes after others in union directory */
+#define        MCREATE 0x0004  /* permit creation in mounted directory */
+#define        MCACHE  0x0010  /* cache some data */
+#define        MMASK   0x0017  /* all bits on */
+
+#define        NCONT   0       /* continue after note */
+#define        NDFLT   1       /* terminate after note */
+#define        NSAVE   2       /* clear note but hold state */
+#define        NRSTR   3       /* restore saved state */
+
+#define        STATMAX 65535U  /* max length of machine-independent stat structure */
+#define        ERRMAX                  128     /* max length of error string */
+#define        KNAMELEN                28      /* max length of name held in kernel */
+
+/* bits in Qid.type */
+#define QTDIR          0x80    /* type bit for directories */
+#define QTAPPEND       0x40    /* type bit for append only files */
+#define QTEXCL         0x20    /* type bit for exclusive use files */
+#define QTMOUNT                0x10    /* type bit for mounted channel */
+#define QTAUTH         0x08    /* type bit for authentication file */
+#define QTFILE         0x01    /* plain file */
+
+/* bits in Dir.mode */
+#define DMDIR          0x80000000      /* mode bit for directories */
+#define DMAPPEND       0x40000000      /* mode bit for append only files */
+#define DMEXCL         0x20000000      /* mode bit for exclusive use files */
+#define DMMOUNT                0x10000000      /* mode bit for mounted channel */
+#define DMSYMLINK      0x02000000      /* symlink -- from 9p2000.u */
+#define DMREAD         0x4     /* mode bit for read permission */
+#define DMWRITE                0x2     /* mode bit for write permission */
+#define DMEXEC         0x1     /* mode bit for execute permission */
+
+/* Helper for mode checks.  It's poorly named since it's really "not writable"*/
+#define IS_RDONLY(x) (!((x) & O_WRITE))
+
+struct qid {
+       uint64_t path;
+       uint32_t vers;
+       uint8_t type;
+};
+
+struct dir {
+       /* system-modified data */
+       uint16_t type;                          /* server type */
+       unsigned int dev;                       /* server subtype */
+       /* file data */
+       struct qid qid;                         /* unique id from server */
+       uint32_t mode;                          /* permissions */
+       uint32_t atime;                         /* last read time */
+       uint32_t mtime;                         /* last write time */
+       int64_t length;                         /* file length: see <u.h> */
+       char *name;                                     /* last element of path */
+       char *uid;                                      /* owner name */
+       char *gid;                                      /* group name */
+       char *muid;                                     /* last modifier name */
+};
+
+struct waitmsg {
+       int pid;                                        /* of loved one */
+       uint32_t time[3];                       /* of loved one and descendants */
+       char msg[ERRMAX];                       /* actually variable-size in user mode */
+};
 
 #define        VERSION9P       "9P2000"
 
 #define        MAXWELEM        16
 
 typedef
-struct Fcall
-{
-       uchar   type;
-       u32int  fid;
-       ushort  tag;
+       struct fcall {
+       uint8_t type;
+       uint32_t fid;
+       uint16_t tag;
        /* union { */
-               /* struct { */
-                       u32int  msize;          /* Tversion, Rversion */
-                       char    *version;       /* Tversion, Rversion */
-               /* }; */
-               /* struct { */
-                       ushort  oldtag;         /* Tflush */
-               /* }; */
-               /* struct { */
-                       char    *ename;         /* Rerror */
-               /* }; */
-               /* struct { */
-                       Qid     qid;            /* Rattach, Ropen, Rcreate */
-                       u32int  iounit;         /* Ropen, Rcreate */
-               /* }; */
-               /* struct { */
-                       Qid     aqid;           /* Rauth */
-               /* }; */
-               /* struct { */
-                       u32int  afid;           /* Tauth, Tattach */
-                       char    *uname;         /* Tauth, Tattach */
-                       char    *aname;         /* Tauth, Tattach */
-               /* }; */
-               /* struct { */
-                       u32int  perm;           /* Tcreate */ 
-                       char    *name;          /* Tcreate */
-                       uchar   mode;           /* Tcreate, Topen */
-               /* }; */
-               /* struct { */
-                       u32int  newfid;         /* Twalk */
-                       ushort  nwname;         /* Twalk */
-                       char    *wname[MAXWELEM];       /* Twalk */
-               /* }; */
-               /* struct { */
-                       ushort  nwqid;          /* Rwalk */
-                       Qid     wqid[MAXWELEM];         /* Rwalk */
-               /* }; */
-               /* struct { */
-                       vlong   offset;         /* Tread, Twrite */
-                       u32int  count;          /* Tread, Twrite, Rread */
-                       char    *data;          /* Twrite, Rread */
-               /* }; */
-               /* struct { */
-                       ushort  nstat;          /* Twstat, Rstat */
-                       uchar   *stat;          /* Twstat, Rstat */
-               /* }; */
+       /* struct { */
+       uint32_t msize;                         /* Tversion, Rversion */
+       char *version;                          /* Tversion, Rversion */
        /* }; */
-} Fcall;
-
+       /* struct { */
+       uint16_t oldtag;                        /* Tflush */
+       /* }; */
+       /* struct { */
+       char *ename;                            /* Rerror */
+       /* }; */
+       /* struct { */
+       struct qid qid;                         /* Rattach, Ropen, Rcreate */
+       uint32_t iounit;                        /* Ropen, Rcreate */
+       /* }; */
+       /* struct { */
+       struct qid aqid;                        /* Rauth */
+       /* }; */
+       /* struct { */
+       uint32_t afid;                          /* Tauth, Tattach */
+       char *uname;                            /* Tauth, Tattach */
+       char *aname;                            /* Tauth, Tattach */
+       /* }; */
+       /* struct { */
+       uint32_t perm;                          /* Tcreate */
+       char *name;                                     /* Tcreate */
+       uint8_t mode;                           /* Tcreate, Topen */
+       /* }; */
+       /* struct { */
+       uint32_t newfid;                        /* Twalk */
+       uint16_t nwname;                        /* Twalk */
+       char *wname[MAXWELEM];          /* Twalk */
+       /* }; */
+       /* struct { */
+       uint16_t nwqid;                         /* Rwalk */
+       struct qid wqid[MAXWELEM];      /* Rwalk */
+       /* }; */
+       /* struct { */
+       int64_t offset;                         /* Tread, Twrite */
+       uint32_t count;                         /* Tread, Twrite, Rread */
+       char *data;                                     /* Twrite, Rread */
+       /* }; */
+       /* struct { */
+       uint16_t nstat;                         /* Twstat, Rstat */
+       uint8_t *stat;                          /* Twstat, Rstat */
+       /* }; */
+       /* }; */
+} fcall;
 
 #define        GBIT8(p)        ((p)[0])
 #define        GBIT16(p)       ((p)[0]|((p)[1]<<8))
-#define        GBIT32(p)       ((u32int)((p)[0]|((p)[1]<<8)|((p)[2]<<16)|((p)[3]<<24)))
-#define        GBIT64(p)       ((u32int)((p)[0]|((p)[1]<<8)|((p)[2]<<16)|((p)[3]<<24)) |\
-                               ((vlong)((p)[4]|((p)[5]<<8)|((p)[6]<<16)|((p)[7]<<24)) << 32))
+#define        GBIT32(p)       ((uint32_t)((p)[0]|((p)[1]<<8)|((p)[2]<<16)|((p)[3]<<24)))
+#define        GBIT64(p)       ((uint32_t)((p)[0]|((p)[1]<<8)|((p)[2]<<16)|((p)[3]<<24)) |\
+                               ((int64_t)((p)[4]|((p)[5]<<8)|((p)[6]<<16)|((p)[7]<<24)) << 32))
 
 #define        PBIT8(p,v)      (p)[0]=(v)
 #define        PBIT16(p,v)     (p)[0]=(v);(p)[1]=(v)>>8
@@ -84,457 +211,360 @@ struct   Fcall
 /* The count, however, excludes itself; total size is BIT16SZ+count */
 #define STATFIXLEN     (BIT16SZ+QIDSZ+5*BIT16SZ+4*BIT32SZ+1*BIT64SZ)   /* amount of fixed length data in a stat buffer */
 
-#define        NOTAG           (ushort)~0U     /* Dummy tag */
-#define        NOFID           (u32int)~0U     /* Dummy fid */
+#define        NOTAG           (uint16_t)~0U   /* Dummy tag */
+#define        NOFID           (uint32_t)~0U   /* Dummy fid */
 #define        IOHDRSZ         24      /* ample room for Twrite/Rread header (iounit) */
 
-enum
-{
-       Tversion =      100,
+enum {
+       Tversion = 100,
        Rversion,
-       Tauth = 102,
+       Tauth = 102,
        Rauth,
-       Tattach =       104,
+       Tattach = 104,
        Rattach,
-       Terror =        106,    /* illegal */
+       Terror = 106,   /* illegal */
        Rerror,
-       Tflush =        108,
+       Tflush = 108,
        Rflush,
-       Twalk =         110,
+       Twalk = 110,
        Rwalk,
-       Topen =         112,
+       Topen = 112,
        Ropen,
-       Tcreate =       114,
+       Tcreate = 114,
        Rcreate,
-       Tread =         116,
+       Tread = 116,
        Rread,
-       Twrite =        118,
+       Twrite = 118,
        Rwrite,
-       Tclunk =        120,
+       Tclunk = 120,
        Rclunk,
-       Tremove =       122,
+       Tremove = 122,
        Rremove,
-       Tstat =         124,
+       Tstat = 124,
        Rstat,
-       Twstat =        126,
+       Twstat = 126,
        Rwstat,
        Tmax,
 };
 
-uint   convM2S(uchar*, uint, Fcall*);
-uint   convS2M(Fcall*, uchar*, uint);
-uint   sizeS2M(Fcall*);
-
-int    statcheck(uchar *abuf, uint nbuf);
-uint   convM2D(uchar*, uint, Dir*, char*);
-uint   convD2M(Dir*, uchar*, uint);
-uint   sizeD2M(Dir*);
-
-int    fcallfmt(Fmt*);
-int    dirfmt(Fmt*);
-int    dirmodefmt(Fmt*);
-
-int    read9pmsg(int, void*, uint);
-
-#pragma        varargck        type    "F"     Fcall*
-#pragma        varargck        type    "M"     ulong
-#pragma        varargck        type    "D"     Dir*
-
-typedef struct Alarms  Alarms;
-typedef struct Block   Block;
-typedef struct Bkpt Bkpt;
-typedef struct BkptCond BkptCond;
-typedef struct Chan    Chan;
-typedef struct Cmdbuf  Cmdbuf;
-typedef struct Cmdtab  Cmdtab;
-typedef struct Cname   Cname;
-typedef struct Crypt   Crypt;
-typedef struct Dev     Dev;
-typedef struct DevConf DevConf;
-typedef struct Dirtab  Dirtab;
-typedef struct Edf     Edf;
-typedef struct Egrp    Egrp;
-typedef struct Evalue  Evalue;
-typedef struct Fgrp    Fgrp;
-typedef struct List    List;
-typedef struct Log     Log;
-typedef struct Logflag Logflag;
-typedef struct Mntcache Mntcache;
-typedef struct Mntparam Mntparam;
-typedef struct Mount   Mount;
-typedef struct Mntrpc  Mntrpc;
-typedef struct Mntwalk Mntwalk;
-typedef struct Mnt     Mnt;
-typedef struct Mhead   Mhead;
-typedef struct Osenv   Osenv;
-typedef struct Pgrp    Pgrp;
-typedef struct Proc    Proc;
-typedef struct QLock   QLock;
-typedef struct Queue   Queue;
-typedef struct Ref     Ref;
-typedef struct Rendez  Rendez;
-typedef struct Rept    Rept;
-typedef struct Rootdata        Rootdata;
-typedef struct RWlock  RWlock;
-typedef struct Signerkey Signerkey;
-typedef struct Skeyset Skeyset;
-typedef struct Talarm  Talarm;
-typedef struct Timer   Timer;
-typedef struct Timers  Timers;
-typedef struct Uart    Uart;
-typedef struct Walkqid Walkqid;
-typedef int    Devgen(Chan*, char*, Dirtab*, int, int, Dir*);
-
-#pragma incomplete DevConf
-#pragma incomplete Edf
-#pragma incomplete Mntcache
-#pragma incomplete Mntrpc
-#pragma incomplete Queue
-#pragma incomplete Timers
-
-#include "fcall.h"
-#include <pool.h>
-
-struct Ref
-{
-       Lock    l;
-       long    ref;
-};
+void init_empty_dir(struct dir *d);
+unsigned int convM2S(uint8_t * unused_uint8_p_t, unsigned int unused_int,
+                                        struct fcall *);
+unsigned int convS2M(struct fcall *, uint8_t * unused_uint8_p_t, unsigned int);
+unsigned int sizeS2M(struct fcall *);
 
-struct Rendez
-{
-       Lock;
-       Proc    *p;
-};
+unsigned int convM2kdirent(uint8_t * buf, unsigned int nbuf, struct kdirent *kd,
+                                                  char *strs);
+unsigned int convM2kstat(uint8_t * buf, unsigned int nbuf, struct kstat *ks);
 
-struct Rept
-{
-       Lock    l;
-       Rendez  r;
-       void    *o;
-       int     t;
-       int     (*active)(void*);
-       int     (*ck)(void*, int);
-       void    (*f)(void*);    /* called with VM acquire()'d */
-};
+int statcheck(uint8_t * abuf, unsigned int nbuf);
+unsigned int convM2D(uint8_t * unused_uint8_p_t, unsigned int unused_int,
+                                        struct dir *, char *unused_char_p_t);
+unsigned int convD2M(struct dir *, uint8_t * unused_uint8_p_t, unsigned int);
+unsigned int sizeD2M(struct dir *);
 
-struct Osenv
-{
-       char    *syserrstr;     /* last error from a system call, errbuf0 or 1 */
-       char    *errstr;        /* reason we're unwinding the error stack, errbuf1 or 0 */
-       char    errbuf0[ERRMAX];
-       char    errbuf1[ERRMAX];
-       Pgrp*   pgrp;           /* Ref to namespace, working dir and root */
-       Fgrp*   fgrp;           /* Ref to file descriptors */
-       Egrp*   egrp;   /* Environment vars */
-       Skeyset*        sigs;           /* Signed module keys */
-       Rendez* rend;           /* Synchro point */
-       Queue*  waitq;          /* Info about dead children */
-       Queue*  childq;         /* Info about children for debuggers */
-       void*   debug;          /* Debugging master */
-       int     uid;            /* Numeric user id for system */
-       int     gid;            /* Numeric group id for system */
-       char*   user;           /* Inferno user name */
-       FPenv   fpu;            /* Floating point thread state */
-};
-
-enum
-{
-       Nopin = -1
-};
+int read9pmsg(int unused_int, void *, unsigned int);
 
-struct QLock
-{
-       Lock    use;                    /* to access Qlock structure */
-       Proc    *head;                  /* next process waiting for object */
-       Proc    *tail;                  /* last process waiting for object */
-       int     locked;                 /* flag */
+struct ref {
+       spinlock_t l;
+       long ref;
 };
 
-struct RWlock
-{
-       Lock;                           /* Lock modify lock */
-       QLock   x;                      /* Mutual exclusion lock */
-       QLock   k;                      /* Lock for waiting writers */
-       int     readers;                /* Count of readers in lock */
+struct rept {
+       spinlock_t l;
+       struct rendez r;
+       void *o;
+       int t;
+       int (*active) (void *);
+       int (*ck) (void *, int);
+       void (*f) (void *);                     /* called with VM acquire()'d */
 };
 
-struct Talarm
-{
-       Lock;
-       Proc*   list;
+enum {
+       Nopin = -1
 };
 
-struct Alarms
-{
-       QLock;
-       Proc*   head;
+struct talarm {
+       spinlock_t lock;
+       struct proc *list;
 };
 
-struct Rootdata
-{
-       int     dotdot;
-       void    *ptr;
-       int     size;
-       int     *sizep;
+struct alarms {
+       qlock_t qlock;
+       struct proc *head;
 };
 
 /*
  * Access types in namec & channel flags
  */
-enum
-{
-       Aaccess,                        /* as in stat, wstat */
-       Abind,                  /* for left-hand-side of bind */
-       Atodir,                         /* as in chdir */
-       Aopen,                          /* for i/o */
-       Amount,                         /* to be mounted or mounted upon */
-       Acreate,                        /* is to be created */
-       Aremove,                        /* will be removed by caller */
-
-       COPEN   = 0x0001,               /* for i/o */
-       CMSG    = 0x0002,               /* the message channel for a mount */
-       CCEXEC  = 0x0008,               /* close on exec */
-       CFREE   = 0x0010,               /* not in use */
-       CRCLOSE = 0x0020,               /* remove on close */
-       CCACHE  = 0x0080,               /* client cache */
-};
-
-enum
-{
-       BINTR           =       (1<<0),
-       BFREE           =       (1<<1),
-       Bipck   =       (1<<2),         /* ip checksum */
-       Budpck  =       (1<<3),         /* udp checksum */
-       Btcpck  =       (1<<4),         /* tcp checksum */
-       Bpktck  =       (1<<5),         /* packet checksum */
+enum {
+       Aaccess,                                        /* as in stat, wstat */
+       Abind,                                          /* for left-hand-side of bind */
+       Atodir,                                         /* as in chdir */
+       Aopen,                                          /* for i/o */
+       Amount,                                         /* to be mounted or mounted upon */
+       Acreate,                                        /* is to be created */
+       Aremove,                                        /* will be removed by caller */
+       Acreatechan,                                    /* return a chan for a create request. for sysrename. */
+
+       /* internal chan flags, used by the kernel only */
+       COPEN =                 0x0001, /* for i/o */
+       CMSG =                  0x0002, /* the message channel for a mount */
+       CFREE =                 0x0004, /* not in use */
+       CCACHE =                0x0008, /* client cache */
+       CINTERNAL_FLAGS = (COPEN | CMSG | CFREE | CCACHE),
+
+       /* chan/file flags, setably via open and sometimes fcntl/setfl.  these are
+        * the internal names used in some parts of 9ns */
+       CCEXEC =                O_CLOEXEC,      /* (prob should be on the FD, 9ns has it here) */
+       CRCLOSE =               O_REMCLO,       /* remove on close (also, maybe should be on FD) */
+       CAPPEND =               O_APPEND,       /* append on write */
+       CNONBLOCK =     O_NONBLOCK,     /* don't block, can't be set via setfl */
+       CEXTERNAL_FLAGS = (CCEXEC | CRCLOSE | CAPPEND | CNONBLOCK),
 };
 
-struct Block
-{
-       Block*  next;
-       Block*  list;
-       uchar*  rp;                     /* first unconsumed byte */
-       uchar*  wp;                     /* first empty byte */
-       uchar*  lim;                    /* 1 past the end of the buffer */
-       uchar*  base;                   /* start of the buffer */
-       void    (*free)(Block*);
-       ushort  flag;
-       ushort  checksum;               /* IP checksum of complete packet (minus media header) */
-};
-#define BLEN(s)        ((s)->wp - (s)->rp)
-#define BALLOC(s) ((s)->lim - (s)->base)
-
-struct Chan
-{
-       Lock;
-       Ref;
-       Chan*   next;                   /* allocation */
-       Chan*   link;
-       vlong   offset;                 /* in file */
-       ushort  type;
-       ulong   dev;
-       ushort  mode;                   /* read/write */
-       ushort  flag;
-       Qid     qid;
-       int     fid;                    /* for devmnt */
-       ulong   iounit; /* chunk size for i/o; 0==default */
-       Mhead*  umh;                    /* mount point that derived Chan; used in unionread */
-       Chan*   umc;                    /* channel in union; held for union read */
-       QLock   umqlock;                /* serialize unionreads */
-       int     uri;                    /* union read index */
-       int     dri;                    /* devdirread index */
-       ulong   mountid;
-       Mntcache *mcp;                  /* Mount cache pointer */
-       Mnt             *mux;           /* Mnt for clients using me for messages */
+#define NS_IPCK_SHIFT  2
+#define NS_UDPCK_SHIFT 3
+#define NS_TCPCK_SHIFT 4
+#define NS_PKTCK_SHIFT 5
+#define NS_TSO_SHIFT 6
+#define NS_SHIFT_MAX 6
+
+enum {
+       BINTR = (1 << 0),
+       BFREE = (1 << 1),
+       Bipck = (1 << NS_IPCK_SHIFT),   /* ip checksum */
+       Budpck = (1 << NS_UDPCK_SHIFT), /* udp checksum */
+       Btcpck = (1 << NS_TCPCK_SHIFT), /* tcp checksum */
+       Bpktck = (1 << NS_PKTCK_SHIFT), /* packet checksum */
+       Btso = (1 << NS_TSO_SHIFT),     /* TSO */
+};
+#define BCKSUM_FLAGS (Bipck|Budpck|Btcpck|Bpktck|Btso)
+
+struct extra_bdata {
+       uintptr_t base;
+       /* using u32s for packing reasons.  this means no extras > 4GB */
+       uint32_t off;
+       uint32_t len;
+};
+
+struct block {
+       struct block *next;
+       struct block *list;
+       uint8_t *rp;                            /* first unconsumed byte */
+       uint8_t *wp;                            /* first empty byte */
+       uint8_t *lim;                           /* 1 past the end of the buffer */
+       uint8_t *base;                          /* start of the buffer */
+       void (*free) (struct block *);
+       uint16_t flag;
+       uint16_t checksum;                      /* IP checksum of complete packet (minus media header) */
+       uint16_t checksum_start;                /* off from start of block to start csum */
+       uint16_t checksum_offset;               /* off from checksum_start to store csum */
+       uint16_t mss;               /* TCP MSS for TSO */
+       /* might want something to track the next free extra_data slot */
+       size_t extra_len;
+       unsigned int nr_extra_bufs;
+       struct extra_bdata *extra_data;
+};
+#define BLEN(s)        ((s)->wp - (s)->rp + (s)->extra_len)
+#define BHLEN(s) ((s)->wp - (s)->rp)
+#define BALLOC(s) ((s)->lim - (s)->base + (s)->extra_len)
+
+struct chan {
+       spinlock_t lock;
+       struct kref ref;
+       struct chan *next;                      /* allocation */
+       struct chan *link;
+       int64_t offset;                         /* in file */
+       int type;
+       uint32_t dev;
+       uint16_t mode;                          /* read/write */
+       uint16_t flag;
+       struct qid qid;
+       int fid;                                        /* for devmnt */
+       uint32_t iounit;                        /* chunk size for i/o; 0==default */
+       struct mhead *umh;                      /* mount point that derived Chan; used in unionread */
+       struct chan *umc;                       /* channel in union; held for union read */
+       qlock_t umqlock;                        /* serialize unionreads */
+       int uri;                                        /* union read index */
+       int dri;                                        /* devdirread index */
+       uint32_t mountid;
+       struct mntcache *mcp;           /* Mount cache pointer */
+       struct mnt *mux;                        /* Mnt for clients using me for messages */
        union {
-               void*   aux;
-               char    tag[4];         /* for iproute */
+               void *aux;
+               char tag[4];                    /* for iproute */
        };
-       Chan*   mchan;                  /* channel to mounted server */
-       Qid     mqid;                   /* qid of root of mount point */
-       Cname   *name;
+       /* mountpoint, as discovered during walk.
+        * Used for rename at present.
+        */
+       struct chan *mountpoint;
+       struct chan *mchan;                     /* channel to mounted server */
+       struct qid mqid;                        /* qid of root of mount point */
+       struct cname *name;
+       /* hack for dir reads to try to get them right. */
+       int ateof;
+       void *buf;
+       int bufused;
 };
 
-struct Cname
-{
-       Ref;
-       int     alen;                   /* allocated length */
-       int     len;                    /* strlen(s) */
-       char    *s;
+struct cname {
+       struct kref ref;
+       int alen;                                       /* allocated length */
+       int len;                                        /* strlen(s) */
+       char *s;
 };
 
-struct Dev
-{
-       int     dc;
-       char*   name;
-
-       void    (*reset)(void);
-       void    (*init)(void);
-       void    (*shutdown)(void);
-       Chan*   (*attach)(char*);
-       Walkqid*        (*walk)(Chan*, Chan*, char**, int);
-       int     (*stat)(Chan*, uchar*, int);
-       Chan*   (*open)(Chan*, int);
-       void    (*create)(Chan*, char*, int, ulong);
-       void    (*close)(Chan*);
-       long    (*read)(Chan*, void*, long, vlong);
-       Block*  (*bread)(Chan*, long, ulong);
-       long    (*write)(Chan*, void*, long, vlong);
-       long    (*bwrite)(Chan*, Block*, ulong);
-       void    (*remove)(Chan*);
-       int     (*wstat)(Chan*, uchar*, int);
-       void    (*power)(int);  /* power mgt: power(1) → on, power (0) → off */
-       int     (*config)(int, char*, DevConf*);
-};
-
-struct Dirtab
-{
-       char    name[KNAMELEN];
-       Qid     qid;
-       vlong   length;
-       long    perm;
+struct dev {
+       int dc;
+       char *name;
+
+       void (*reset) (void);
+       void (*init) (void);
+       void (*shutdown) (void);
+       struct chan *(*attach) (char *muxattach);
+       struct walkqid *(*walk) (struct chan *, struct chan *, char **name, int);
+       int (*stat) (struct chan *, uint8_t *, int);
+       struct chan *(*open) (struct chan *, int);
+       void (*create) (struct chan *, char *, int, uint32_t);
+       void (*close) (struct chan *);
+       long (*read) (struct chan *, void *, long, int64_t);
+       struct block *(*bread) (struct chan *, long, uint32_t);
+       long (*write) (struct chan *, void *, long, int64_t);
+       long (*bwrite) (struct chan *, struct block *, uint32_t);
+       void (*remove) (struct chan *);
+       int (*wstat) (struct chan *, uint8_t * unused_uint8_p_t, int);
+       void (*power) (int);            /* power mgt: power(1) → on, power (0) → off */
+//  int (*config)( int unused_int, char *unused_char_p_t, DevConf*);
+       char *(*chaninfo) (struct chan *, char *, size_t);
+       int (*tapfd) (struct chan *, struct fd_tap *, int);
+       /* we need to be aligned, we think to 64 bytes, for the linker tables. */
+} __attribute__ ((aligned(64)));
+
+struct dirtab {
+       char name[KNAMELEN];
+       struct qid qid;
+       int64_t length;
+       long perm;
 };
 
-struct Walkqid
-{
-       Chan    *clone;
-       int     nqid;
-       Qid     qid[1];
+struct walkqid {
+       struct chan *clone;
+       int nqid;
+       struct qid qid[1];
 };
 
-enum
-{
-       NSMAX   =       1000,
-       NSLOG   =       7,
-       NSCACHE =       (1<<NSLOG),
+enum {
+       NSMAX = 1000,
+       NSLOG = 7,
+       NSCACHE = (1 << NSLOG),
 };
 
-struct Mntwalk                         /* state for /proc/#/ns */
-{
-       int             cddone;
-       ulong   id;
-       Mhead*  mh;
-       Mount*  cm;
+struct mntwalk {                               /* state for /proc/#/ns */
+       int cddone;
+       uint32_t id;
+       struct mhead *mh;
+       struct mount *cm;
 };
 
-struct Mount
-{
-       ulong   mountid;
-       Mount*  next;
-       Mhead*  head;
-       Mount*  copy;
-       Mount*  order;
-       Chan*   to;                     /* channel replacing channel */
-       int     mflag;
-       char    *spec;
+struct mount {
+       uint32_t mountid;
+       struct mount *next;
+       struct mhead *head;
+       struct mount *copy;
+       struct mount *order;
+       struct chan *to;                        /* channel replacing channel */
+       int mflag;
+       char *spec;
 };
 
-struct Mhead
-{
-       Ref;
-       RWlock  lock;
-       Chan*   from;                   /* channel mounted upon */
-       Mount*  mount;                  /* what's mounted upon it */
-       Mhead*  hash;                   /* Hash chain */
+struct mhead {
+       struct kref ref;
+       struct rwlock lock;
+       struct chan *from;                      /* channel mounted upon */
+       struct mount *mount;            /* what's mounted upon it */
+       struct mhead *hash;                     /* Hash chain */
 };
 
-struct Mnt
-{
-       Lock;
+struct mnt {
+       spinlock_t lock;
        /* references are counted using c->ref; channels on this mount point incref(c->mchan) == Mnt.c */
-       Chan    *c;             /* Channel to file service */
-       Proc    *rip;           /* Reader in progress */
-       Mntrpc  *queue;         /* Queue of pending requests on this channel */
-       ulong   id;             /* Multiplexer id for channel check */
-       Mnt     *list;          /* Free list */
-       int     flags;          /* cache */
-       int     msize;          /* data + IOHDRSZ */
-       char    *version;                       /* 9P version */
-       Queue   *q;             /* input queue */
-};
-
-enum
-{
-       RENDLOG =       5,
-       RENDHASH =      1<<RENDLOG,             /* Hash to lookup rendezvous tags */
-       MNTLOG  =       5,
-       MNTHASH =       1<<MNTLOG,              /* Hash to walk mount table */
-       DELTAFD=                20,             /* allocation quantum for process file descriptors */
-       MAXNFD =                4000,           /* max per process file descriptors */
-       MAXKEY =                8,      /* keys for signed modules */
+       struct chan *c;                         /* Channel to file service */
+       struct proc *rip;                       /* Reader in progress */
+       struct mntrpc *queue;           /* Queue of pending requests on this channel */
+       uint32_t id;                            /* Multiplexer id for channel check */
+       struct mnt *list;                       /* Free list */
+       int flags;                                      /* cache */
+       int msize;                                      /* data + IOHDRSZ */
+       char *version;                          /* 9P version */
+       struct queue *q;                        /* input queue */
+};
+
+enum {
+       RENDLOG = 5,
+       RENDHASH = 1 << RENDLOG,        /* Hash to lookup rendezvous tags */
+       MNTLOG = 5,
+       MNTHASH = 1 << MNTLOG,  /* Hash to walk mount table */
+       DELTAFD = 20,   /* allocation quantum for process file descriptors */
+       MAXNFD = 4000,  /* max per process file descriptors */
+       MAXKEY = 8,     /* keys for signed modules */
 };
 #define MOUNTH(p,qid)  ((p)->mnthash[(qid).path&((1<<MNTLOG)-1)])
 
-struct Mntparam {
-       Chan*   chan;
-       Chan*   authchan;
-       char*   spec;
-       int     flags;
+struct mntparam {
+       struct chan *chan;
+       struct chan *authchan;
+       char *spec;
+       int flags;
 };
 
-struct Pgrp
-{
-       Ref;                            /* also used as a lock when mounting */
-       ulong   pgrpid;
-       QLock   debug;                  /* single access via devproc.c */
-       RWlock  ns;                     /* Namespace n read/one write lock */
-       QLock   nsh;
-       Mhead*  mnthash[MNTHASH];
-       int     progmode;
-       Chan*   dot;
-       Chan*   slash;
-       int     nodevs;
-       int     pin;
-};
-
-struct Fgrp
-{
-       Lock;
-       Ref;
-       Chan**  fd;
-       int     nfd;                    /* number of fd slots */
-       int     maxfd;                  /* highest fd in use */
-       int     minfd;                  /* lower bound on free fd */
+struct pgrp {
+       struct kref ref;                        /* also used as a lock when mounting */
+       uint32_t pgrpid;
+       qlock_t debug;                          /* single access via devproc.c */
+       struct rwlock ns;                       /* Namespace n read/one write lock */
+       qlock_t nsh;
+       struct mhead *mnthash[MNTHASH];
+       int progmode;
+       struct chan *dot;
+       struct chan *slash;
+       int nodevs;
+       int pin;
 };
 
-struct Evalue
-{
-       char    *var;
-       char    *val;
-       int     len;
-       Qid     qid;
-       Evalue  *next;
+struct evalue {
+       char *var;
+       char *val;
+       int len;
+       struct qid qid;
+       struct evalue *next;
 };
 
-struct Egrp
-{
-       Ref;
-       QLock;
-       Evalue  *entries;
-       ulong   path;   /* qid.path of next Evalue to be allocated */
-       ulong   vers;   /* of Egrp */
+struct egrp {
+       struct kref ref;
+       qlock_t qlock;
+       struct evalue *entries;
+       uint32_t path;                          /* qid.path of next Evalue to be allocated */
+       uint32_t vers;                          /* of Egrp */
 };
 
-struct Signerkey
-{
-       Ref;
-       char*   owner;
-       ushort  footprint;
-       ulong   expires;
-       void*   alg;
-       void*   pk;
-       void    (*pkfree)(void*);
+struct signerkey {
+       struct kref ref;
+       char *owner;
+       uint16_t footprint;
+       uint32_t expires;
+       void *alg;
+       void *pk;
+       void (*pkfree) (void *);
 };
 
-struct Skeyset
-{
-       Ref;
-       QLock;
-       ulong   flags;
-       char*   devs;
-       int     nkey;
-       Signerkey       *keys[MAXKEY];
+struct skeyset {
+       struct kref ref;
+       qlock_t qlock;
+       uint32_t flags;
+       char *devs;
+       int nkey;
+       struct signerkey *keys[MAXKEY];
 };
 
 /*
@@ -542,271 +572,472 @@ struct Skeyset
  */
 enum {
        /* Mode */
-       Trelative,      /* timer programmed in ns from now */
-       Tabsolute,      /* timer programmed in ns since epoch */
-       Tperiodic,      /* periodic timer, period in ns */
-};
-
-struct Timer
-{
-       /* Public interface */
-       int     tmode;          /* See above */
-       vlong   tns;            /* meaning defined by mode */
-       void    (*tf)(Ureg*, Timer*);
-       void    *ta;
-       /* Internal */
-       Lock;
-       Timers  *tt;            /* Timers queue this timer runs on */
-       vlong   twhen;          /* ns represented in fastticks */
-       Timer   *tnext;
-};
-
-enum
-{
-       Dead = 0,               /* Process states */
-       Moribund,
-       Ready,
-       Scheding,
-       Running,
-       Queueing,
-       Wakeme,
-       Broken,
-       Stopped,
-       Rendezvous,
-       Waitrelease,
-
-       Proc_stopme = 1,        /* devproc requests */
-       Proc_exitme,
-       Proc_traceme,
-       Proc_exitbig,
-
-       NERR            = 30,
-
-       Unknown         = 0,
-       IdleGC,
-       Interp,
-       BusyGC,
-
-       PriLock         = 0,    /* Holding Spin lock */
-       PriEdf, /* active edf processes */
-       PriRelease,     /* released edf processes */
-       PriRealtime,            /* Video telephony */
-       PriHicodec,             /* MPEG codec */
-       PriLocodec,             /* Audio codec */
-       PriHi,                  /* Important task */
-       PriNormal,
-       PriLo,
-       PriBackground,
-       PriExtra,       /* edf processes we don't care about */
-       Nrq
-};
-
-struct Proc
-{
-       Label           sched;          /* known to l.s */
-       char*           kstack;         /* known to l.s */
-       Mach*           mach;           /* machine running this proc */
-       char            text[KNAMELEN];
-       Proc*           rnext;          /* next process in run queue */
-       Proc*           qnext;          /* next process on queue for a QLock */
-       QLock*          qlock;          /* addrof qlock being queued for DEBUG */
-       int             state;
-       int             type;
-       void*           prog;           /* Dummy Prog for interp release */
-       void*           iprog;
-       Osenv*          env;
-       Osenv           defenv;
-       int             swipend;        /* software interrupt pending for Prog */
-       Lock            sysio;          /* note handler lock */
-       char*           psstate;        /* What /proc/#/status reports */
-       ulong           pid;
-       int             fpstate;
-       int             procctl;        /* Control for /proc debugging */
-       ulong           pc;             /* DEBUG only */
-       Lock    rlock;  /* sync between sleep/swiproc for r */
-       Rendez*         r;              /* rendezvous point slept on */
-       Rendez          sleep;          /* place for syssleep/debug */
-       int             killed;         /* by swiproc */
-       int             kp;             /* true if a kernel process */
-       ulong           alarm;          /* Time of call */
-       int             pri;            /* scheduler priority */
-       ulong           twhen;
-       Rendez*         trend;
-       Proc*           tlink;
-       int             (*tfn)(void*);
-       void            (*kpfun)(void*);
-       void*           arg;
-       FPU             fpsave;
-       int             scallnr;
-       int             nerrlab;
-       Label           errlab[NERR];
-       char    genbuf[128];    /* buffer used e.g. for last name element from namec */
-       Mach*           mp;             /* machine this process last ran on */
-       Mach*           wired;
-       ulong           movetime;       /* next time process should switch processors */
-       ulong           delaysched;
-       int                     preempted;      /* process yielding in interrupt */
-       ulong           qpc;            /* last call that blocked in qlock */
-       void*           dbgreg;         /* User registers for devproc */
-       int             dbgstop;                /* don't run this kproc */
-       Edf*    edf;    /* if non-null, real-time proc, edf contains scheduling params */
-};
-
-enum
-{
-       /* kproc flags */
-       KPDUPPG         = (1<<0),
-       KPDUPFDG        = (1<<1),
-       KPDUPENVG       = (1<<2),
-       KPDUP = KPDUPPG | KPDUPFDG | KPDUPENVG
+       Trelative,                                      /* timer programmed in ns from now */
+       Tabsolute,                                      /* timer programmed in ns since epoch */
+       Tperiodic,                                      /* periodic timer, period in ns */
 };
 
 enum {
-       BrkSched,
-       BrkNoSched,
+       PRINTSIZE = 256,
+       NUMSIZE = 12,   /* size of formatted number */
+       MB = (1024 * 1024),
+       READSTR = 2000, /* temporary buffer size for device reads */
 };
 
-struct BkptCond
-{
-       uchar op;
-       ulong val;
-       BkptCond *next;
-};
-
-struct Bkpt
-{
-       int id;
-       ulong addr;
-       BkptCond *conditions;
-       Instr instr;
-       void (*handler)(Bkpt*);
-       void *aux;
-       Bkpt *next;
-       Bkpt *link;
-};
-
-enum
-{
-       PRINTSIZE =     256,
-       NUMSIZE =       12,             /* size of formatted number */
-       MB =            (1024*1024),
-       READSTR =       1000,           /* temporary buffer size for device reads */
-};
-
-extern Conf    conf;
-extern char*   conffile;
-extern int     consoleprint;
-extern Dev*    devtab[];
-extern char*   eve;
-extern int     hwcurs;
-extern FPU     initfp;
-extern  Queue  *kbdq;
-extern  Queue  *kscanq;
-extern  Ref    noteidalloc;
-extern  Queue  *printq;
-extern uint    qiomaxatomic;
-extern char*   statename[];
-extern char*   sysname;
-extern Talarm  talarm;
-
-/*
- *  action log
- */
-struct Log {
-       Lock;
-       int     opens;
-       char*   buf;
-       char    *end;
-       char    *rptr;
-       int     len;
-       int     nlog;
-       int     minread;
-
-       int     logmask;        /* mask of things to debug */
+extern struct dev devtab[];
+extern struct dev __devtabend[];
 
-       QLock   readq;
-       Rendez  readr;
+struct cmdbuf {
+       char *buf;
+       char **f;
+       int nf;
 };
 
-struct Logflag {
-       char*   name;
-       int     mask;
+struct cmdtab {
+       int index;                                      /* used by client to switch on result */
+       char *cmd;                                      /* command name */
+       int narg;                                       /* expected #args; 0 ==> variadic */
 };
 
-struct Cmdbuf
-{
-       char    *buf;
-       char    **f;
-       int     nf;
+/* queue state bits, all can be set in qopen (Qstarve is always set) */
+enum {
+       Qstarve = (1 << 0),                     /* consumer starved */
+       Qmsg = (1 << 1),        /* message stream */
+       Qclosed = (1 << 2),     /* queue has been closed/hungup */
+       Qflow = (1 << 3),       /* producer flow controlled */
+       Qcoalesce = (1 << 4),   /* coallesce packets on read */
+       Qkick = (1 << 5),       /* always call the kick routine after qwrite */
+       Qdropoverflow = (1 << 6),       /* writes that would block will be dropped */
+       Qnonblock = (1 << 7),   /* do not block, throw EAGAIN */
 };
 
-struct Cmdtab
-{
-       int     index;  /* used by client to switch on result */
-       char    *cmd;   /* command name */
-       int     narg;   /* expected #args; 0 ==> variadic */
-};
+#define DEVDOTDOT -1
 
-enum
+typedef int Devgen(struct chan *, char *unused_char_p_t, struct dirtab *,
+                                  int unused_int, int, struct dir *);
+
+/* inferno portfns.h. Not all these are needed. */
+// INFERNO
+#define                FPinit() fpinit()       /* remove this if math lib is linked */
+void FPrestore(void *);
+void FPsave(void *);
+struct cname *addelem(struct cname *, char *unused_char_p_t);
+void addprog(struct proc *);
+void addrootfile(char *unused_char_p_t, uint8_t * unused_uint8_p_t, uint32_t);
+struct block *adjustblock(struct block *, int);
+struct block *allocb(int);
+void block_add_extd(struct block *b, unsigned int nr_bufs, int mem_flags);
+int anyhigher(void);
+int anyready(void);
+void _assert(char *unused_char_p_t);
+struct block *bl2mem(uint8_t * unused_uint8_p_t, struct block *, int);
+int blocklen(struct block *);
+char *channame(struct chan *);
+void cclose(struct chan *);
+void chan_incref(struct chan *);
+void chandevinit(void);
+void chandevreset(void);
+void chandevshutdown(void);
+void chanfree(struct chan *);
+void chanrec(struct mnt *);
+void checkalarms(void);
+void checkb(struct block *, char *unused_char_p_t);
+void cinit(void);
+struct chan *cclone(struct chan *);
+void cclose(struct chan *);
+void closeegrp(struct egrp *);
+void closemount(struct mount *);
+void closepgrp(struct pgrp *);
+void closesigs(struct skeyset *);
+void debugcmd(struct cmdbuf *cb);
+struct mhead *newmhead(struct chan *from);
+int cmount(struct chan *, struct chan *, int unused_int, char *unused_char_p_t);
+void cnameclose(struct cname *);
+struct block *concatblock(struct block *);
+struct block *linearizeblock(struct block *b);
+void confinit(void);
+void copen(struct chan *);
+struct block *copyblock(struct block *, int);
+int cread(struct chan *, uint8_t * unused_uint8_p_t, int unused_int, int64_t);
+struct chan *cunique(struct chan *);
+struct chan *createdir(struct chan *, struct mhead *);
+void cunmount(struct chan *, struct chan *);
+void cupdate(struct chan *, uint8_t * unused_uint8_p_t, int unused_int,
+                        int64_t);
+void cursorenable(void);
+void cursordisable(void);
+int cursoron(int);
+void cursoroff(int);
+void cwrite(struct chan *, uint8_t * unused_uint8_p_t, int unused_int, int64_t);
+struct chan *devattach(int unused_int, char *unused_char_p_t);
+struct block *devbread(struct chan *, long, uint32_t);
+long devbwrite(struct chan *, struct block *, uint32_t);
+struct chan *devclone(struct chan *);
+void devcreate(struct chan *, char *name, int mode, uint32_t perm);
+void devdir(struct chan *, struct qid, char *, int64_t, char *, long,
+                       struct dir *);
+long devdirread(struct chan *, char *, long, struct dirtab *, int, Devgen *);
+Devgen devgen;
+void devinit(void);
+int devno(int unused_int, int);
+void devpower(int);
+struct dev *devbyname(char *unused_char_p_t);
+struct chan *devopen(struct chan *, int unused_int,
+                                        struct dirtab *, int unused_int2, Devgen *);
+void devpermcheck(char *unused_char_p_t, uint32_t, int);
+void devremove(struct chan *);
+void devreset(void);
+void devshutdown(void);
+int devstat(struct chan *, uint8_t * unused_uint8_p_t, int unused_int,
+                       struct dirtab *, int unused_int2, Devgen *);
+struct walkqid *devwalk(struct chan *,
+                                               struct chan *, char **unused_char_pp_t, int unused_int,
+                                               struct dirtab *, int unused_intw, Devgen *);
+int devwstat(struct chan *, uint8_t * unused_uint8_p_t, int);
+char *devchaninfo(struct chan *chan, char *ret, size_t ret_l);
+void disinit(void *);
+void disfault(void *, char *unused_char_p_t);
+int domount(struct chan **, struct mhead **);
+void drawactive(int);
+void drawcmap(void);
+void dumpstack(void);
+void egrpcpy(struct egrp *, struct egrp *);
+int emptystr(char *unused_char_p_t);
+int eqchan(struct chan *, struct chan *, int);
+int eqqid(struct qid, struct qid);
+
+void errstr(char *unused_char_p_t, int);
+void excinit(void);
+void exit(int);
+void reboot(void);
+void halt(void);
+int export(int unused_int, char *unused_char_p_t, int);
+uint64_t fastticks(uint64_t *);
+uint64_t fastticks2ns(uint64_t);
+int findmount(struct chan **, struct mhead **, int unused_int, int, struct qid);
+void free(void *);
+void freeb(struct block *);
+void freeblist(struct block *);
+void freeskey(struct signerkey *);
+void getcolor(uint32_t, uint32_t *, uint32_t *, uint32_t *);
+uint32_t getmalloctag(void *);
+uint32_t getrealloctag(void *);
+struct block *iallocb(int);
+void iallocsummary(void);
+void printblock(struct block *b);
+void ilock(spinlock_t *);
+int iprint(char *unused_char_p_t, ...);
+void isdir(struct chan *);
+int islo(void);
+void iunlock(spinlock_t *);
+void ixsummary(void);
+void kbdclock(void);
+int kbdcr2nl(struct queue *, int);
+int kbdputc(struct queue *, int);
+void kbdrepeat(int);
+void kproc(char *unused_char_p_t, void (*)(void *), void *, int);
+void kprocchild(struct proc *, void (*)(void *), void *);
+void (*kproftick) (uint32_t);
+void ksetenv(char *unused_char_p_t, char *, int);
+//void      kstrncpy( char *unused_char_p_t, char*, int unused_int, sizeof(char*, char*));
+void kstrdup(char **unused_char_pp_t, char *unused_char_p_t);
+
+struct block *mem2bl(uint8_t * unused_uint8_p_t, int);
+int memusehigh(void);
+void microdelay(int);
+uint64_t mk64fract(uint64_t, uint64_t);
+void mkqid(struct qid *, int64_t, uint32_t, int);
+void modinit(void);
+struct chan *mntauth(struct chan *, char *unused_char_p_t);
+long mntversion(struct chan *, char *unused_char_p_t, int unused_int, int);
+void mountfree(struct mount *);
+void mousetrack(int unused_int, int, int, int);
+uint64_t ms2fastticks(uint32_t);
+void mul64fract(uint64_t *, uint64_t, uint64_t);
+void muxclose(struct mnt *);
+struct chan *namec(char *unused_char_p_t, int unused_int, int, uint32_t);
+struct chan *newchan(void);
+struct egrp *newegrp(void);
+struct mount *newmount(struct mhead *, struct chan *, int unused_int,
+                                          char *unused_char_p_t);
+struct pgrp *newpgrp(void);
+struct proc *newproc(void);
+char *nextelem(char *unused_char_p_t, char *);
+
+struct cname *newcname(char *unused_char_p_t);
+void notkilled(void);
+int nrand(int);
+uint64_t ns2fastticks(uint64_t);
+int okaddr(uint32_t, uint32_t, int);
+int omode_to_rwx(int);
+int omode_to_9p_accmode(int open_flags);
+struct block *packblock(struct block *);
+struct block *padblock(struct block *, int);
+
+void pgrpcpy(struct pgrp *, struct pgrp *);
+
+int progfdprint(struct chan *, int unused_int, int, char *unused_char_p_t,
+                               int i);
+int pullblock(struct block **, int);
+struct block *pullupblock(struct block *, int);
+struct block *pullupqueue(struct queue *, int);
+void putmhead(struct mhead *);
+void putstrn(char *unused_char_p_t, int);
+void qaddlist(struct queue *, struct block *);
+struct block *qbread(struct queue *, int);
+long qbwrite(struct queue *, struct block *);
+long qibwrite(struct queue *q, struct block *b);
+struct queue *qbypass(void (*)(void *, struct block *), void *);
+int qcanread(struct queue *);
+void qclose(struct queue *);
+int qconsume(struct queue *, void *, int);
+struct block *qcopy(struct queue *, int unused_int, uint32_t);
+struct block *qclone(struct queue *q, int header_len, int len,
+                     uint32_t offset);
+struct block *blist_clone(struct block *blist, int header_len, int len,
+                          uint32_t offset);
+int qdiscard(struct queue *, int);
+void qflush(struct queue *);
+void qfree(struct queue *);
+int qfull(struct queue *);
+struct block *qget(struct queue *);
+void qhangup(struct queue *, char *unused_char_p_t);
+int qisclosed(struct queue *);
+int qiwrite(struct queue *, void *, int);
+int qlen(struct queue *);
+void qdropoverflow(struct queue *, bool);
+void qnonblock(struct queue *, bool);
+struct queue *qopen(int unused_int, int, void (*)(void *), void *);
+int qpass(struct queue *, struct block *);
+int qpassnolim(struct queue *, struct block *);
+int qproduce(struct queue *, void *, int);
+void qputback(struct queue *, struct block *);
+long qread(struct queue *, void *, int);
+struct block *qremove(struct queue *);
+void qreopen(struct queue *);
+void qsetlimit(struct queue *, int);
+int qwindow(struct queue *);
+int qwrite(struct queue *, void *, int);
+typedef void (*qio_wake_cb_t)(struct queue *q, void *data, int filter);
+void qio_set_wake_cb(struct queue *q, qio_wake_cb_t func, void *data);
+
+void randominit(void);
+uint32_t randomread(void *, uint32_t);
+void *realloc(void *, uint32_t);
+int readmem(unsigned long offset, char *buf, unsigned long n,
+                       void *mem, size_t mem_len);
+int readnum(unsigned long off, char *buf, unsigned long n, unsigned long val,
+                       size_t size);
+int readstr(unsigned long offset, char *buf, unsigned long n, char *str);
+int readnum_int64_t(uint32_t, char *unused_char_p_t, uint32_t, int64_t, int);
+void ready(struct proc *);
+void renameproguser(char *unused_char_p_t, char *);
+void renameuser(char *unused_char_p_t, char *);
+void resrcwait(char *unused_char_p_t);
+struct proc *runproc(void);
+void (*serwrite) (char *unused_char_p_t, int);
+int setcolor(uint32_t, uint32_t, uint32_t, uint32_t);
+
+void setmalloctag(void *, uint32_t);
+int setpri(int);
+void setrealloctag(void *, uint32_t);
+char *skipslash(char *unused_char_p_t);
+void *smalloc(uint32_t);
+int splhi(void);
+int spllo(void);
+void splx(int);
+void splxpc(int);
+void swiproc(struct proc *, int);
+uint32_t _tas(uint32_t *);
+uint32_t tk2ms(uint32_t);
+#define                TK2MS(x) ((x)*(1000/HZ))
+uint64_t tod2fastticks(int64_t);
+int64_t todget(int64_t *);
+void todfix(void);
+void todsetfreq(int64_t);
+void todinit(void);
+void todset(int64_t, int64_t, int);
+int tready(void *);
+struct block *trimblock(struct block *, int unused_int, int);
+int uartgetc(void);
+void uartputc(int);
+void uartputs(char *unused_char_p_t, int);
+void unlock(spinlock_t *);
+void userinit(void);
+uint32_t userpc(void);
+void validname(char *, int);
+void validwstatname(char *);
+int walk(struct chan **, char **unused_char_pp_t, int unused_int, int, int *);
+void *xalloc(uint32_t);
+void *xallocz(uint32_t, int);
+void xfree(void *);
+void xhole(uint32_t, uint32_t);
+void xinit(void);
+int xmerge(void *, void *);
+void *xspanalloc(uint32_t, int unused_int, uint32_t);
+void xsummary(void);
+
+void validaddr(void *, uint32_t, int);
+void *vmemchr(void *, int unused_int, int);
+void hnputv(void *, int64_t);
+void hnputl(void *, uint32_t);
+void hnputs(void *, uint16_t);
+int64_t nhgetv(void *);
+uint32_t nhgetl(void *);
+uint16_t nhgets(void *);
+
+/* error messages, from inferno emu error.h */
+extern char Enoerror[];                        /* no error */
+extern char Emount[];                  /* inconsistent mount */
+extern char Eunmount[];                        /* not mounted */
+extern char Eunion[];                  /* not in union */
+extern char Emountrpc[];               /* mount rpc error */
+extern char Eshutdown[];               /* mounted device shut down */
+extern char Eowner[];                  /* not owner */
+extern char Eunknown[];                        /* unknown user or group id */
+extern char Enocreate[];               /* mounted directory forbids creation */
+extern char Enonexist[];               /* file does not exist */
+extern char Eexist[];                  /* file already exists */
+extern char Ebadsharp[];               /* unknown device in # filename */
+extern char Enotdir[];                 /* not a directory */
+extern char Eisdir[];                  /* file is a directory */
+extern char Ebadchar[];                        /* bad character in file name */
+extern char Efilename[];               /* file name syntax */
+extern char Eperm[];                   /* permission denied */
+extern char Ebadusefd[];               /* inappropriate use of fd */
+extern char Ebadarg[];                 /* bad arg in system call */
+extern char Einuse[];                  /* device or object already in use */
+extern char Eio[];                             /* i/o error */
+extern char Etoobig[];                 /* read or write too large */
+extern char Etoosmall[];               /* read or write too small */
+extern char Enetaddr[];                        /* bad network address */
+extern char Emsgsize[];                        /* message is too big for protocol */
+extern char Enetbusy[];                        /* network device is busy or allocated */
+extern char Enoproto[];                        /* network protocol not supported */
+extern char Enoport[];                 /* network port not available */
+extern char Enoifc[];                  /* bad interface or no free interface slots */
+extern char Enolisten[];               /* not announced */
+extern char Ehungup[];                 /* i/o on hungup channel */
+extern char Ebadctl[];                 /* bad process or channel control request */
+extern char Enodev[];                  /* no free devices */
+extern char Enoenv[];                  /* no free environment resources */
+extern char Ethread[];                 /* thread exited */
+extern char Enochild[];                        /* no living children */
+extern char Eioload[];                 /* i/o error in demand load */
+extern char Enovmem[];                 /* out of memory: virtual memory */
+extern char Ebadld[];                  /* illegal line discipline */
+extern char Ebadfd[];                  /* fd out of range or not open */
+extern char Eisstream[];               /* seek on a stream */
+extern char Ebadexec[];                        /* exec header invalid */
+extern char Etimedout[];               /* connection timed out */
+extern char Econrefused[];             /* connection refused */
+extern char Econinuse[];               /* connection in use */
+extern char Enetunreach[];             /* network unreachable */
+extern char Eintr[];                   /* interrupted */
+extern char Enomem[];                  /* out of memory: kernel */
+extern char Esfnotcached[];            /* subfont not cached */
+extern char Esoverlap[];               /* segments overlap */
+extern char Emouseset[];               /* mouse type already set */
+extern char Eshort[];                  /* i/o count too small */
+extern char Enobitstore[];             /* out of screen memory */
+extern char Egreg[];                   /* jim'll fix it */
+extern char Ebadspec[];                        /* bad attach specifier */
+extern char Estopped[];                        /* thread must be stopped */
+extern char Enoattach[];               /* mount/attach disallowed */
+extern char Eshortstat[];              /* stat buffer too small */
+extern char Enegoff[];                 /* negative i/o offset */
+extern char Ebadstat[];                        /* malformed stat buffer */
+extern char Ecmdargs[];                        /* wrong #args in control message */
+extern char Enofd[];                   /* no free file descriptors */
+extern char Enoctl[];                  /* unknown control request */
+extern char Eprocdied[];               /* process died */
+
+char *get_cur_genbuf(void);
+
+/* hack for now. */
+#define        NOW     tsc2msec(read_tsc())
+#define        seconds() tsc2sec(read_tsc())
+#define        milliseconds() tsc2msec(read_tsc())
+
+/* kern/drivers/dev/tab.c */
+void devtabinit();
+void devtabreset();
+
+/* kern/src/ns/parse.c */
+struct cmdbuf *parsecmd(char *p, int n);
+void cmderror(struct cmdbuf *cb, char *s);
+struct cmdtab *lookupcmd(struct cmdbuf *cb, struct cmdtab *ctab, int nctab);
+
+/* kern/src/ns/sysfile.c */
+int newfd(struct chan *c, int oflags);
+struct chan *fdtochan(struct fd_table *fdt, int fd, int mode, int chkmnt,
+                      int iref);
+long kchanio(void *vc, void *buf, int n, int mode);
+int openmode(uint32_t o);
+void fdclose(struct fd_table *fdt, int fd);
+int syschdir(char *path);
+int grpclose(struct fd_table *fdt, int fd);
+int sysclose(int fd);
+int syscreate(char *path, int mode, uint32_t perm);
+int sysdup(int old);
+int sys_dup_to(struct proc *from_proc, unsigned int from_fd,
+               struct proc *to_proc, unsigned int to_fd);
+int sysfstat(int fd, uint8_t*, int n);
+int sysfstatakaros(int fd, struct kstat *);
+char *sysfd2path(int fd);
+int sysfauth(int fd, char *aname);
+int sysfversion(int fd, unsigned int msize, char *vers, unsigned int arglen);
+int syspipe(int fd[2]);
+int sysfwstat(int fd, uint8_t * buf, int n);
+long bindmount(struct chan *c, char *old, int flag, char *spec);
+int sysbind(char *new, char *old, int flags);
+int sysmount(int fd, int afd, char *old, int flags, char *spec);
+int sysunmount(char *old, char *new);
+int sysopen(char *path, int mode);
+long unionread(struct chan *c, void *va, long n);
+void read_exactly_n(struct chan *c, void *vp, long n);
+long sysread(int fd, void *va, long n);
+long syspread(int fd, void *va, long n, int64_t off);
+int sysremove(char *path);
+int64_t sysseek(int fd, int64_t off, int whence);
+void validstat(uint8_t * s, int n, int slashok);
+int sysstat(char *path, uint8_t*, int n);
+int sysstatakaros(char *path, struct kstat *);
+long syswrite(int fd, void *va, long n);
+long syspwrite(int fd, void *va, long n, int64_t off);
+int syswstat(char *path, uint8_t * buf, int n);
+struct dir *chandirstat(struct chan *c);
+struct dir *sysdirstat(char *name);
+struct dir *sysdirfstat(int fd);
+int sysdirwstat(char *name, struct dir *dir);
+int sysdirfwstat(int fd, struct dir *dir);
+long sysdirread(int fd, struct kdirent **d);
+int sysiounit(int fd);
+void print_chaninfo(struct chan *ch);
+int plan9setup(struct proc *new_proc, struct proc *parent, int flags);
+int iseve(void);
+int fd_getfl(int fd);
+int fd_setfl(int fd, int flags);
+
+/* kern/drivers/dev/srv.c */
+char *srvname(struct chan *c);
+
+/* kern/src/eipconv.c. Put them here or face real include hell. */
+void printqid(void (*putch) (int, void **), void **putdat, struct qid *q);
+void printcname(void (*putch) (int, void **), void **putdat, struct cname *c);
+void printchan(void (*putch) (int, void **), void **putdat, struct chan *c);
+
+static inline int abs(int a)
 {
-       MAXPOOL         = 8,
-};
+       if (a < 0)
+               return -a;
+       return a;
+}
 
-extern Pool*   mainmem;
-extern Pool*   heapmem;
-extern Pool*   imagmem;
+extern char *eve;
+extern unsigned int qiomaxatomic;
 
-/* queue state bits,  Qmsg, Qcoalesce, and Qkick can be set in qopen */
-enum
-{
-       /* Queue.state */
-       Qstarve         = (1<<0),       /* consumer starved */
-       Qmsg            = (1<<1),       /* message stream */
-       Qclosed         = (1<<2),       /* queue has been closed/hungup */
-       Qflow           = (1<<3),       /* producer flow controlled */
-       Qcoalesce       = (1<<4),       /* coallesce packets on read */
-       Qkick           = (1<<5),       /* always call the kick routine after qwrite */
-};
-
-#define DEVDOTDOT -1
+/* special sections */
+#define __devtab  __attribute__((__section__(".devtab")))
 
-#pragma        varargck        argpos  print   1
-#pragma        varargck        argpos  snprint 3
-#pragma        varargck        argpos  seprint 3
-#pragma        varargck        argpos  sprint  2
-#pragma        varargck        argpos  fprint  2
-#pragma        varargck        argpos  iprint  1
-#pragma        varargck        argpos  panic   1
-#pragma        varargck        argpos  kwerrstr        1
-#pragma        varargck        argpos  kprint  1
-
-#pragma        varargck        type    "lld"   vlong
-#pragma        varargck        type    "llx"   vlong
-#pragma        varargck        type    "lld"   uvlong
-#pragma        varargck        type    "llx"   uvlong
-#pragma        varargck        type    "lx"    void*
-#pragma        varargck        type    "ld"    long
-#pragma        varargck        type    "lx"    long
-#pragma        varargck        type    "ld"    ulong
-#pragma        varargck        type    "lx"    ulong
-#pragma        varargck        type    "d"     int
-#pragma        varargck        type    "x"     int
-#pragma        varargck        type    "c"     int
-#pragma        varargck        type    "C"     int
-#pragma        varargck        type    "d"     uint
-#pragma        varargck        type    "x"     uint
-#pragma        varargck        type    "c"     uint
-#pragma        varargck        type    "C"     uint
-#pragma        varargck        type    "f"     double
-#pragma        varargck        type    "e"     double
-#pragma        varargck        type    "g"     double
-#pragma        varargck        type    "s"     char*
-#pragma        varargck        type    "S"     Rune*
-#pragma        varargck        type    "r"     void
-#pragma        varargck        type    "%"     void
-#pragma        varargck        type    "I"     uchar*
-#pragma        varargck        type    "V"     uchar*
-#pragma        varargck        type    "E"     uchar*
-#pragma        varargck        type    "M"     uchar*
-#pragma        varargck        type    "p"     void*
-#pragma        varargck        type    "q"     char*
+#endif /* ROS_KERN_NS_H */