From: nemo@gsyc.escet.urjc.es
To: 9fans@cse.psu.edu
Subject: [9fans] ide fs patch for the current plan9 version
Date: Wed, 16 May 2001 15:02:52 +0200 [thread overview]
Message-ID: <20010516125649.67D48199E6@mail.cse.psu.edu> (raw)
[-- Attachment #1: Type: text/plain, Size: 1121 bytes --]
Hi,
this is just edorman's patch for the fs kernel to let it work
with ide disks. Unlike the original patch as posted in 9fans,
this one can be `applied' to the current fs
kernel source. There is almost no change actually.
I don't know if the patch might break the fs code for regular scsi disks,
since it is `removing' some code which seems to be working on a scsi-based
fs. I couldn't try because I don't have scsi disks around.
In any case, I'm using the current fs code w/ this patch applied and it
seems to work ok.
My configuration string (if I remember well) is ch0fh2. The
block size is 16K, but you may change the define for RBUFSIZE in
plan9pc/dat.h.
I'll try to keep the patch up-to-date wrt the distributed fs code
until the day when the new integrated fs code be done and released.
To apply the patch, I suggest you create two directories
./idefs/port and ./idefs/plan9pc, then run rc idefs.rc on ./idefs and
bind -bc ./idefs/port /sys/src/fs/port
bind -bc ./idefs/plan9pc /sys/src/fs/plan9pc
after that you can mk in /sys/src/fs/plan9pc.
hope this helps
[-- Attachment #2: Type: message/rfc822, Size: 105984 bytes --]
# To unbundle, run this file
echo plan9pc/dat.h
sed 's/.//' >plan9pc/dat.h <<'//GO.SYSIN DD plan9pc/dat.h'
-#define RBUFSIZE (16*1024) /* raw buffer size */
-#define DSIZE 546000
-
-#include "../port/portdat.h"
-
-extern Mach mach0;
-
-typedef struct Segdesc Segdesc;
-struct Segdesc
-{
- ulong d0;
- ulong d1;
-};
-
-typedef struct Mbank {
- ulong base;
- ulong limit;
-} Mbank;
-
-#define MAXBANK 8
-
-typedef struct Mconf {
- Lock;
- Mbank bank[MAXBANK];
- int nbank;
- ulong topofmem;
-} Mconf;
-extern Mconf mconf;
-
-/*
- * a parsed plan9.ini line
- */
-#define ISAOPTLEN 16
-#define NISAOPT 8
-
-typedef struct ISAConf {
- char type[NAMELEN];
- ulong port;
- ulong irq;
- ulong dma;
- ulong mem;
- ulong size;
- ulong freq;
-
- int nopt;
- char opt[NISAOPT][ISAOPTLEN];
-} ISAConf;
-
-typedef struct Pcidev Pcidev;
-
-extern char nvrfile[128];
//GO.SYSIN DD plan9pc/dat.h
echo plan9pc/devata.c
sed 's/.//' >plan9pc/devata.c <<'//GO.SYSIN DD plan9pc/devata.c'
-#include "all.h"
-#include "io.h"
-#include "mem.h"
-
-
-/* There were some chunks of code commented out in the originial
- ide patches for version 2 which are not commented out in version 3
- I leave those pieces of code commented out here too.
- */
-
-#define DEBUG 0
-#define DPRINT if(DEBUG)print
-#define IDEBUG 0
-#define IDPRINT if(IDEBUG)print
-
-typedef struct Drive Drive;
-typedef struct Ident Ident;
-typedef struct Controller Controller;
-
-enum
-{
- /* ports */
- Pbase0= 0x1F0, /* primary */
- Pbase1= 0x170, /* secondary */
- Pbase2= 0x1E8, /* tertiary */
- Pbase3= 0x168, /* quaternary */
- Pdata= 0, /* data port (16 bits) */
- Perror= 1, /* error port (read) */
- Eabort= (1<<2),
- Pfeature= 1, /* buffer mode port (write) */
- Pcount= 2, /* sector count port */
- Psector= 3, /* sector number port */
- Pcyllsb= 4, /* least significant byte cylinder # */
- Pcylmsb= 5, /* most significant byte cylinder # */
- Pdh= 6, /* drive/head port */
- DHmagic= 0xA0,
- DHslave= 0x10,
- Pstatus= 7, /* status port (read) */
- Sbusy= (1<<7),
- Sready= (1<<6),
- Sdrq= (1<<3),
- Serr= (1<<0),
- Pcmd= 7, /* cmd port (write) */
-
- /* commands */
- Crecal= 0x10,
- Cread= 0x20,
- Cwrite= 0x30,
- Cident= 0xEC,
- Cident2= 0xFF, /* pseudo command for post Cident interrupt */
- Csetbuf= 0xEF,
-
- Cpktcmd= 0xA0,
- Cidentd= 0xA1,
- Ctur= 0x00,
- Creqsense= 0x03,
- Ccapacity= 0x25,
- Cread2= 0x28,
- Cwrite2= 0x2A,
-
- ATAtimo= 6000, /* ms to wait for things to complete */
- ATAPItimo= 10000,
-
- NCtlr= 4,
- NDrive= NCtlr*2,
-
- Maxloop= 1000000,
-};
-
-/*
- * ident sector from drive. this is from ANSI X3.221-1994
- */
-struct Ident
-{
- ushort config; /* general configuration info */
- ushort cyls; /* # of cylinders (default) */
- ushort reserved0;
- ushort heads; /* # of heads (default) */
- ushort b2t; /* unformatted bytes/track */
- ushort b2s; /* unformated bytes/sector */
- ushort s2t; /* sectors/track (default) */
- ushort reserved1[3];
-/* 10 */
- ushort serial[10]; /* serial number */
- ushort type; /* buffer type */
- ushort bsize; /* buffer size/512 */
- ushort ecc; /* ecc bytes returned by read long */
- ushort firm[4]; /* firmware revision */
- ushort model[20]; /* model number */
-/* 47 */
- ushort s2i; /* number of sectors/interrupt */
- ushort dwtf; /* double word transfer flag */
- ushort capabilities;
- ushort reserved2;
- ushort piomode;
- ushort dmamode;
- ushort cvalid; /* (cvald&1) if next 4 words are valid */
- ushort ccyls; /* current # cylinders */
- ushort cheads; /* current # heads */
- ushort cs2t; /* current sectors/track */
- ushort ccap[2]; /* current capacity in sectors */
- ushort cs2i; /* current number of sectors/interrupt */
-/* 60 */
- ushort lbasecs[2]; /* # LBA user addressable sectors */
- ushort dmasingle;
- ushort dmadouble;
-/* 64 */
- ushort reserved3[64];
- ushort vendor[32]; /* vendor specific */
- ushort reserved4[96];
-};
-
-enum {
- Maxxfer = 16*1024, /* maximum transfer size/cmd */
- Npart = 8+2, /* 8 sub partitions, disk, and partition */
-};
-
-typedef struct {
- ulong start;
- ulong end;
- char name[NAMELEN+1];
-} Partition;
-
-typedef struct {
- int online;
- int npart; /* number of real partitions */
- Partition p[Npart];
- ulong offset;
- Partition *current; /* current partition */
-
- ulong cap; /* total sectors */
- int bytes; /* bytes/sector */
- int sectors; /* sectors/track */
- int heads; /* heads/cyl */
- long cyl; /* cylinders/drive */
-
- char lba; /* true if drive has logical block addressing */
- char multi; /* non-zero if drive does multiple block xfers */
-} Disc;
-
-/*
- * an ata drive
- */
-struct Drive
-{
- Controller *cp;
- uchar driveno;
- uchar dh;
- uchar atapi; /* ATAPI */
- uchar drqintr; /* ATAPI */
- ulong vers; /* ATAPI */
-
- int partok;
-
- Disc;
-};
-
-/*
- * a controller for 2 drives
- */
-struct Controller
-{
- QLock;
- int pbase; /* base port */
- uchar ctlrno;
-
- /*
- * current operation
- */
- int cmd; /* current command */
- uchar cmdblk[12]; /* ATAPI */
- int len; /* ATAPI */
- int count; /* ATAPI */
- uchar lastcmd; /* debugging info */
- uchar *buf; /* xfer buffer */
- int tcyl; /* target cylinder */
- int thead; /* target head */
- int tsec; /* target sector */
- int tbyte; /* target byte */
- int nsecs; /* length of transfer (sectors) */
- int sofar; /* sectors transferred so far */
- int status;
- int error;
- Drive *dp; /* drive being accessed */
-};
-
-static int atactlrmask;
-static Controller *atactlr[NCtlr];
-static int atadrivemask;
-static Drive *atadrive[NDrive];
-static int pbase[NCtlr] = {
- Pbase0, Pbase1, Pbase2, Pbase3,
-};
-static int defirq[NCtlr] = {
- 14, 15, 0, 0,
-};
-
-static void ataintr(Ureg*, void*);
-static long ataxfer(Drive*, Partition*, int, ulong, long);
-static int ataident(Drive*);
-static Drive* atapart(Drive*);
-static int ataparams(Drive*);
-static void atarecal(Drive*);
-static int ataprobe(Drive*, int, int, int);
-static Drive* atapipart(Drive*);
-static void atapiintr(Controller*);
-static long atapiio(Drive*, long);
-
-static void
-atactlrprobe(int ctlrno, int irq)
-{
- Controller *ctlr;
- Drive *drive;
- int driveno, port;
-
- if(atactlrmask & (1<<ctlrno))
- return;
- atactlrmask |= 1<<ctlrno;
-
- port = pbase[ctlrno];
- outb(port+Pdh, DHmagic);
- delay(1);
- if((inb(port+Pdh) & 0xFF) != DHmagic){
- DPRINT("ata%d: DHmagic not ok\n", ctlrno);
- return;
- }
- DPRINT("ata%d: DHmagic ok\n", ctlrno);
-
- atactlr[ctlrno] = ialloc(sizeof(Controller), 0);
- ctlr = atactlr[ctlrno];
- ctlr->pbase = port;
- ctlr->ctlrno = ctlrno;
- ctlr->buf = ialloc(Maxxfer, 0);
- inb(ctlr->pbase+Pstatus);
- setvec(irq, ataintr, ctlr);
-
- driveno = ctlrno*2;
- atadrive[driveno] = ialloc(sizeof(Drive), 0);
- drive = atadrive[driveno];
- drive->cp = ctlr;
- drive->driveno = driveno;
- drive->dh = DHmagic;
-
- driveno++;
- atadrive[driveno] = ialloc(sizeof(Drive), 0);
- drive = atadrive[driveno];
- drive->cp = ctlr;
- drive->driveno = driveno;
- drive->dh = DHmagic|DHslave;
-}
-
-static Drive*
-atadriveprobe(int driveno)
-{
- Drive *drive;
- int ctlrno;
- ISAConf isa;
-
- ctlrno = driveno/2;
- if(atactlr[ctlrno] == 0){
- if(atactlrmask & (1<<ctlrno))
- return 0;
- memset(&isa, 0, sizeof(ISAConf));
- if(isaconfig("ata", ctlrno, &isa) == 0)
- return 0;
- if(ctlrno && isa.irq)
- atactlrprobe(ctlrno, Int0vec+isa.irq);
- if(atactlr[ctlrno] == 0)
- return 0;
- }
-
- drive = atadrive[driveno];
- drive->driveno = driveno;
- if(drive->online == 0){
- if(atadrivemask & (1<<driveno))
- return 0;
- atadrivemask |= 1<<driveno;
- if(ataparams(drive))
- return 0;
- if(drive->lba)
- print("hd%d: LBA %lud sectors\n",
- drive->driveno, drive->cap);
- else
- print("hd%d: CHS %ld/%d/%d %lud sectors\n",
- drive->driveno, drive->cyl, drive->heads,
- drive->sectors, drive->cap);
- drive->online = 1;
- }
-
- return atapart(drive);
-}
-
-int
-atainit(void)
-{
- ISAConf isa;
- int ctlrno;
-
- for(ctlrno = 0; ctlrno < NCtlr; ctlrno++){
- memset(&isa, 0, sizeof(ISAConf));
- if(isaconfig("ata", ctlrno, &isa) == 0 && ctlrno > 1)
- continue;
- if(isa.irq == 0 && (isa.irq = defirq[ctlrno]) == 0)
- continue;
- atactlrprobe(ctlrno, Int0vec+isa.irq);
- }
- DPRINT("atainit: mask 0x%ux 0x%ux\n", atactlrmask, atadrivemask);
-
- return 0xFF;
-}
-
-long
-ataseek(int driveno, long offset)
-{
- Drive *drive;
-// more permissive for ide disks
- drive = atadrive[driveno];
- if (drive->online == 0)
- return -1;
-
-// real check was
-// if((drive = atadriveprobe(driveno)) == 0)
-// return -1;
-
- drive->offset = offset;
- return offset;
-}
-
-/*
- * did an interrupt happen?
- */
-static void
-atawait(Controller *cp, int timo)
-{
- ulong start;
- int x;
-
- x = spllo();
- start = m->ticks;
- while(TK2MS(m->ticks - start) < timo){
- if(cp->cmd == 0)
- break;
- if(cp->cmd == Cident2 && TK2MS(m->ticks - start) >= 1000)
- break;
- }
- if(TK2MS(m->ticks - start) >= timo){
- DPRINT("atawait timed out 0x%ux\n", inb(cp->pbase+Pstatus));
- ataintr(0, cp);
- }
- splx(x);
-}
-
-int
-setatapart(int driveno, char *p)
-{
- Partition *pp;
- Drive *dp;
-
- if((dp = atadriveprobe(driveno)) == 0)
- return 0;
-
- for(pp = dp->p; pp < &dp->p[dp->npart]; pp++)
- if(strcmp(pp->name, p) == 0){
- dp->current = pp;
- return 1;
- }
- return 0;
-}
-
-long
-ataread(int driveno, void *a, long n)
-{
- Drive *dp;
- long rv, i;
- int skip;
- uchar *aa = a;
- Partition *pp;
- Controller *cp;
-
-// for ide
- dp = atadrive[ driveno ];
- if( dp->online == 0 )
- return 0;
-
-// real code was
-// if((dp = atadriveprobe(driveno)) == 0)
-// return 0;
-
- pp = dp->current;
-// can ide leave pp as nil?
-// if(pp == 0)
-// return -1;
- cp = dp->cp;
-
- skip = dp->offset % dp->bytes;
- for(rv = 0; rv < n; rv += i){
- i = ataxfer(dp, pp, Cread, dp->offset+rv-skip, n-rv+skip);
- if(i == 0)
- break;
- if(i < 0)
- return -1;
- i -= skip;
- if(i > n - rv)
- i = n - rv;
- memmove(aa+rv, cp->buf + skip, i);
- skip = 0;
- }
- dp->offset += rv;
-
- return rv;
-}
-
-long
-atawrite(int driveno, void *a, long n)
-{
- Drive *dp;
- long rv, i, partial;
- uchar *aa = a;
- Partition *pp;
- Controller *cp;
-
-// ide
- dp = atadrive[ driveno ];
- if( dp->online == 0 )
- return 0;
-// if((dp = atadriveprobe(driveno)) == 0)
-// return 0;
-
- pp = dp->current;
-// if(pp == 0)
-// return -1;
- cp = dp->cp;
-
- /*
- * if not starting on a sector boundary,
- * read in the first sector before writing
- * it out.
- */
- partial = dp->offset % dp->bytes;
- if(partial){
- ataxfer(dp, pp, Cread, dp->offset-partial, dp->bytes);
- if(partial+n > dp->bytes)
- rv = dp->bytes - partial;
- else
- rv = n;
- memmove(cp->buf+partial, aa, rv);
- if(ataxfer(dp, pp, Cwrite, dp->offset-partial, dp->bytes) < 0)
- return -1;
- } else
- rv = 0;
-
- /*
- * write out the full sectors
- */
- partial = (n - rv) % dp->bytes;
- n -= partial;
- for(; rv < n; rv += i){
- i = n - rv;
- if(i > Maxxfer)
- i = Maxxfer;
- memmove(cp->buf, aa+rv, i);
- i = ataxfer(dp, pp, Cwrite, dp->offset+rv, i);
- if(i == 0)
- break;
- if(i < 0)
- return -1;
- }
-
- /*
- * if not ending on a sector boundary,
- * read in the last sector before writing
- * it out.
- */
- if(partial){
- if(ataxfer(dp, pp, Cread, dp->offset+rv, dp->bytes) < 0)
- return -1;
- memmove(cp->buf, aa+rv, partial);
- if(ataxfer(dp, pp, Cwrite, dp->offset+rv, dp->bytes) < 0)
- return -1;
- rv += partial;
- }
- dp->offset += rv;
- return rv;
-}
-
-/*
- * wait for the controller to be ready to accept a command
- */
-static int
-cmdreadywait(Drive *drive)
-{
- ulong end;
- uchar dh, status;
- Controller *ctlr;
-
- ctlr = drive->cp;
- end = m->ticks+MS2TK(10)+1;
- dh = (inb(ctlr->pbase+Pdh) & DHslave)^(drive->dh & DHslave);
-
- status = 0;
- while(m->ticks < end){
- status = inb(ctlr->pbase+Pstatus);
- if(status & Sbusy)
- continue;
- if(dh){
- outb(ctlr->pbase+Pdh, drive->dh);
- dh = 0;
- continue;
- }
- if(drive->atapi || (status & Sready))
- return 0;
- }
- USED(status);
-
- DPRINT("hd%d: cmdreadywait failed 0x%ux\n", drive->driveno, status);
- outb(ctlr->pbase+Pdh, DHmagic);
- return -1;
-}
-
-/*
- * transfer a number of sectors. ataintr will perform all the iterative
- * parts.
- */
-static long
-ataxfer(Drive *dp, Partition *pp, int cmd, ulong start, long len)
-{
- Controller *cp;
- long lsec;
- int loop;
-
- if(dp->online == 0){
- DPRINT("hd%d: disk not on line\n", dp->driveno);
- return -1;
- }
-
- /*
- * cut transfer size down to disk buffer size
- */
- start = start / dp->bytes;
- if(len > Maxxfer)
- len = Maxxfer;
- len = (len + dp->bytes - 1) / dp->bytes;
-
- /*
- * calculate physical address
- */
- cp = dp->cp;
- if (pp){ // ide did not check; was assumed non-nil by 3rd ed fs.
- lsec = start + pp->start;
- if(lsec >= pp->end){
- DPRINT("hd%d: read past end of partition\n", dp->driveno);
- return 0;
- }
- } else
- lsec = start;
-
- if(dp->lba){
- cp->tsec = lsec & 0xff;
- cp->tcyl = (lsec>>8) & 0xffff;
- cp->thead = (lsec>>24) & 0xf;
- } else {
- cp->tcyl = lsec/(dp->sectors*dp->heads);
- cp->tsec = (lsec % dp->sectors) + 1;
- cp->thead = (lsec/dp->sectors) % dp->heads;
- }
-
- /*
- * can't xfer past end of disk
- */
- if (pp) // ide did not check
- if(lsec+len > pp->end)
- len = pp->end - lsec;
- cp->nsecs = len;
-
- if(dp->atapi){
- if(cmd == Cread)
- cp->cmd = Cread2;
- else
- cp->cmd = Cwrite2;
- cp->dp = dp;
- cp->sofar = 0;
- cp->status = 0;
- return atapiio(dp, lsec);
- }
-
- if(cmdreadywait(dp) < 0)
- return -1;
-
- /*
- * start the transfer
- */
- cp->cmd = cmd;
- cp->dp = dp;
- cp->sofar = 0;
- cp->status = 0;
- DPRINT("hd%d: xfer:\ttcyl %d, tsec %d, thead %d\n",
- dp->driveno, cp->tcyl, cp->tsec, cp->thead);
- DPRINT("\tnsecs %d, sofar %d\n", cp->nsecs, cp->sofar);
- outb(cp->pbase+Pcount, cp->nsecs);
- outb(cp->pbase+Psector, cp->tsec);
- outb(cp->pbase+Pdh, dp->dh | (dp->lba<<6) | cp->thead);
- outb(cp->pbase+Pcyllsb, cp->tcyl);
- outb(cp->pbase+Pcylmsb, cp->tcyl>>8);
- outb(cp->pbase+Pcmd, cmd);
-
- if(cmd == Cwrite){
- loop = 0;
- while((inb(cp->pbase+Pstatus) & Sdrq) == 0)
- if(++loop > 10000)
- panic("ataxfer");
- outss(cp->pbase+Pdata, cp->buf, dp->bytes/2);
- }
-
- atawait(cp, ATAtimo);
-
- if(cp->status & Serr){
- DPRINT("hd%d: err: status 0x%ux, err 0x%ux\n",
- dp->driveno, cp->status, cp->error);
- DPRINT("\ttcyl %d, tsec %d, thead %d\n",
- cp->tcyl, cp->tsec, cp->thead);
- DPRINT("\tnsecs %d, sofar %d\n", cp->nsecs, cp->sofar);
- return -1;
- }
-
- return cp->nsecs*dp->bytes;
-}
-
-static int
-isatapi(Drive *drive)
-{
- Controller *cp;
-
- cp = drive->cp;
- outb(cp->pbase+Pdh, drive->dh);
- IDPRINT("hd%d: isatapi %d\n", drive->driveno, drive->atapi);
- outb(cp->pbase+Pcmd, 0x08);
- drive->atapi = 1;
- if(cmdreadywait(drive)){
- drive->atapi = 0;
- return 0;
- }
- drive->atapi = 0;
- drive->bytes = 512;
- microdelay(1);
- if(inb(cp->pbase+Pstatus)){
- IDPRINT("hd%d: isatapi status 0x%ux\n",
- drive->driveno, inb(cp->pbase+Pstatus));
- return 0;
- }
- if(inb(cp->pbase+Pcylmsb) != 0xEB || inb(cp->pbase+Pcyllsb) != 0x14){
- IDPRINT("hd%d: isatapi cyl 0x%ux 0x%ux\n",
- drive->driveno, inb(cp->pbase+Pcylmsb), inb(cp->pbase+Pcyllsb));
- return 0;
- }
- drive->atapi = 1;
-
- return 1;
-}
-
-/*
- * get parameters from the drive
- */
-static int
-ataident(Drive *dp)
-{
- Controller *cp;
- Ident *ip;
- ulong lbasecs;
- char id[21];
-
- dp->bytes = 512;
- cp = dp->cp;
-
-retryatapi:
- cp->nsecs = 1;
- cp->sofar = 0;
- cp->dp = dp;
- outb(cp->pbase+Pdh, dp->dh);
- microdelay(1);
- if(inb(cp->pbase+Pcylmsb) == 0xEB && inb(cp->pbase+Pcyllsb) == 0x14){
- dp->atapi = 1;
- cp->cmd = Cidentd;
- }
- else
- cp->cmd = Cident;
- outb(cp->pbase+Pcmd, cp->cmd);
-
- IDPRINT("hd%d: ident command 0x%ux sent\n", dp->driveno, cp->cmd);
- atawait(cp, ATAPItimo);
-
- if(cp->status & Serr){
- IDPRINT("hd%d: bad disk ident status\n", dp->driveno);
- if(cp->error & Eabort){
- if(isatapi(dp) && cp->cmd != Cidentd)
- goto retryatapi;
- }
- return -1;
- }
-
- atawait(cp, ATAtimo);
-
- ip = (Ident*)cp->buf;
- memmove(id, ip->model, sizeof(id)-1);
- id[sizeof(id)-1] = 0;
-
- IDPRINT("hd%d: config 0x%ux capabilities 0x%ux\n",
- dp->driveno, ip->config, ip->capabilities);
- if(dp->atapi){
- if((ip->config & 0x0060) == 0x0020)
- dp->drqintr = 1;
- if((ip->config & 0x1F00) == 0x0000)
- dp->atapi = 2;
- }
-
- lbasecs = (ip->lbasecs[0]) | (ip->lbasecs[1]<<16);
- if((ip->capabilities & (1<<9)) && (lbasecs & 0xf0000000) == 0){
- dp->lba = 1;
- dp->cap = lbasecs;
- } else {
- dp->lba = 0;
-
- if(ip->cvalid&(1<<0)){
- /* use current settings */
- dp->cyl = ip->ccyls;
- dp->heads = ip->cheads;
- dp->sectors = ip->cs2t;
- }
- else{
- /* use default (unformatted) settings */
- dp->cyl = ip->cyls;
- dp->heads = ip->heads;
- dp->sectors = ip->s2t;
- }
-
- /*
- * Very strange, but some old non-LBA discs report
- * sectors > 32.
- if(dp->heads >= 64 || dp->sectors >= 32)
- return -1;
- */
- dp->cap = dp->cyl * dp->heads * dp->sectors;
- }
- IDPRINT("hd%d: %s lba/atapi/drqintr: %d/%d/%d C/H/S: %ld/%d/%d CAP: %ld\n",
- dp->driveno, id,
- dp->lba, dp->atapi, dp->drqintr,
- dp->cyl, dp->heads, dp->sectors,
- dp->cap);
-
- return 0;
-}
-
-/*
- * probe the given sector to see if it exists
- */
-static int
-ataprobe(Drive *dp, int cyl, int sec, int head)
-{
- Controller *cp;
-
- cp = dp->cp;
- if(cmdreadywait(dp) < 0)
- return -1;
-
- /*
- * start the transfer
- */
- cp->cmd = Cread;
- cp->dp = dp;
- cp->sofar = 0;
- cp->nsecs = 1;
- cp->status = 0;
- outb(cp->pbase+Pcount, 1);
- outb(cp->pbase+Psector, sec+1);
- outb(cp->pbase+Pdh, dp->dh | (dp->lba<<6) | head);
- outb(cp->pbase+Pcyllsb, cyl);
- outb(cp->pbase+Pcylmsb, cyl>>8);
- outb(cp->pbase+Pcmd, Cread);
-
- atawait(cp, ATAtimo);
-
- if(cp->status & Serr)
- return -1;
-
- return 0;
-}
-
-/*
- * figure out the drive parameters
- */
-static int
-ataparams(Drive *dp)
-{
- int i, hi, lo;
-
- /*
- * first try the easy way, ask the drive and make sure it
- * isn't lying.
- */
- dp->bytes = 512;
- if(ataident(dp) < 0)
- return -1;
- if(dp->atapi)
- return 0;
- if(dp->lba){
- i = dp->cap - 1;
- if(ataprobe(dp, (i>>8)&0xffff, (i&0xff)-1, (i>>24)&0xf) == 0)
- return 0;
- } else {
- if(ataprobe(dp, dp->cyl-1, dp->sectors-1, dp->heads-1) == 0)
- return 0;
- }
-
- IDPRINT("hd%d: ataparam: cyl %ld sectors %d heads %d\n",
- dp->driveno, dp->cyl, dp->sectors, dp->heads);
- /*
- * the drive lied, determine parameters by seeing which ones
- * work to read sectors.
- */
- dp->lba = 0;
- for(i = 0; i < 16; i++)
- if(ataprobe(dp, 0, 0, i) < 0)
- break;
- dp->heads = i;
- for(i = 0; i < 64; i++)
- if(ataprobe(dp, 0, i, 0) < 0)
- break;
- dp->sectors = i;
- for(i = 512; ; i += 512)
- if(ataprobe(dp, i, dp->sectors-1, dp->heads-1) < 0)
- break;
- lo = i - 512;
- hi = i;
- for(; hi-lo > 1;){
- i = lo + (hi - lo)/2;
- if(ataprobe(dp, i, dp->sectors-1, dp->heads-1) < 0)
- hi = i;
- else
- lo = i;
- }
- dp->cyl = lo + 1;
- dp->cap = dp->cyl * dp->heads * dp->sectors;
-
- if(dp->cyl == 0 || dp->heads == 0 || dp->sectors == 0)
- return -1;
-
- return 0;
-}
-
-static Drive*
-atapart(Drive *dp)
-{
- Partition *pp;
-
- if(dp->partok)
- return dp;
-
- /*
- * we always have a partition for the whole disk
- */
- pp = &dp->p[0];
- strcpy(pp->name, "disk");
- dp->npart = 1;
- pp->start = 0;
- if(dp->atapi)
- return atapipart(dp);
- pp->end = dp->cap;
- dp->partok = 1;
-
- return dp;
-}
-
-/*
- * we get an interrupt for every sector transferred
- */
-static void
-ataintr(Ureg*, void *arg)
-{
- Controller *cp;
- Drive *dp;
- long loop;
-
- cp = arg;
- if((dp = cp->dp) == 0)
- return;
-
- loop = 0;
- while((cp->status = inb(cp->pbase+Pstatus)) & Sbusy)
- if(++loop > Maxloop){
- print("hd%d: intr busy: status 0x%ux\n", dp->driveno, cp->status);
- break;
- }
- switch(cp->cmd){
- case Cwrite:
- if(cp->status & Serr){
- cp->error = inb(cp->pbase+Perror);
- cp->cmd = 0;
- return;
- }
- cp->sofar++;
- if(cp->sofar < cp->nsecs){
- loop = 0;
- while((inb(cp->pbase+Pstatus) & Sdrq) == 0)
- if(++loop > 10000){
- print("ataintr 1");
- cp->cmd = 0;
- return;
- }
- outss(cp->pbase+Pdata, &cp->buf[cp->sofar*dp->bytes],
- dp->bytes/2);
- } else{
- cp->cmd = 0;
- }
- break;
- case Cread:
- case Cident:
- case Cidentd:
- if(cp->status & Serr){
- cp->cmd = 0;
- cp->error = inb(cp->pbase+Perror);
- return;
- }
- loop = 0;
- while((inb(cp->pbase+Pstatus) & Sdrq) == 0)
- if(++loop > Maxloop){
- print("hd%d: intr drq: cmd %ux status 0x%ux",
- dp->driveno, cp->cmd, inb(cp->pbase+Pstatus));
- cp->cmd = 0;
- return;
- }
- inss(cp->pbase+Pdata, &cp->buf[cp->sofar*dp->bytes],
- dp->bytes/2);
- cp->sofar++;
- if(cp->sofar >= cp->nsecs){
- if(cp->cmd == Cident && (cp->status & Sready) == 0)
- cp->cmd = Cident2; /* sometimes we get a second intr */
- else
- cp->cmd = 0;
- inb(cp->pbase+Pstatus);
- }
- break;
- case Csetbuf:
- case Cident2:
- cp->cmd = 0;
- break;
- case Cpktcmd:
- atapiintr(cp);
- break;
- default:
- cp->cmd = 0;
- break;
- }
-}
-
-static int
-atapiexec(Drive *dp)
-{
- Controller *cp;
- int loop, s;
-
- cp = dp->cp;
-
- if(cmdreadywait(dp))
- return -1;
-
- s = splhi();
- cp->sofar = 0;
- cp->error = 0;
- cp->cmd = Cpktcmd;
- outb(cp->pbase+Pcount, 0);
- outb(cp->pbase+Psector, 0);
- outb(cp->pbase+Pfeature, 0);
- outb(cp->pbase+Pcyllsb, cp->len);
- outb(cp->pbase+Pcylmsb, cp->len>>8);
- outb(cp->pbase+Pdh, dp->dh);
- outb(cp->pbase+Pcmd, cp->cmd);
-
- if(dp->drqintr == 0){
- microdelay(1);
- for(loop = 0; (inb(cp->pbase+Pstatus) & (Serr|Sdrq)) == 0; loop++){
- if(loop < 10000)
- continue;
- panic("hd%d: cmddrqwait: cmd=0x%ux status=0x%ux\n",
- dp->driveno, cp->cmd, inb(cp->pbase+Pstatus));
- }
- outss(cp->pbase+Pdata, cp->cmdblk, sizeof(cp->cmdblk)/2);
- }
- splx(s);
-
- atawait(cp, ATAPItimo);
-
- if(cp->status & Serr){
- DPRINT("hd%d: Bad packet command 0x%ux, error 0x%ux\n",
- dp->driveno, cp->cmdblk[0], cp->error);
- return -1;
- }
-
- return 0;
-}
-
-static long
-atapiio(Drive *dp, long lba)
-{
- int n;
- Controller *cp;
-
- cp = dp->cp;
-
- n = cp->nsecs*dp->bytes;
- cp->len = n;
- cp->count = 0;
- memset(cp->cmdblk, 0, 12);
- cp->cmdblk[0] = cp->cmd;
- cp->cmdblk[2] = lba >> 24;
- cp->cmdblk[3] = lba >> 16;
- cp->cmdblk[4] = lba >> 8;
- cp->cmdblk[5] = lba;
- cp->cmdblk[7] = cp->nsecs>>8;
- cp->cmdblk[8] = cp->nsecs;
- if(atapiexec(dp))
- return -1;
- if(cp->count != n)
- print("hd%d: short read %d != %d\n", dp->driveno, cp->count, n);
-
- return n;
-}
-
-static Drive*
-atapipart(Drive *dp)
-{
- Controller *cp;
- Partition *pp;
- int retrycount;
-
- cp = dp->cp;
-
- pp = &dp->p[0];
- pp->end = 0;
-
- retrycount = 0;
-retry:
- if(retrycount++){
- IDPRINT("hd%d: atapipart: cmd 0x%ux error 0x%ux, retry %d\n",
- dp->driveno, cp->cmdblk[0], cp->error, retrycount);
- if((cp->status & Serr) && (cp->error & 0xF0) == 0x60){
- dp->vers++;
- if(retrycount < 3)
- goto again;
- }
- cp->dp = 0;
- IDPRINT("hd%d: atapipart: cmd %ux return error %ux, retry %d\n",
- dp->driveno, cp->cmd, cp->error, retrycount);
- return 0;
- }
-again:
- cp->dp = dp;
-
- cp->len = 18;
- cp->count = 0;
- memset(cp->cmdblk, 0, sizeof(cp->cmdblk));
- cp->cmdblk[0] = Creqsense;
- cp->cmdblk[4] = 18;
- DPRINT("reqsense %d\n", retrycount);
- atapiexec(dp);
- //if(atapiexec(dp))
- // goto retry;
- if(cp->count != 18){
- print("cmd=0x%2.2ux, lastcmd=0x%2.2ux ", cp->cmd, cp->lastcmd);
- print("cdsize count %d, status 0x%2.2ux, error 0x%2.2ux\n",
- cp->count, cp->status, cp->error);
- return 0;
- }
-
- cp->len = 8;
- cp->count = 0;
- memset(cp->cmdblk, 0, sizeof(cp->cmdblk));
- cp->cmdblk[0] = Ccapacity;
- DPRINT("capacity %d\n", retrycount);
- if(atapiexec(dp))
- goto retry;
- if(cp->count != 8){
- print("cmd=0x%2.2ux, lastcmd=0x%2.2ux ", cp->cmd, cp->lastcmd);
- print("cdsize count %d, status 0x%2.2ux, error 0x%2.2ux\n",
- cp->count, cp->status, cp->error);
- return 0;
- }
- dp->sectors = (cp->buf[0]<<24)|(cp->buf[1]<<16)|(cp->buf[2]<<8)|cp->buf[3];
- dp->bytes = (cp->buf[4]<<24)|(cp->buf[5]<<16)|(cp->buf[6]<<8)|cp->buf[7];
- if(dp->bytes > 2048 && dp->bytes <= 2352)
- dp->bytes = 2048;
- dp->cap = dp->sectors;
- IDPRINT("hd%d: atapipart secs %ud, bytes %ud, cap %lud\n",
- dp->driveno, dp->sectors, dp->bytes, dp->cap);
- cp->dp = 0;
-
- pp->end = dp->sectors;
- dp->partok = 1;
-
- return dp;
-}
-
-static void
-atapiintr(Controller *cp)
-{
- uchar cause;
- int count, loop, pbase;
-
- pbase = cp->pbase;
- cause = inb(pbase+Pcount) & 0x03;
- DPRINT("hd%d: atapiintr 0x%ux\n", cp->dp->driveno, cause);
- switch(cause){
-
- case 1: /* command */
- if(cp->status & Serr){
- cp->lastcmd = cp->cmd;
- cp->cmd = 0;
- cp->error = inb(pbase+Perror);
- break;
- }
- outss(pbase+Pdata, cp->cmdblk, sizeof(cp->cmdblk)/2);
- break;
-
- case 0: /* data out */
- case 2: /* data in */
- if(cp->buf == 0){
- cp->lastcmd = cp->cmd;
- cp->cmd = 0;
- if(cp->status & Serr)
- cp->error = inb(pbase+Perror);
- cp->cmd = 0;
- break;
- }
- loop = 0;
- while((cp->status & (Serr|Sdrq)) == 0){
- if(++loop > Maxloop){
- cp->status |= Serr;
- break;
- }
- cp->status = inb(pbase+Pstatus);
- }
- if(cp->status & Serr){
- cp->lastcmd = cp->cmd;
- cp->cmd = 0;
- cp->error = inb(pbase+Perror);
- print("hd%d: Cpktcmd status=0x%ux, error=0x%ux\n",
- cp->dp->driveno, cp->status, cp->error);
- break;
- }
- count = inb(pbase+Pcyllsb)|(inb(pbase+Pcylmsb)<<8);
- if(cp->count+count > Maxxfer)
- panic("hd%d: count %d, already %d\n", count, cp->count);
- if(cause == 0)
- outss(pbase+Pdata, cp->buf+cp->count, count/2);
- else
- inss(pbase+Pdata, cp->buf+cp->count, count/2);
- cp->count += count;
- break;
-
- case 3: /* status */
- cp->lastcmd = cp->cmd;
- cp->cmd = 0;
- if(cp->status & Serr)
- cp->error = inb(cp->pbase+Perror);
- break;
- }
-}
-
-ideread( Device *d, long b, void *c )
-{
- Drive *dp;
- Controller *cp;
- int x;
-
- dp = d->private;
- cp = dp->cp;
-
- qlock( cp );
-
- DPRINT("ideread(dev %x, %ld, %x, %d): %x\n"
- , d, b, c, dp->driveno, dp );
- ataseek( dp->driveno, b * RBUFSIZE );
- x = ataread( dp->driveno, c, RBUFSIZE )==0;
- qunlock( cp );
-
- return x;
-}
-
-idewrite( Device *d, long b, void *c)
-{
- Drive *dp;
- Controller *cp;
- int x;
-
- dp = d->private;
- cp = dp->cp;
-
- qlock( cp );
-
- DPRINT("idewrite(%x, %ld, %x): driveno %d\n", d, b, c, dp->driveno );
- ataseek( dp->driveno, b * RBUFSIZE );
- x = atawrite( dp->driveno, c, RBUFSIZE )==0;
- qunlock( cp );
-
- return x;
-}
-
-long atasize( Device *d )
-{
- Drive *dp;
-
- dp = d->private;
- DPRINT("atasize(%x): %uld -> %uld\n", d, dp->cap, dp->cap / RBUFSIZE * 512);
- return (dp->cap / RBUFSIZE * 512);
-}
-
-void ideinit( Device *d )
-{
- Drive *dp;
-
- if( d->private )
- return;
-
- if( (dp = atadriveprobe( d->wren.ctrl * 2 + d->wren.targ ) ) ) {
- DPRINT("ideinit( device %x ctrl %d targ %d ) driveno %d dp %x\n"
- , d, d->wren.ctrl, d->wren.targ, dp->driveno, dp );
- d->private = dp;
- }
-}
//GO.SYSIN DD plan9pc/devata.c
echo plan9pc/fns.h
sed 's/.//' >plan9pc/fns.h <<'//GO.SYSIN DD plan9pc/fns.h'
-ulong strtoul(char*, char**, int);
-
-#include "../port/portfns.h"
-
-void aamloop(int);
-void cgaputc(int);
-void cgaputs(char*, int);
-int cistrcmp(char*, char*);
-int cistrncmp(char*, char*, int);
-void (*coherence)(void);
-void etherinit(void);
-void etherstart(void);
-int floppyinit(void);
-void floppyproc(void);
-long floppyread(int, void*, long);
-long floppyseek(int, long);
-long floppywrite(int, void*, long);
-char* getconf(char*);
-ulong getcr0(void);
-ulong getcr2(void);
-ulong getcr4(void);
-int getfields(char*, char**, int, char);
-ulong getstatus(void);
-int atainit(void);
-long ataread(int, void*, long);
-long ataseek(int, long);
-long atawrite(int, void*, long);
-void i8042a20(void);
-void i8042reset(void);
-int inb(int);
-void insb(int, void*, int);
-ushort ins(int);
-void inss(int, void*, int);
-ulong inl(int);
-void insl(int, void*, int);
-int isaconfig(char*, int, ISAConf*);
-void kbdinit(void);
-int kbdintr0(void);
-int kbdgetc(void);
-long* mapaddr(ulong);
-void microdelay(int);
-void mmuinit(void);
-uchar nvramread(int);
-void outb(int, int);
-void outsb(int, void*, int);
-void outs(int, ushort);
-void outss(int, void*, int);
-void outl(int, ulong);
-void outsl(int, void*, int);
-int pcicfgr8(Pcidev*, int);
-int pcicfgr16(Pcidev*, int);
-int pcicfgr32(Pcidev*, int);
-void pcicfgw8(Pcidev*, int, int);
-void pcicfgw16(Pcidev*, int, int);
-void pcicfgw32(Pcidev*, int, int);
-void pcihinv(Pcidev*);
-Pcidev* pcimatch(Pcidev*, int, int);
-Pcidev* pcimatchtbdf(int);
-void pcireset(void);
-void pcisetbme(Pcidev*);
-void printcpufreq(void);
-void putgdt(Segdesc*, int);
-void putidt(Segdesc*, int);
-void putcr3(ulong);
-void putcr4(ulong);
-void puttr(ulong);
-void rdmsr(int, vlong*);
-void scsiinit(void);
-long scsiread(int, void*, long);
-long scsiseek(int, long);
-long scsiwrite(int, void*, long);
-int setatapart(int, char*);
-int setscsipart(int, char*);
-void setvec(int, void (*)(Ureg*, void*), void*);
-int tas(Lock*);
-void trapinit(void);
-void uartspecial(int, void (*)(int), int (*)(void), int);
-int uartgetc(void);
-void uartputc(int);
-void wbflush(void);
-void cpuid(char*, int*, int*);
-#define PADDR(a) ((ulong)(a)&~KZERO)
-
-void ideinit(Device *d);
-int ideread(Device *d, long, void*);
-int idewrite(Device *d, long, void*);
-long atasize(Device *d);
-void atainitstub(Device *d);
//GO.SYSIN DD plan9pc/fns.h
echo port/config.c
sed 's/.//' >port/config.c <<'//GO.SYSIN DD port/config.c'
-#include "all.h"
-#include "io.h"
-
-struct
-{
- char* icharp;
- char* charp;
- int error;
- int newconf; /* clear befor start */
- int modconf; /* write back when done */
- int nextiter;
- int lastiter;
- int diriter;
- int ipauthset;
- Device* lastcw;
- Device* devlist;
-} f;
-
-int
-devcmpr(Device *d1, Device *d2)
-{
-
-loop:
- if(d1 == d2)
- return 0;
- if(d1 == 0 || d2 == 0 || d1->type != d2->type)
- return 1;
-
- switch(d1->type) {
- default:
- print("cant compare dev: %D\n", d1);
- panic("devcmp");
- break;
-
- case Devmcat:
- case Devmlev:
- d1 = d1->cat.first;
- d2 = d2->cat.first;
- while(d1 && d2) {
- if(devcmpr(d1, d2))
- return 1;
- d1 = d1->link;
- d2 = d2->link;
- }
- goto loop;
-
- case Devnone:
- return 0;
-
- case Devro:
- d1 = d1->ro.parent;
- d2 = d2->ro.parent;
- goto loop;
-
- case Devjuke:
- case Devcw:
- if(devcmpr(d1->cw.c, d2->cw.c))
- break;
- d1 = d1->cw.w;
- d2 = d2->cw.w;
- goto loop;
-
- case Devfworm:
- d1 = d1->fw.fw;
- d2 = d2->fw.fw;
- goto loop;
-
- case Devwren:
- case Devworm:
- case Devlworm:
- case Devide:
- if(d1->wren.ctrl == d2->wren.ctrl)
- if(d1->wren.targ == d2->wren.targ)
- if(d1->wren.lun == d2->wren.lun)
- return 0;
- break;
-
- case Devpart:
- if(d1->part.base == d2->part.base)
- if(d1->part.size == d2->part.size) {
- d1 = d1->part.d;
- d2 = d2->part.d;
- goto loop;
- }
- break;
- }
- return 1;
-}
-
-void
-cdiag(char *s, int c1)
-{
-
- f.charp--;
- if(f.error == 0) {
- print("config diag: %s -- <%c>\n", s, c1);
- f.error = 1;
- }
-}
-
-int
-cnumb(void)
-{
- int c, n;
-
- c = *f.charp++;
- if(c == '<') {
- n = f.nextiter;
- if(n >= 0) {
- f.nextiter = n+f.diriter;
- if(n == f.lastiter) {
- f.nextiter = -1;
- f.lastiter = -1;
- }
- for(;;) {
- c = *f.charp++;
- if(c == '>')
- break;
- }
- return n;
- }
- n = cnumb();
- if(*f.charp++ != '-') {
- cdiag("- expected", f.charp[-1]);
- return 0;
- }
- c = cnumb();
- if(*f.charp++ != '>') {
- cdiag("> expected", f.charp[-1]);
- return 0;
- }
- f.lastiter = c;
- f.diriter = 1;
- if(n > c)
- f.diriter = -1;
- f.nextiter = n+f.diriter;
- return n;
- }
- if(c < '0' || c > '9') {
- cdiag("number expected", c);
- return 0;
- }
- n = 0;
- while(c >= '0' && c <= '9') {
- n = n*10 + (c-'0');
- c = *f.charp++;
- }
- f.charp--;
- return n;
-}
-
-Device*
-config1(int c)
-{
- Device *d, *t;
- int m;
-
- d = ialloc(sizeof(Device), 0);
- for(;;) {
- t = config();
- if(d->cat.first == 0)
- d->cat.first = t;
- else
- d->cat.last->link = t;
- d->cat.last = t;
- if(f.error)
- goto bad;
- m = *f.charp;
- if(c == '(' && m == ')') {
- d->type = Devmcat;
- break;
- }
- if(c == '[' && m == ']') {
- d->type = Devmlev;
- break;
- }
- }
- f.charp++;
- if(d->cat.first == d->cat.last)
- d = d->cat.first;
- return d;
-
-bad:
- return devnone;
-}
-
-Device*
-config(void)
-{
- int c, m;
- Device *d;
- char *icp;
-
- if(f.error)
- goto bad;
- d = ialloc(sizeof(Device), 0);
-
- c = *f.charp++;
- switch(c) {
- default:
- cdiag("unknown type", c);
- goto bad;
-
- case '(': /* (d+) one or multiple cat */
- case '[': /* [d+] one or multiple interleave */
- return config1(c);
-
- case 'f': /* fd fake worm */
- d->type = Devfworm;
- d->fw.fw = config();
- break;
-
- case 'n':
- d->type = Devnone;
- break;
-
- case 'w': /* w[#.]# wren [ctrl] unit [part] */
- case 'r': /* r[#.]#[.#] worm [ctrl] unit [part] */
- case 'l': /* r[#.]#[.#] worm [ctrl] unit [part] */
- case 'h': /* h[#.]# ide [ctlr] unit [part] */
- icp = f.charp;
- d->type = Devwren;
- if(c == 'h')
- d->type = Devide;
- else
- d->type = Devwren;
- d->wren.ctrl = 0;
- d->wren.targ = cnumb();
- d->wren.lun = 0;
- m = *f.charp;
- if(m == '.') {
- f.charp++;
- d->wren.lun = cnumb();
- m = *f.charp;
- if(m == '.') {
- f.charp++;
- d->wren.ctrl = d->wren.targ;
- d->wren.targ = d->wren.lun;
- d->wren.lun = cnumb();
- }
- }
- if(f.nextiter >= 0)
- f.charp = icp-1;
- if(c == 'r') { /* worms are virtual and not uniqued */
- d->type = Devworm;
- break;
- }
- if(c == 'l') {
- d->type = Devlworm;
- break;
- }
- break;
-
- case 'o': /* o ro part of last cw */
- if(f.lastcw == 0) {
- cdiag("no cw to match", c);
- goto bad;
- }
- return f.lastcw->cw.ro;
-
- case 'j': /* DD jukebox */
- d->type = Devjuke;
- d->j.j = config();
- d->j.m = config();
- break;
-
- case 'c': /* cache/worm */
- d->type = Devcw;
- d->cw.c = config();
- d->cw.w = config();
- d->cw.ro = ialloc(sizeof(Device), 0);
- d->cw.ro->type = Devro;
- d->cw.ro->ro.parent = d;
- f.lastcw = d;
- break;
-
- case 'p': /* pd#.# partition base% size% */
- d->type = Devpart;
- d->part.d = config();
- d->part.base = cnumb();
- c = *f.charp++;
- if(c != '.')
- cdiag("dot expected", c);
- d->part.size = cnumb();
- break;
-
- case 'x': /* xD swab a device */
- d->type = Devswab;
- d->swab.d = config();
- break;
- }
- d->dlink = f.devlist;
- f.devlist = d;
- return d;
-
-bad:
- return devnone;
-}
-
-char*
-strdup(char *s)
-{
- int n;
- char *s1;
-
- n = strlen(s);
- s1 = ialloc(n+1, 0);
- strcpy(s1, s);
- return s1;
-}
-
-Device*
-iconfig(char *s)
-{
- Device *d;
-
- f.nextiter = -1;
- f.lastiter = -1;
- f.error = 0;
- f.icharp = s;
- f.charp = f.icharp;
- d = config();
- if(*f.charp) {
- cdiag("junk on end", *f.charp);
- f.error = 1;
- }
- return d;
-}
-
-int
-testconfig(char *s)
-{
-
- iconfig(s);
- return f.error;
-}
-
-int
-astrcmp(char *a, char *b)
-{
- int n, c;
-
- n = strlen(b);
- if(memcmp(a, b, n))
- return 1;
- c = a[n];
- if(c == 0) {
- aindex = 0;
- return 0;
- }
- if(a[n+1])
- return 1;
- if(c >= '0' && c <= '9') {
- aindex = c - '0';
- return 0;
- }
- return 1;
-}
-
-void
-mergeconf(Iobuf *p)
-{
- char word[100];
- char *cp;
- Filsys *fs;
-
- cp = p->iobuf;
- goto line;
-
-loop:
- if(*cp != '\n')
- goto bad;
- cp++;
-
-line:
- cp = getwd(word, cp);
- if(strcmp(word, "") == 0)
- return;
- if(strcmp(word, "service") == 0) {
- cp = getwd(word, cp);
- if(service[0] == 0)
- strcpy(service, word);
- goto loop;
- }
- if(strcmp(word, "ipauth") == 0) {
- cp = getwd(word, cp);
- if(!f.ipauthset)
- if(chartoip(authip, word))
- goto bad;
- goto loop;
- }
- if(astrcmp(word, "ip") == 0) {
- cp = getwd(word, cp);
- if(!nzip(ipaddr[aindex].sysip))
- if(chartoip(ipaddr[aindex].sysip, word))
- goto bad;
- goto loop;
- }
- if(astrcmp(word, "ipgw") == 0) {
- cp = getwd(word, cp);
- if(!nzip(ipaddr[aindex].defgwip))
- if(chartoip(ipaddr[aindex].defgwip, word))
- goto bad;
- goto loop;
- }
- if(astrcmp(word, "ipsntp") == 0) {
- cp = getwd(word, cp);
- if (!nzip(sntpip))
- if (chartoip(sntpip, word))
- goto bad;
- goto loop;
- }
- if(astrcmp(word, "ipmask") == 0) {
- cp = getwd(word, cp);
- if(!nzip(ipaddr[aindex].defmask))
- if(chartoip(ipaddr[aindex].defmask, word))
- goto bad;
- goto loop;
- }
- if(strcmp(word, "filsys") == 0) {
- cp = getwd(word, cp);
- for(fs=filsys; fs->name; fs++)
- if(strcmp(fs->name, word) == 0) {
- if(fs->flags & FEDIT) {
- cp = getwd(word, cp);
- goto loop;
- }
- break;
- }
- fs->name = strdup(word);
- cp = getwd(word, cp);
- fs->conf = strdup(word);
- goto loop;
- }
- goto bad;
-
-bad:
- putbuf(p);
- panic("unknown word in config block: %s", word);
-}
-
-void
-sysinit(void)
-{
- Filsys *fs;
- int error, i;
- Device *d;
- Iobuf *p;
-
- dofilter(u->time+0, C0a, C0b, 1);
- dofilter(u->time+1, C1a, C1b, 1);
- dofilter(u->time+2, C2a, C2b, 1);
- dofilter(cons.work+0, C0a, C0b, 1);
- dofilter(cons.work+1, C1a, C1b, 1);
- dofilter(cons.work+2, C2a, C2b, 1);
- dofilter(cons.rate+0, C0a, C0b, 1000);
- dofilter(cons.rate+1, C1a, C1b, 1000);
- dofilter(cons.rate+2, C2a, C2b, 1000);
- dofilter(cons.bhit+0, C0a, C0b, 1);
- dofilter(cons.bhit+1, C1a, C1b, 1);
- dofilter(cons.bhit+2, C2a, C2b, 1);
- dofilter(cons.bread+0, C0a, C0b, 1);
- dofilter(cons.bread+1, C1a, C1b, 1);
- dofilter(cons.bread+2, C2a, C2b, 1);
- dofilter(cons.brahead+0, C0a, C0b, 1);
- dofilter(cons.brahead+1, C1a, C1b, 1);
- dofilter(cons.brahead+2, C2a, C2b, 1);
- dofilter(cons.binit+0, C0a, C0b, 1);
- dofilter(cons.binit+1, C1a, C1b, 1);
- dofilter(cons.binit+2, C2a, C2b, 1);
- cons.chan = chaninit(Devcon, 1);
-
-start:
- /*
- * part 1 -- read the config file
- */
- devnone = iconfig("n");
-
- print("config %s\n", nvr.config);
-
- d = iconfig(nvr.config);
- devinit(d);
- if(f.newconf) {
- p = getbuf(d, 0, Bmod);
- memset(p->iobuf, 0, RBUFSIZE);
- settag(p, Tconfig, 0);
- } else
- p = getbuf(d, 0, Bread|Bmod);
- if(!p || checktag(p, Tconfig, 0))
- panic("config io");
- mergeconf(p);
- if(f.modconf) {
- memset(p->iobuf, 0, BUFSIZE);
- p->flags |= Bmod|Bimm;
- if(service[0])
- sprint(strchr(p->iobuf, 0), "service %s\n", service);
- for(fs=filsys; fs->name; fs++)
- if(fs->conf)
- sprint(strchr(p->iobuf, 0),
- "filsys %s %s\n", fs->name, fs->conf);
- sprint(strchr(p->iobuf, 0), "ipauth %I\n", authip);
- sprint(strchr(p->iobuf, 0), "ipsntp %I\n", sntpip);
- for(i=0; i<10; i++) {
- sprint(strchr(p->iobuf, 0),
- "ip%d %I\n", i, ipaddr[i].sysip);
- sprint(strchr(p->iobuf, 0),
- "ipgw%d %I\n", i, ipaddr[i].defgwip);
- sprint(strchr(p->iobuf, 0),
- "ipmask%d %I\n", i, ipaddr[i].defmask);
- }
- putbuf(p);
- f.modconf = 0;
- f.newconf = 0;
- print("config block written\n");
- goto start;
- }
- putbuf(p);
-
- print("service %s\n", service);
- print("ipauth %I\n", authip);
- print("ipsntp %I\n", sntpip);
- for(i=0; i<10; i++) {
- if(nzip(ipaddr[i].sysip)) {
- print("ip%d %I\n", i, ipaddr[i].sysip);
- print("ipgw%d %I\n", i, ipaddr[i].defgwip);
- print("ipmask%d %I\n", i, ipaddr[i].defmask);
- }
- }
-
-loop:
- /*
- * part 2 -- squeeze out the deleted filesystems
- */
- for(fs=filsys; fs->name; fs++)
- if(fs->conf == 0) {
- for(; fs->name; fs++)
- *fs = *(fs+1);
- goto loop;
- }
- if(filsys[0].name == 0)
- panic("no filsys");
-
- /*
- * part 3 -- compile the device expression
- */
- error = 0;
- for(fs=filsys; fs->name; fs++) {
- print("filsys %s %s\n", fs->name, fs->conf);
- fs->dev = iconfig(fs->conf);
- if(f.error) {
- error = 1;
- continue;
- }
- }
- if(error)
- panic("fs config");
-
- /*
- * part 4 -- initialize the devices
- */
- for(fs=filsys; fs->name; fs++) {
- print("sysinit: %s\n", fs->name);
- if(fs->flags & FREAM)
- devream(fs->dev, 1);
- if(fs->flags & FRECOVER)
- devrecover(fs->dev);
- devinit(fs->dev);
- }
-}
-
-void
-getline(char *line)
-{
- char *p;
- int c;
-
- p = line;
- for(;;) {
- c = rawchar(0);
- if(c == 0 || c == '\n') {
- *p = 0;
- return;
- }
- if(c == '\b') {
- p--;
- continue;
- }
- *p++ = c;
- }
-}
-
-void
-arginit(void)
-{
- int verb, c;
- char line[300], word[300], *cp;
- uchar localip[Pasize];
- Filsys *fs;
- uchar csum;
-
- print("nvr read\n");
- nvread(NVRAUTHADDR, &nvr, sizeof(nvr));
- csum = nvcsum(nvr.authkey, sizeof(nvr.authkey));
- if(csum != nvr.authsum) {
- print("\n\n ** NVR key checksum is incorrect **\n");
- print(" ** set password to allow attaches **\n\n");
- memset(nvr.authkey, 0, sizeof(nvr.authkey));
- goto loop;
- }
- csum = nvcsum(nvr.config, sizeof(nvr.config));
- if(csum != nvr.configsum) {
- print("\n\n ** NVR config checksum is incorrect **\n");
- memset(nvr.config, 0, sizeof(nvr.config));
- goto loop;
- }
-
- print("for config mode hit a key within 5 seconds\n");
- c = rawchar(5);
- if(c == 0) {
- print(" no config\n");
- return;
- }
-
-loop:
- print("config: ");
- getline(line);
- cp = getwd(word, line);
- if(strcmp(word, "end") == 0)
- return;
- if(strcmp(word, "halt") == 0)
- exit();
-
- if(strcmp(word, "allow") == 0) {
- wstatallow = 1;
- writeallow = 1;
- goto loop;
- }
-
- if(strcmp(word, "noauth") == 0) {
- noauth = !noauth;
- goto loop;
- }
- if(strcmp(word, "noattach") == 0) {
- noattach = !noattach;
- goto loop;
- }
- if(strcmp(word, "ream") == 0) {
- verb = FREAM;
- goto gfsname;
- }
- if(strcmp(word, "recover") == 0) {
- verb = FRECOVER;
- goto gfsname;
- }
- if(strcmp(word, "filsys") == 0) {
- verb = FEDIT;
- goto gfsname;
- }
- if(strcmp(word, "nvram") == 0) {
- getwd(word, cp);
- if(testconfig(word))
- goto loop;
- c = strlen(word);
- if(c >= sizeof(nvr.config)) {
- print("config string too long\n");
- goto loop;
- }
- memset(nvr.config, 0, sizeof(nvr.config));
- memmove(nvr.config, word, c);
- nvr.configsum = nvcsum(nvr.config, sizeof(nvr.config));
- nvwrite(NVRAUTHADDR, &nvr, sizeof(nvr));
- goto loop;
- }
- if(strcmp(word, "config") == 0) {
- getwd(word, cp);
- if(testconfig(word))
- goto loop;
- c = strlen(word);
- if(c >= sizeof(nvr.config)) {
- print("config string too long\n");
- goto loop;
- }
- memset(nvr.config, 0, sizeof(nvr.config));
- memmove(nvr.config, word, c);
- nvr.configsum = nvcsum(nvr.config, sizeof(nvr.config));
- nvwrite(NVRAUTHADDR, &nvr, sizeof(nvr));
- f.newconf = 1;
- goto loop;
- }
- if(strcmp(word, "service") == 0) {
- getwd(word, cp);
- strcpy(service, word);
- f.modconf = 1;
- goto loop;
- }
- if(strcmp(word, "ipauth") == 0) {
- f.ipauthset = 1;
- verb = 2;
- goto ipname;
- }
- if(astrcmp(word, "ip") == 0) {
- verb = 0;
- goto ipname;
- }
- if(astrcmp(word, "ipgw") == 0) {
- verb = 1;
- goto ipname;
- }
- if(astrcmp(word, "ipmask") == 0) {
- verb = 3;
- goto ipname;
- }
- if(astrcmp(word, "ipsntp") == 0) {
- verb = 4;
- goto ipname;
- }
- print("unknown config command\n");
- print(" type end to get out\n");
- goto loop;
-
-ipname:
- getwd(word, cp);
- if(chartoip(localip, word)) {
- print("bad ip address\n");
- goto loop;
- }
- switch(verb) {
- case 0:
- memmove(ipaddr[aindex].sysip, localip,
- sizeof(ipaddr[aindex].sysip));
- break;
- case 1:
- memmove(ipaddr[aindex].defgwip, localip,
- sizeof(ipaddr[aindex].defgwip));
- break;
- case 2:
- memmove(authip, localip,
- sizeof(authip));
- break;
- case 3:
- memmove(ipaddr[aindex].defmask, localip,
- sizeof(ipaddr[aindex].defmask));
- break;
- case 4:
- memmove(sntpip, localip,
- sizeof(sntpip));
- break;
- }
- f.modconf = 1;
- goto loop;
-
-gfsname:
- cp = getwd(word, cp);
- for(fs=filsys; fs->name; fs++)
- if(strcmp(word, fs->name) == 0)
- goto found;
- memset(fs, 0, sizeof(*fs));
- fs->name = strdup(word);
-
-found:
- switch(verb) {
- case FREAM:
- if(strcmp(fs->name, "main") == 0)
- wstatallow = 1; /* only set, never reset */
- case FRECOVER:
- fs->flags |= verb;
- goto loop;
- case FEDIT:
- f.modconf = 1;
- getwd(word, cp);
- fs->flags |= verb;
- if(word[0] == 0) {
- fs->conf = 0;
- goto loop;
- }
- if(testconfig(word))
- goto loop;
- fs->conf = strdup(word);
- goto loop;
- }
-}
//GO.SYSIN DD port/config.c
echo port/main.c
sed 's/.//' >port/main.c <<'//GO.SYSIN DD port/main.c'
-#include "all.h"
-#include "mem.h"
-#include "io.h"
-#include "ureg.h"
-
-void
-machinit(void)
-{
- int n;
-
- n = m->machno;
- memset(m, 0, sizeof(Mach));
- m->machno = n;
- m->mmask = 1<<m->machno;
- m->lights = 0;
-
- active.exiting = 0;
- active.machs = 1;
-}
-
-static
-void
-confinit(void)
-{
- conf.nmach = 1;
- conf.nproc = 50;
-
- conf.mem = meminit();
- conf.sparemem = conf.mem/12; /* 8% spare for chk etc */
-
- conf.nalarm = 200;
- conf.nuid = 1000;
- conf.nserve = 15;
- conf.nfile = 30000;
- conf.nlgmsg = 100;
- conf.nsmmsg = 500;
- conf.wcpsize = 1024*1024;
- localconfinit();
-
- conf.nwpath = conf.nfile*8;
- conf.gidspace = conf.nuid*3;
-
- cons.flags = 0;
-}
-
-void
-main(void)
-{
- int i;
-
- echo = 1;
- predawn = 1;
- formatinit();
- machinit();
- vecinit();
- confinit();
- lockinit();
- printinit();
- procinit();
- clockinit();
- alarminit();
-
- mainlock.wr.name = "mainr";
- mainlock.rd.name = "mainw";
- reflock.name = "ref";
-
- qlock(&reflock);
- qunlock(&reflock);
- serveq = newqueue(1000);
- raheadq = newqueue(1000);
- authreply = newqueue(Nqueue);
-
- mbinit();
-
- sntpinit();
- otherinit();
-
- files = ialloc(conf.nfile * sizeof(*files), 0);
- for(i=0; i<conf.nfile; i++) {
- qlock(&files[i]);
- files[i].name = "file";
- qunlock(&files[i]);
- }
-
- wpaths = ialloc(conf.nwpath * sizeof(*wpaths), 0);
- uid = ialloc(conf.nuid * sizeof(*uid), 0);
- gidspace = ialloc(conf.gidspace * sizeof(*gidspace), 0);
-
- print("iobufinit\n");
- iobufinit();
-
- arginit();
-
- userinit(touser, 0, "ini");
-
- predawn = 0;
- launchinit();
- schedinit();
-}
-
-/*
- * read ahead processes.
- * read message from q and then
- * read the device.
- */
-int
-rbcmp(void *va, void *vb)
-{
- Rabuf *ra, *rb;
-
- ra = *(Rabuf**)va;
- rb = *(Rabuf**)vb;
- if(rb == 0)
- return 1;
- if(ra == 0)
- return -1;
- if(ra->dev > rb->dev)
- return 1;
- if(ra->dev < rb->dev)
- return -1;
- if(ra->addr > rb->addr)
- return 1;
- if(ra->addr < rb->addr)
- return -1;
- return 0;
-}
-
-void
-rahead(void)
-{
- Rabuf *rb[50];
- Iobuf *p;
- int i, n;
-
-loop:
- rb[0] = recv(raheadq, 0);
- for(n=1; n<nelem(rb); n++) {
- if(raheadq->count <= 0)
- break;
- rb[n] = recv(raheadq, 0);
- }
- qsort(rb, n, sizeof(rb[0]), rbcmp);
- for(i=0; i<n; i++) {
- if(rb[i] == 0)
- continue;
- p = getbuf(rb[i]->dev, rb[i]->addr, Bread);
- if(p)
- putbuf(p);
- lock(&rabuflock);
- rb[i]->link = rabuffree;
- rabuffree = rb[i];
- unlock(&rabuflock);
- }
- goto loop;
-}
-
-/*
- * main filesystem server loop.
- * entered by many processes.
- * they wait for message buffers and
- * then process them.
- */
-void
-serve(void)
-{
- Fcall fi, fo;
- Msgbuf *mb, *mb1;
- Chan *cp;
- int t, n;
-
-loop:
- qlock(&reflock);
- mb = recv(serveq, 0);
- cp = mb->chan;
- rlock(&cp->reflock);
- qunlock(&reflock);
-
- rlock(&mainlock);
-
- /*
- * conversion to structure and
- * simple syntax checks.
- */
- if(convM2S(mb->data, &fi, mb->count) == 0) {
- print("bad M2S conversion\n");
- goto error;
- }
- t = fi.type;
-
- if(t < 0 || t >= MAXSYSCALL || (t&1) || !p9call[t]) {
- print("bad message type\n");
- goto error;
- }
-
- /*
- * allocate reply message
- */
- if(t == Tread) {
- mb1 = mballoc(MAXMSG+MAXDAT, cp, Mbreply2);
- fo.data = mb1->data + 8;
- } else
- mb1 = mballoc(MAXMSG, cp, Mbreply3);
-
- /*
- * call the file system
- */
- cons.work[0].count++;
- cons.work[1].count++;
- cons.work[2].count++;
- cp->work.count++;
- cons.rate[0].count += mb->count;
- cons.rate[1].count += mb->count;
- cons.rate[2].count += mb->count;
- cp->rate.count += mb->count;
- fo.err = 0;
-
- (*p9call[t])(cp, &fi, &fo);
-
- fo.type = t+1;
- fo.tag = fi.tag;
-
- if(fo.err) {
- if(cons.flags&errorflag)
- print(" type %d: error: %s\n", t,
- errstr[fo.err]);
- if(CHAT(cp))
- print(" error: %s\n", errstr[fo.err]);
- fo.type = Rerror;
- strncpy(fo.ename, errstr[fo.err], sizeof(fo.ename));
- }
-
- n = convS2M(&fo, mb1->data);
- if(n == 0) {
- print("bad S2M conversion\n");
- mbfree(mb1);
- goto error;
- }
- mb1->count = n;
- mb1->param = mb->param;
- cons.rate[0].count += n;
- cons.rate[1].count += n;
- cons.rate[2].count += n;
- cp->rate.count += n;
- send(cp->reply, mb1);
-
-out:
- mbfree(mb);
- runlock(&mainlock);
- runlock(&cp->reflock);
- goto loop;
-
-error:
- print("type=%d count=%d\n", mb->data[0], mb->count);
- print(" %.2x %.2x %.2x %.2x\n",
- mb->data[1]&0xff, mb->data[2]&0xff,
- mb->data[3]&0xff, mb->data[4]&0xff);
- print(" %.2x %.2x %.2x %.2x\n",
- mb->data[5]&0xff, mb->data[6]&0xff,
- mb->data[7]&0xff, mb->data[8]&0xff);
- print(" %.2x %.2x %.2x %.2x\n",
- mb->data[9]&0xff, mb->data[10]&0xff,
- mb->data[11]&0xff, mb->data[12]&0xff);
-
- mb1 = mballoc(3, cp, Mbreply4);
- mb1->data[0] = Rnop; /* your nop was ok */
- mb1->data[1] = ~0;
- mb1->data[2] = ~0;
- mb1->count = 3;
- mb1->param = mb->param;
- send(cp->reply, mb1);
- goto out;
-}
-
-void
-init0(void)
-{
- m->proc = u;
- u->state = Running;
- u->mach = m;
- spllo();
-
- (*u->start)();
-}
-
-void*
-getarg(void)
-{
-
- return u->arg;
-}
-
-void
-exit(void)
-{
- u = 0;
- lock(&active);
- active.machs &= ~(1<<m->machno);
- active.exiting = 1;
- unlock(&active);
- if(!predawn)
- spllo();
- print("cpu %d exiting\n", m->machno);
- while(active.machs)
- delay(1);
- print("halted. press a key to reboot.\n");
- delay(300); /* time to drain print q */
- splhi();
- rawchar(5 * 60); // reboot in 5mins or key press
- consreset();
- firmware();
-}
-
-/*
- * 1 sec timer
- * process+alarm+rendez+rwlock
- */
-static Rendez sec;
-
-static
-void
-callsec(Alarm *a, void *arg)
-{
- User *u;
-
- cancel(a);
- u = arg;
- wakeup(&u->tsleep);
-}
-
-void
-waitsec(int msec)
-{
- alarm(msec, callsec, u);
- sleep(&u->tsleep, no, 0);
-}
-
-#define DUMPTIME 5 /* 5 am */
-#define WEEKMASK 0 /* every day (1=sun, 2=mon 4=tue) */
-
-/*
- * process to copy dump blocks from
- * cache to worm. it runs flat out when
- * it gets work, but only looks for
- * work every 10 seconds.
- */
-void
-wormcopy(void)
-{
- int f;
- Filsys *fs;
- ulong nddate, ntoytime, t;
- long dt;
-
-recalc:
- /*
- * calculate the next dump time.
- * minimum delay is 100 minutes.
- */
- t = time();
- nddate = nextime(t+MINUTE(100), DUMPTIME, WEEKMASK);
- if(!conf.nodump)
- print("next dump at %T\n", nddate);
-
- ntoytime = time() + HOUR(1);
-
-loop:
- dt = time() - t;
- if(dt < 0) {
- print("time went back\n");
- goto recalc;
- }
- if(dt > MINUTE(100)) {
- print("time jumped ahead\n");
- goto recalc;
- }
- t += dt;
- f = 0;
-
- if(t > ntoytime) {
- dt = time() - rtctime();
- if(dt < 0)
- dt = -dt;
- if(dt > 10)
- print("rtc time more than 10 secounds out\n");
- else
- if(dt > 1)
- settime(rtctime());
- ntoytime = time() + HOUR(1);
- goto loop;
- }
-
- if(!f) {
- if(t > nddate) {
- if(!conf.nodump) {
- print("automatic dump %T\n", t);
- for(fs=filsys; fs->name; fs++)
- if(fs->dev->type == Devcw)
- cfsdump(fs);
- }
- goto recalc;
- }
- }
-
- rlock(&mainlock);
- for(fs=filsys; fs->name; fs++)
- if(fs->dev->type == Devcw)
- f |= dumpblock(fs->dev);
- runlock(&mainlock);
-
- if(!f)
- f = dowcp();
-
- if(!f)
- waitsec(10000);
- wormprobe();
- goto loop;
-}
-
-/*
- * process to synch blocks
- * it puts out a block/line every second
- * it waits 10 seconds if caught up.
- * in both cases, it takes about 10 seconds
- * to get up-to-date.
- */
-void
-synccopy(void)
-{
- int f;
-
-loop:
- rlock(&mainlock);
- f = syncblock();
- runlock(&mainlock);
- if(!f)
- waitsec(10000);
- else
- waitsec(1000);
-/* pokewcp(); */
- goto loop;
-}
//GO.SYSIN DD port/main.c
echo port/portdat.h
sed 's/.//' >port/portdat.h <<'//GO.SYSIN DD port/portdat.h'
-/*
- * fundamental constants
- */
-#define SUPER_ADDR 2 /* address of superblock */
-#define ROOT_ADDR 3 /* address of superblock */
-#define ERRREC 64 /* size of a error record */
-#define DIRREC 116 /* size of a directory ascii record */
-#define NAMELEN 28 /* size of names */
-#define NDBLOCK 6 /* number of direct blocks in Dentry */
-#define MAXDAT 8192 /* max allowable data message */
-#define MAXMSG 128 /* max size protocol message sans data */
-#define OFFMSG 60 /* offset of msg in buffer */
-#define NDRIVE 16 /* size of drive structure */
-#define NTLOCK 200 /* number of active file Tlocks */
-#define LRES 3 /* profiling resolution */
-#define NATTID 10 /* the last 10 ID's in attaches */
-#define C0a 59 /* time constants for filters */
-#define C0b 60
-#define C1a 599
-#define C1b 600
-#define C2a 5999
-#define C2b 6000
-
-/*
- * more wonderful constants for authentication
- */
-#include <auth.h>
-
-/*
- * derived constants
- */
-#define BUFSIZE (RBUFSIZE-sizeof(Tag))
-#define DIRPERBUF (BUFSIZE/sizeof(Dentry))
-#define INDPERBUF (BUFSIZE/sizeof(long))
-#define INDPERBUF2 (INDPERBUF*INDPERBUF)
-#define FEPERBUF ((BUFSIZE-sizeof(Super1)-sizeof(long))/sizeof(long))
-#define SMALLBUF (MAXMSG)
-#define LARGEBUF (MAXMSG+MAXDAT+256)
-#define RAGAP (300*1024)/BUFSIZE /* readahead parameter */
-#define CEPERBK ((BUFSIZE-BKPERBLK*sizeof(long))/\
- (sizeof(Centry)*BKPERBLK))
-#define BKPERBLK 10
-
-typedef struct Alarm Alarm;
-typedef struct Conf Conf;
-typedef struct Label Label;
-typedef struct Lock Lock;
-typedef struct Mach Mach;
-typedef struct QLock QLock;
-typedef struct Ureg Ureg;
-typedef struct User User;
-typedef struct Fcall Fcall;
-typedef struct Fbuf Fbuf;
-typedef struct Super1 Super1;
-typedef struct Superb Superb;
-typedef struct Filsys Filsys;
-typedef struct Startsb Startsb;
-typedef struct Dentry Dentry;
-typedef struct Tag Tag;
-typedef struct Talarm Talarm;
-typedef struct Uid Uid;
-typedef struct Device Device;
-typedef struct Qid Qid;
-typedef struct Iobuf Iobuf;
-typedef struct Wpath Wpath;
-typedef struct File File;
-typedef struct Chan Chan;
-typedef struct Cons Cons;
-typedef struct Time Time;
-typedef struct Tm Tm;
-typedef struct Rtc Rtc;
-typedef struct Hiob Hiob;
-typedef struct RWlock RWlock;
-typedef struct Msgbuf Msgbuf;
-typedef struct Queue Queue;
-typedef struct Command Command;
-typedef struct Flag Flag;
-typedef struct Bp Bp;
-typedef struct Rabuf Rabuf;
-typedef struct Rendez Rendez;
-typedef struct Filter Filter;
-typedef ulong Float;
-typedef struct Tlock Tlock;
-typedef struct Enpkt Enpkt;
-typedef struct Arppkt Arppkt;
-typedef struct Ippkt Ippkt;
-typedef struct Ilpkt Ilpkt;
-typedef struct Udppkt Udppkt;
-typedef struct Icmppkt Icmppkt;
-typedef struct Ifc Ifc;
-typedef struct Cache Cache;
-typedef struct Centry Centry;
-typedef struct Bucket Bucket;
-
-struct Lock
-{
- ulong* sbsem; /* addr of sync bus semaphore */
- ulong pc;
- ulong sr;
-};
-
-struct Rendez
-{
- Lock;
- User* p;
-};
-
-struct Filter
-{
- ulong count; /* count and old count kept separate */
- ulong oldcount; /* so interrput can read them */
- int c1; /* time const multiplier */
- int c2; /* time const divider */
- int c3; /* scale for printing */
- Float filter; /* filter */
-};
-
-struct QLock
-{
- Lock; /* to use object */
- User* head; /* next process waiting for object */
- User* tail; /* last process waiting for object */
- char* name; /* for diagnostics */
- int locked; /* flag, is locked */
-};
-
-struct RWlock
-{
- int nread;
- QLock wr;
- QLock rd;
-};
-
-/*
- * send/recv queue structure
- */
-struct Queue
-{
- Lock; /* to manipulate values */
- int size; /* size of queue */
- int loc; /* circular pointer */
- int count; /* how many in queue */
- User* rhead; /* process's waiting for send */
- User* rtail;
- User* whead; /* process's waiting for recv */
- User* wtail;
- void* args[1]; /* list of saved pointers, [->size] */
-};
-
-struct Tag
-{
- short pad;
- short tag;
- long path;
-};
-
-struct Device
-{
- uchar type;
- uchar init;
- Device* link; /* link for mcat/mlev */
- Device* dlink; /* link all devices */
- void* private;
- long size;
- union
- {
- struct /* worm wren */
- {
- int ctrl;
- int targ;
- int lun;
- } wren;
- struct /* ata/ide */
- {
- int ctrl;
- int unit;
- } ata;
- struct /* mcat mlev */
- {
- Device* first;
- Device* last;
- int ndev;
- } cat;
- struct /* cw */
- {
- Device* c;
- Device* w;
- Device* ro;
- } cw;
- struct /* juke */
- {
- Device* j;
- Device* m;
- } j;
- struct /* ro */
- {
- Device* parent;
- } ro;
- struct /* fworm */
- {
- Device* fw;
- } fw;
- struct /* part */
- {
- Device* d;
- long base;
- long size;
- } part;
- struct /* part */
- {
- Device* d;
- } swab;
- };
-};
-
-struct Rabuf
-{
- union
- {
- struct
- {
- Device* dev;
- long addr;
- };
- Rabuf* link;
- };
-};
-
-/* DONT TOUCH, this is the disk structure */
-struct Qid
-{
- long path;
- long version;
-};
-
-struct Hiob
-{
- Iobuf* link;
- Lock;
-};
-
-enum
-{
- Easize = 6, /* Ether address size */
- Pasize = 4, /* IP protocol address size */
-};
-
-typedef
-struct
-{
- Queue* reply; /* ethernet output */
- uchar iphis[Pasize]; /* his ip address (index) */
- uchar ipgate[Pasize]; /* his ip/gateway address */
- Chan* link; /* list of il channels */
-} Enp;
-
-enum
-{
- Nqt= 8,
-};
-
-typedef
-struct Ilp
-{
- Enp; /* must be first -- botch */
-
- int alloc; /* 1 means allocated */
- int srcp; /* source port (index) */
- int dstp; /* dest port (index) */
- int state; /* connection state */
-
- Msgbuf* unacked;
- Msgbuf* unackedtail;
-
- Msgbuf* outoforder;
-
- ulong next; /* id of next to send */
- ulong recvd; /* last packet received */
- ulong start; /* local start id */
- ulong rstart; /* remote start id */
- ulong acksent; /* Last packet acked */
-
- ulong lastxmit; /* time of last xmit */
- ulong lastrecv; /* time of last recv */
- ulong timeout; /* time out counter */
- ulong acktime; /* acknowledge timer */
- ulong querytime; /* Query timer */
-
- ulong delay; /* Average of the fixed rtt delay */
- ulong rate; /* Average byte rate */
- ulong mdev; /* Mean deviation of predicted to real rtt */
- ulong maxrtt; /* largest rtt seen */
- ulong rttack; /* The ack we are waiting for */
- int rttlen; /* Length of rttack packet */
- ulong rttstart; /* Time we issued rttack packet */
- ulong unackedbytes;
- int rexmit; /* number of rexmits of *unacked */
-
- ulong qt[Nqt+1]; /* state table for query messages */
- int qtx; /* ... index into qt */
-
- int window; /* maximum receive window */
-
- Rendez syn; /* connect hang out */
-} Ilp;
-
-struct Chan
-{
- char type; /* major driver type i.e. Dev* */
- char whochan[50];
- char whoname[NAMELEN];
- ulong flags;
- int chan; /* overall channel number, mostly for printing */
- int nmsgs; /* outstanding messages, set under flock -- for flush */
- ulong whotime;
- Filter work;
- Filter rate;
- int nfile; /* used by cmd_files */
- RWlock reflock;
- Chan* next; /* link list of chans */
- Queue* send;
- Queue* reply;
- uchar chal[CHALLEN]; /* locally generated challenge */
- uchar rchal[CHALLEN]; /* remotely generated challenge */
- Lock idlock;
- ulong idoffset; /* offset of id vector */
- ulong idvec; /* vector of acceptable id's */
-
- Ifc* ifc;
- union
- {
- /*
- * il ether circuit structure
- */
- Ilp ilp;
- };
-};
-
-struct Filsys
-{
- char* name; /* name of filsys */
- char* conf; /* symbolic configuration */
- Device* dev; /* device that filsys is on */
- int flags;
- #define FREAM (1<<0) /* mkfs */
- #define FRECOVER (1<<1) /* install last dump */
- #define FEDIT (1<<2) /* modified */
-};
-
-struct Startsb
-{
- char* name;
- long startsb;
-};
-
-struct Time
-{
- ulong lasttoy;
- long bias;
- long offset;
-};
-
-/*
- * array of qids that are locked
- */
-struct Tlock
-{
- Device* dev;
- ulong time;
- long qpath;
- File* file;
-};
-
-struct Cons
-{
- ulong flags; /* overall flags for all channels */
- QLock; /* generic qlock for mutex */
- int uid; /* botch -- used to get uid on cons_create */
- int gid; /* botch -- used to get gid on cons_create */
- int nuid; /* number of uids */
- int ngid; /* number of gids */
- long offset; /* used to read files, c.f. fchar */
- int chano; /* generator for channel numbers */
- Chan* chan; /* console channel */
- Filsys* curfs; /* current filesystem */
-
- int profile; /* are we profiling? */
- long* profbuf;
- ulong minpc;
- ulong maxpc;
- ulong nprofbuf;
-
- long nlarge; /* number of large message buffers */
- long nsmall; /* ... small ... */
- long nwormre; /* worm read errors */
- long nwormwe; /* worm write errors */
- long nwormhit; /* worm read cache hits */
- long nwormmiss; /* worm read cache non-hits */
- int noage; /* dont update cache age, dump and check */
- long nwrenre; /* disk read errors */
- long nwrenwe; /* disk write errors */
- long nreseq; /* cache bucket resequence */
-
- Filter work[3]; /* thruput in messages */
- Filter rate[3]; /* thruput in bytes */
- Filter bhit[3]; /* getbufs that hit */
- Filter bread[3]; /* getbufs that miss and read */
- Filter brahead[3]; /* messages to readahead */
- Filter binit[3]; /* getbufs that miss and dont read */
-};
-
-struct File
-{
- QLock;
- Qid qid;
- Wpath* wpath;
- Chan* cp; /* null means a free slot */
- Tlock* tlock; /* if file is locked */
- File* next; /* in cp->flist */
- Filsys* fs;
- long addr;
- long slot;
- long lastra; /* read ahead address */
- ushort fid;
- short uid;
- char open;
- #define FREAD 1
- #define FWRITE 2
- #define FREMOV 4
-};
-
-struct Wpath
-{
- Wpath* up; /* pointer upwards in path */
- long addr; /* directory entry addr */
- long slot; /* directory entry slot */
- short refs; /* number of files using this structure */
-};
-
-struct Iobuf
-{
- QLock;
- Device* dev;
- Iobuf* next; /* for hash */
- Iobuf* fore; /* for lru */
- Iobuf* back; /* for lru */
- char* iobuf; /* only active while locked */
- char* xiobuf; /* "real" buffer pointer */
- long addr;
- int flags;
-};
-
-struct Uid
-{
- short uid; /* user id */
- short lead; /* leader of group */
- short *gtab; /* group table */
- int ngrp; /* number of group entries */
- char name[NAMELEN]; /* user name */
-};
-
-/* DONT TOUCH, this is the disk structure */
-struct Dentry
-{
- char name[NAMELEN];
- short uid;
- short gid;
- ushort mode;
- #define DALLOC 0x8000
- #define DDIR 0x4000
- #define DAPND 0x2000
- #define DLOCK 0x1000
- #define DREAD 0x4
- #define DWRITE 0x2
- #define DEXEC 0x1
- short wuid;
- Qid qid;
- long size;
- long dblock[NDBLOCK];
- long iblock;
- long diblock;
- long atime;
- long mtime;
-};
-
-/* DONT TOUCH, this is the disk structure */
-struct Super1
-{
- long fstart;
- long fsize;
- long tfree;
- long qidgen; /* generator for unique ids */
- /*
- * Stuff for WWC device
- */
- long cwraddr; /* cfs root addr */
- long roraddr; /* dump root addr */
- long last; /* last super block addr */
- long next; /* next super block addr */
-};
-
-/* DONT TOUCH, this is the disk structure */
-struct Fbuf
-{
- long nfree;
- long free[FEPERBUF];
-};
-
-/* DONT TOUCH, this is the disk structure */
-struct Superb
-{
- Fbuf fbuf;
- Super1;
-};
-
-struct Fcall
-{
- char type;
- ushort fid;
- short err;
- short tag;
- union
- {
- struct
- {
- short uid; /* T-Userstr */
- short oldtag; /* T-nFlush */
- Qid qid; /* R-Attach, R-Clwalk, R-Walk,
- * R-Open, R-Create */
- char rauth[AUTHENTLEN]; /* R-attach */
- };
- struct
- {
- char uname[NAMELEN]; /* T-nAttach */
- char aname[NAMELEN]; /* T-nAttach */
- char ticket[TICKETLEN]; /* T-attach */
- char auth[AUTHENTLEN]; /* T-attach */
- };
- struct
- {
- char ename[ERRREC]; /* R-nError */
- char chal[CHALLEN]; /* T-session, R-session */
- char authid[NAMELEN]; /* R-session */
- char authdom[DOMLEN]; /* R-session */
- };
- struct
- {
- char name[NAMELEN]; /* T-Walk, T-Clwalk, T-Create, T-Remove */
- long perm; /* T-Create */
- ushort newfid; /* T-Clone, T-Clwalk */
- char mode; /* T-Create, T-Open */
- };
- struct
- {
- long offset; /* T-Read, T-Write */
- long count; /* T-Read, T-Write, R-Read */
- char* data; /* T-Write, R-Read */
- };
- struct
- {
- char stat[DIRREC]; /* T-Wstat, R-Stat */
- };
- };
-};
-
-struct Label
-{
- ulong pc;
- ulong sp;
-};
-
-struct Alarm
-{
- Lock;
- Alarm* next;
- int busy;
- int dt; /* in ticks */
- void (*f)(Alarm*, void*);
- void* arg;
-};
-
-struct Talarm
-{
- Lock;
- User *list;
-};
-
-struct Conf
-{
- ulong nmach; /* processors */
- ulong nproc; /* processes */
- ulong mem; /* total physical bytes of memory */
- ulong sparemem; /* memory left for check/dump and chans */
- ulong nalarm; /* alarms */
- ulong nuid; /* distinct uids */
- ulong nserve; /* server processes */
- ulong nfile; /* number of fid -- system wide */
- ulong nwpath; /* number of active paths, derrived from nfile */
- ulong gidspace; /* space for gid names -- derrived from nuid */
- ulong nlgmsg; /* number of large message buffers */
- ulong nsmmsg; /* number of small message buffers */
- ulong wcpsize; /* memory for worm copies */
- ulong recovcw; /* recover addresses */
- ulong recovro;
- ulong firstsb;
- ulong recovsb;
- uchar nodump; /* no periodic dumps */
- uchar ripoff;
- uchar dumpreread; /* read and compare in dump copy */
-
- ulong npage0; /* total physical pages of memory */
- ulong npage1; /* total physical pages of memory */
- ulong base0; /* base of bank 0 */
- ulong base1; /* base of bank 1 */
-};
-
-/*
- * message buffers
- * 2 types, large and small
- */
-struct Msgbuf
-{
- short count;
- short flags;
- #define LARGE (1<<0)
- #define FREE (1<<1)
- #define BFREE (1<<2)
- Chan* chan;
- Msgbuf* next;
- ulong param;
- int category;
- char* data;
- char* xdata;
-};
-
-/*
- * message buffer categories
- */
-enum
-{
- Mxxx = 0,
- Mbreply1,
- Mbreply2,
- Mbreply3,
- Mbreply4,
- Mbarp1,
- Mbarp2,
- Mbip1,
- Mbip2,
- Mbip3,
- Mbil1,
- Mbil2,
- Mbil3,
- Mbil4,
- Mbilauth,
- Maeth1,
- Maeth2,
- Maeth3,
- Mbeth1,
- Mbeth2,
- Mbeth3,
- Mbeth4,
- Mbsntp,
- MAXCAT,
-};
-
-struct Mach
-{
- int machno; /* physical id of processor */
- int mmask; /* 1<<m->machno */
- ulong ticks; /* of the clock since boot time */
- int lights; /* light lights, this processor */
- User* proc; /* current process on this processor */
- Label sched; /* scheduler wakeup */
- Lock alarmlock; /* access to alarm list */
- void* alarm; /* alarms bound to this clock */
- void (*intr)(Ureg*, ulong); /* pending interrupt */
- User* intrp; /* process that was interrupted */
- ulong cause; /* arg to intr */
- Ureg* ureg; /* arg to intr */
- uchar stack[1];
-};
-
-#define MAXSTACK 4000
-#define NHAS 100
-struct User
-{
- Label sched;
- Mach* mach; /* machine running this proc */
- User* rnext; /* next process in run queue */
- User* qnext; /* next process on queue for a QLock */
- void (*start)(void); /* startup function */
- char* text; /* name of this process */
- void* arg;
- Filter time[3]; /* cpu time used */
- int exiting;
- int pid;
- int state;
- Rendez tsleep;
-
- ulong twhen;
- Rendez *trend;
- User *tlink;
- int (*tfn)(void*);
-
- struct
- {
- QLock* q[NHAS];/* list of locks this process has */
- QLock* want; /* lock waiting */
- } has;
- uchar stack[MAXSTACK];
-};
-
-#define PRINTSIZE 256
-struct
-{
- Lock;
- int machs;
- int exiting;
-} active;
-
-struct Command
-{
- char* arg0;
- char* help;
- void (*func)(int, char*[]);
-};
-
-struct Flag
-{
- char* arg0;
- char* help;
- ulong flag;
-};
-
-struct Tm
-{
- /* see ctime(3) */
- int sec;
- int min;
- int hour;
- int mday;
- int mon;
- int year;
- int wday;
- int yday;
- int isdst;
-};
-
-struct Rtc
-{
- int sec;
- int min;
- int hour;
- int mday;
- int mon;
- int year;
-};
-
-/*
- * cw device
- */
-
-/* DONT TOUCH, this is the disk structure */
-struct Cache
-{
- long maddr; /* cache map addr */
- long msize; /* cache map size in buckets */
- long caddr; /* cache addr */
- long csize; /* cache size */
- long fsize; /* current size of worm */
- long wsize; /* max size of the worm */
- long wmax; /* highwater write */
-
- long sbaddr; /* super block addr */
- long cwraddr; /* cw root addr */
- long roraddr; /* dump root addr */
-
- long toytime; /* somewhere convienent */
- long time;
-};
-
-/* DONT TOUCH, this is the disk structure */
-struct Centry
-{
- ushort age;
- short state;
- long waddr; /* worm addr */
-};
-
-/* DONT TOUCH, this is the disk structure */
-struct Bucket
-{
- long agegen; /* generator for ages in this bkt */
- Centry entry[CEPERBK];
-};
-
-/*
- * scsi i/o
- */
-enum
-{
- SCSIread = 0,
- SCSIwrite = 1,
-};
-
-/*
- * Process states
- */
-enum
-{
- Dead = 0,
- Moribund,
- Zombie,
- Ready,
- Scheding,
- Running,
- Queueing,
- Sending,
- Recving,
- MMUing,
- Exiting,
- Inwait,
- Wakeme,
- Broken,
-};
-
-/*
- * Lights
- */
-enum
-{
- Lreal = 0, /* blink in clock interrupt */
- Lintr, /* on while in interrupt */
- Lpanic, /* in panic */
- Lcwmap, /* in cw lookup */
-};
-
-/*
- * devnone block numbers
- */
-enum
-{
- Cwio1 = 1,
- Cwio2,
- Cwxx1,
- Cwxx2,
- Cwxx3,
- Cwxx4,
- Cwdump1,
- Cwdump2,
- Cuidbuf,
- Cckbuf,
-};
-
-#define MAXFDATA 8192
-/*
- * P9 protocol message types
- */
-/* DONT TOUCH, this the 9P protocol */
-enum
-{
- Tnop = 50,
- Rnop,
- Tosession = 52,
- Rosession,
- Terror = 54, /* illegal */
- Rerror,
- Tflush = 56,
- Rflush,
- Toattach = 58,
- Roattach,
- Tclone = 60,
- Rclone,
- Twalk = 62,
- Rwalk,
- Topen = 64,
- Ropen,
- Tcreate = 66,
- Rcreate,
- Tread = 68,
- Rread,
- Twrite = 70,
- Rwrite,
- Tclunk = 72,
- Rclunk,
- Tremove = 74,
- Rremove,
- Tstat = 76,
- Rstat,
- Twstat = 78,
- Rwstat,
- Tclwalk = 80,
- Rclwalk,
- Tauth = 82, /* illegal */
- Rauth, /* illegal */
- Tsession = 84,
- Rsession,
- Tattach = 86,
- Rattach,
-
- MAXSYSCALL
-};
-
-/*
- * error codes generated from the file server
- */
-enum
-{
- Ebadspc = 1,
- Efid,
- Echar,
- Eopen,
- Ecount,
- Ealloc,
- Eqid,
- Eaccess,
- Eentry,
- Emode,
- Edir1,
- Edir2,
- Ephase,
- Eexist,
- Edot,
- Eempty,
- Ebadu,
- Enotu,
- Enotg,
- Ename,
- Ewalk,
- Eronly,
- Efull,
- Eoffset,
- Elocked,
- Ebroken,
- Eauth,
- Enoattach,
- MAXERR
-};
-
-/*
- * device types
- */
-enum
-{
- Devnone = 0,
- Devcon, /* console */
- Devwren, /* scsi disk drive */
- Devworm, /* scsi video drive */
- Devlworm, /* scsi video drive (labeled) */
- Devfworm, /* fake read-only device */
- Devjuke, /* jukebox */
- Devcw, /* cache with worm */
- Devro, /* readonly worm */
- Devcycl, /* cyclone fiber uart */
- Devmcat, /* multiple cat devices */
- Devmlev, /* multiple interleave devices */
- Devil, /* internet link */
- Devpart, /* partition */
- Devfloppy, /* floppy drive */
- Devide, /* IDE drive */
- Devswab, /* swab data between mem and device */
- Devdup, /* Dup drive */
- MAXDEV
-};
-
-/*
- * tags on block
- */
-/* DONT TOUCH, this is in disk structures */
-enum
-{
- Tnone = 0,
- Tsuper, /* the super block */
- Tdir, /* directory contents */
- Tind1, /* points to blocks */
- Tind2, /* points to Tind1 */
- Tfile, /* file contents */
- Tfree, /* in free list */
- Tbuck, /* cache fs bucket */
- Tvirgo, /* fake worm virgin bits */
- Tcache, /* cw cache things */
- Tconfig, /* configuration block */
- MAXTAG
-};
-
-/*
- * flags to getbuf
- */
-enum
-{
- Bread = (1<<0), /* read the block if miss */
- Bprobe = (1<<1), /* return null if miss */
- Bmod = (1<<2), /* buffer is dirty, needs writing */
- Bimm = (1<<3), /* write immediately on putbuf */
- Bres = (1<<4), /* reserved, never renammed */
-};
-
-/*
- * open modes passed into P9 open/create
- */
-/* DONT TOUCH, this the P9 protocol */
-enum
-{
- MREAD = 0,
- MWRITE,
- MBOTH,
- MEXEC,
- MTRUNC = (1<<4), /* truncate on open */
- MCEXEC = (1<<5), /* close on exec (host) */
- MRCLOSE = (1<<6), /* remove on close */
-};
-
-
-/*
- * Ethernet header
- */
-enum
-{
- ETHERMINTU = 60, /* minimum transmit size */
- ETHERMAXTU = 1514, /* maximum transmit size */
-
- Arptype = 0x0806,
- Iptype = 0x0800,
-
- Icmpproto = 1,
- Igmpproto = 2,
- Tcpproto = 6,
- Udpproto = 17,
- Ilproto = 40,
-
- Nqueue = 20,
- Nfrag = 6, /* max number of non-contig ip fragments */
- Nrock = 20, /* number of partial ip assembly stations */
- Nb = 211, /* number of arp hash buckets */
- Ne = 10, /* number of entries in each arp hash bucket */
-
- Ensize = 14, /* ether header size */
- Ipsize = 20, /* ip header size -- doesnt include Ensize */
- Arpsize = 28, /* arp header size -- doesnt include Ensize */
- Ilsize = 18, /* il header size -- doesnt include Ipsize/Ensize */
- Udpsize = 8, /* il header size -- doesnt include Ipsize/Ensize */
- Udpphsize = 12, /* udp pseudo ip header size */
-
- IP_VER = 0x40, /* Using IP version 4 */
- IP_HLEN = Ipsize/4, /* Header length in longs */
- IP_DF = 0x4000, /* Don't fragment */
- IP_MF = 0x2000, /* More fragments */
-
- Arprequest = 1,
- Arpreply,
-
- Ilfsport = 17008,
- Ilauthport = 17020,
- Ilfsout = 5000,
- SNTP = 123,
- SNTP_LOCAL = 6001,
-};
-
-struct Enpkt
-{
- uchar d[Easize]; /* destination address */
- uchar s[Easize]; /* source address */
- uchar type[2]; /* packet type */
-
- uchar data[ETHERMAXTU-(6+6+2)];
- uchar crc[4];
-};
-
-struct Arppkt
-{
- uchar d[Easize]; /* ether header */
- uchar s[Easize];
- uchar type[2];
-
- uchar hrd[2]; /* hardware type, must be ether==1 */
- uchar pro[2]; /* protocol, must be ip */
- uchar hln; /* hardware address len, must be Easize */
- uchar pln; /* protocol address len, must be Pasize */
- uchar op[2];
- uchar sha[Easize];
- uchar spa[Pasize];
- uchar tha[Easize];
- uchar tpa[Pasize];
-};
-
-struct Ippkt
-{
- uchar d[Easize]; /* ether header */
- uchar s[Easize];
- uchar type[2];
-
- uchar vihl; /* Version and header length */
- uchar tos; /* Type of service */
- uchar length[2]; /* packet length */
- uchar id[2]; /* Identification */
- uchar frag[2]; /* Fragment information */
- uchar ttl; /* Time to live */
- uchar proto; /* Protocol */
- uchar cksum[2]; /* Header checksum */
- uchar src[Pasize]; /* Ip source */
- uchar dst[Pasize]; /* Ip destination */
-};
-
-struct Ilpkt
-{
- uchar d[Easize]; /* ether header */
- uchar s[Easize];
- uchar type[2];
-
- uchar vihl; /* ip header */
- uchar tos;
- uchar length[2];
- uchar id[2];
- uchar frag[2];
- uchar ttl;
- uchar proto;
- uchar cksum[2];
- uchar src[Pasize];
- uchar dst[Pasize];
-
- uchar ilsum[2]; /* Checksum including header */
- uchar illen[2]; /* Packet length */
- uchar iltype; /* Packet type */
- uchar ilspec; /* Special */
- uchar ilsrc[2]; /* Src port */
- uchar ildst[2]; /* Dst port */
- uchar ilid[4]; /* Sequence id */
- uchar ilack[4]; /* Acked sequence */
-};
-
-struct Udppkt
-{
- uchar d[Easize]; /* ether header */
- uchar s[Easize];
- uchar type[2];
-
- uchar vihl; /* ip header */
- uchar tos;
- uchar length[2];
- uchar id[2];
- uchar frag[2];
- uchar ttl;
- uchar proto;
- uchar cksum[2];
- uchar src[Pasize];
- uchar dst[Pasize];
-
- uchar udpsrc[2]; /* Src port */
- uchar udpdst[2]; /* Dst port */
- uchar udplen[2]; /* Packet length */
- uchar udpsum[2]; /* Checksum including header */
-};
-
-struct Icmppkt
-{
- uchar d[Easize]; /* ether header */
- uchar s[Easize];
- uchar type[2];
-
- uchar vihl; /* ip header */
- uchar tos;
- uchar length[2];
- uchar id[2];
- uchar frag[2];
- uchar ttl;
- uchar proto;
- uchar cksum[2];
- uchar src[Pasize];
- uchar dst[Pasize];
-
- uchar icmptype; /* Src port */
- uchar icmpcode; /* Dst port */
- uchar icmpsum[2]; /* Checksum including header */
-
- uchar icmpbody[10]; /* Depends on type */
-};
-
-struct Ifc
-{
- Lock;
- Queue* reply;
- Filter work[3];
- Filter rate[3];
- ulong rcverr;
- ulong txerr;
- ulong sumerr;
- ulong rxpkt;
- ulong txpkt;
- uchar ea[Easize]; /* my ether address */
- uchar ipa[Pasize]; /* my ip address, pulled from netdb */
- uchar netgate[Pasize]; /* my ip gateway, pulled from netdb */
- ulong ipaddr;
- ulong mask;
- ulong cmask;
- Ifc *next; /* List of configured interfaces */
-};
-
-extern register Mach* m;
-extern register User* u;
-extern Talarm talarm;
-
-Conf conf;
-Cons cons;
-#define MACHP(n) ((Mach*)(MACHADDR+n*BY2PG))
-
-#pragma varargck type "D" Device*
-#pragma varargck type "T" ulong
-#pragma varargck type "I" uchar*
-#pragma varargck type "E" uchar*
-#pragma varargck type "F" Filter*
-#pragma varargck type "G" int
//GO.SYSIN DD port/portdat.h
echo port/sub.c
sed 's/.//' >port/sub.c <<'//GO.SYSIN DD port/sub.c'
-#include "all.h"
-#include "io.h"
-
-Filsys*
-fsstr(char *p)
-{
- Filsys *fs;
-
- for(fs=filsys; fs->name; fs++)
- if(strcmp(fs->name, p) == 0)
- return fs;
- return 0;
-}
-
-/*
- * allocate 'count' contiguous channels
- * of type 'type' and return pointer to base
- */
-Chan*
-chaninit(int type, int count)
-{
- Chan *cp, *icp;
- int i;
-
- icp = ialloc(count * sizeof(*icp), 0);
- cp = icp;
- for(i=0; i<count; i++) {
- cp->next = chans;
- chans = cp;
- cp->type = type;
- cp->chan = cons.chano;
- cons.chano++;
- strncpy(cp->whoname, "<none>", sizeof(cp->whoname));
- dofilter(&cp->work, C0a, C0b, 1);
- dofilter(&cp->rate, C0a, C0b, 1000);
- fileinit(cp);
- wlock(&cp->reflock);
- wunlock(&cp->reflock);
- rlock(&cp->reflock);
- runlock(&cp->reflock);
- cp++;
- }
- return icp;
-}
-
-void
-fileinit(Chan *cp)
-{
- File *f, *prev;
- Tlock *t;
- int h;
-
-loop:
- lock(&flock);
- for(h=0; h<nelem(flist); h++) {
- for(prev=0,f=flist[h]; f; prev=f,f=f->next) {
- if(f->cp != cp)
- continue;
- if(prev) {
- prev->next = f->next;
- f->next = flist[h];
- flist[h] = f;
- }
- goto out;
- }
- }
- unlock(&flock);
- return;
-
-out:
- flist[h] = f->next;
- unlock(&flock);
-
- qlock(f);
- if(t = f->tlock) {
- t->time = 0;
- f->tlock = 0;
- }
- if(f->open & FREMOV)
- doremove(f, 0);
- freewp(f->wpath);
- f->open = 0;
- f->cp = 0;
- qunlock(f);
-
- goto loop;
-}
-
-/*
- * returns a locked file structure
- */
-File*
-filep(Chan *cp, int fid, int flag)
-{
- File *f;
- int h;
-
- if(fid == NOF)
- return 0;
-
- h = (long)cp + fid;
- if(h < 0)
- h = ~h;
- h = h % nelem(flist);
-
-loop:
- lock(&flock);
- for(f=flist[h]; f; f=f->next)
- if(f->fid == fid && f->cp == cp)
- goto out;
-
- if(flag) {
- f = newfp();
- if(f) {
- f->fid = fid;
- f->cp = cp;
- f->wpath = 0;
- f->tlock = 0;
- f->next = flist[h];
- flist[h] = f;
- goto out;
- }
- }
- unlock(&flock);
- return 0;
-
-out:
- unlock(&flock);
- qlock(f);
- if(f->fid == fid && f->cp == cp)
- return f;
- qunlock(f);
- goto loop;
-}
-
-/*
- * always called with flock locked
- */
-File*
-newfp(void)
-{
- static first;
- File *f;
- int start, i;
-
- i = first;
- start = i;
- do {
- f = &files[i];
- i++;
- if(i >= conf.nfile)
- i = 0;
- if(f->cp)
- continue;
-
- first = i;
-
- return f;
- } while(i != start);
-
- print("out of files\n");
- return 0;
-}
-
-void
-freefp(File *fp)
-{
- Chan *cp;
- File *f, *prev;
- int h;
-
- if(!fp || !(cp = fp->cp))
- return;
-
- h = (long)cp + fp->fid;
- if(h < 0)
- h = ~h;
- h = h % nelem(flist);
-
- lock(&flock);
- for(prev=0,f=flist[h]; f; prev=f,f=f->next)
- if(f == fp) {
- if(prev)
- prev->next = f->next;
- else
- flist[h] = f->next;
- break;
- }
- fp->cp = 0;
- unlock(&flock);
-}
-
-int
-iaccess(File *f, Dentry *d, int m)
-{
-
- /* uid none gets only other permissions */
- if(f->uid == 0)
- goto doother;
-
- /*
- * owner
- */
- if(f->uid == d->uid)
- if((m<<6) & d->mode)
- return 0;
- /*
- * group membership
- */
- if(ingroup(f->uid, d->gid))
- if((m<<3) & d->mode)
- return 0;
-
-doother:
- /*
- * other
- */
- if(m & d->mode) {
- if((d->mode & DDIR) && (m == DEXEC))
- return 0;
- if(!ingroup(f->uid, 9999))
- return 0;
- }
-
- /*
- * various forms of superuser
- */
- if(wstatallow)
- return 0;
- if(duallow != 0 && duallow == f->uid)
- if((d->mode & DDIR) && (m == DREAD || m == DEXEC))
- return 0;
-
- return 1;
-}
-
-Tlock*
-tlocked(Iobuf *p, Dentry *d)
-{
- Tlock *t, *t1;
- long qpath, tim;
- Device *dev;
-
- tim = toytime();
- qpath = d->qid.path;
- dev = p->dev;
-
-again:
- t1 = 0;
- for(t=tlocks+NTLOCK-1; t>=tlocks; t--) {
- if(t->qpath == qpath)
- if(t->time >= tim)
- if(t->dev == dev)
- return nil; /* its locked */
- if(t1 != nil && t->time == 0)
- t1 = t; /* remember free lock */
- }
- if(t1 == 0) {
- // reclaim old locks
- lock(&tlocklock);
- for(t=tlocks+NTLOCK-1; t>=tlocks; t--)
- if(t->time < tim) {
- t->time = 0;
- t1 = t;
- }
- unlock(&tlocklock);
- }
- if(t1) {
- lock(&tlocklock);
- if(t1->time != 0) {
- unlock(&tlocklock);
- goto again;
- }
- t1->dev = dev;
- t1->qpath = qpath;
- t1->time = tim + TLOCK;
- unlock(&tlocklock);
- }
- /* botch
- * out of tlock nodes simulates
- * a locked file
- */
- return t1;
-}
-
-Wpath*
-newwp(void)
-{
- static int si = 0;
- int i;
- Wpath *w, *sw, *ew;
-
- i = si + 1;
- if(i < 0 || i >= conf.nwpath)
- i = 0;
- si = i;
- sw = &wpaths[i];
- ew = &wpaths[conf.nwpath];
- for(w=sw;;) {
- w++;
- if(w >= ew)
- w = &wpaths[0];
- if(w == sw) {
- print("out of wpaths\n");
- return 0;
- }
- if(w->refs)
- continue;
- lock(&wpathlock);
- if(w->refs) {
- unlock(&wpathlock);
- continue;
- }
- w->refs = 1;
- w->up = 0;
- unlock(&wpathlock);
- return w;
- }
-
-}
-
-void
-freewp(Wpath *w)
-{
- lock(&wpathlock);
- for(; w; w=w->up)
- w->refs--;
- unlock(&wpathlock);
-}
-
-Qid
-newqid(Device *dev)
-{
- Iobuf *p;
- Superb *sb;
- Qid qid;
-
- p = getbuf(dev, superaddr(dev), Bread|Bmod);
- if(!p || checktag(p, Tsuper, QPSUPER))
- panic("newqid: super block");
- sb = (Superb*)p->iobuf;
- sb->qidgen++;
- qid.path = sb->qidgen;
- qid.version = 0;
- putbuf(p);
- return qid;
-}
-
-void
-buffree(Device *dev, long addr, int d)
-{
- Iobuf *p;
- long a;
- int i;
-
- if(!addr)
- return;
- if(d > 0) {
- d--;
- p = getbuf(dev, addr, Bread);
- if(p) {
- for(i=INDPERBUF-1; i>=0; i--) {
- a = ((long*)p->iobuf)[i];
- buffree(dev, a, d);
- }
- putbuf(p);
- }
- }
- /*
- * stop outstanding i/o
- */
- p = getbuf(dev, addr, Bprobe);
- if(p) {
- p->flags &= ~(Bmod|Bimm);
- putbuf(p);
- }
- /*
- * dont put written worm
- * blocks into free list
- */
- if(dev->type == Devcw) {
- i = cwfree(dev, addr);
- if(i)
- return;
- }
- p = getbuf(dev, superaddr(dev), Bread|Bmod);
- if(!p || checktag(p, Tsuper, QPSUPER))
- panic("buffree: super block");
- addfree(dev, addr, (Superb*)p->iobuf);
- putbuf(p);
-}
-
-long
-bufalloc(Device *dev, int tag, long qid, int uid)
-{
- Iobuf *bp, *p;
- Superb *sb;
- long a;
- int n;
-
- p = getbuf(dev, superaddr(dev), Bread|Bmod);
- if(!p || checktag(p, Tsuper, QPSUPER)) {
- print("bufalloc: super block\n");
- if(p)
- putbuf(p);
- return 0;
- }
- sb = (Superb*)p->iobuf;
-
-loop:
- n = --sb->fbuf.nfree;
- sb->tfree--;
- if(n < 0 || n >= FEPERBUF) {
- print("bufalloc: bad freelist\n");
- n = 0;
- sb->fbuf.free[0] = 0;
- }
- a = sb->fbuf.free[n];
- if(n <= 0) {
- if(a == 0) {
- sb->tfree = 0;
- sb->fbuf.nfree = 1;
- if(dev->type == Devcw) {
- n = uid;
- if(n < 0 || n >= nelem(growacct))
- n = 0;
- growacct[n]++;
- if(cwgrow(dev, sb, uid))
- goto loop;
- }
- putbuf(p);
- print("fs full uid=%d\n", uid);
- return 0;
- }
- bp = getbuf(dev, a, Bread);
- if(!bp || checktag(bp, Tfree, QPNONE)) {
- if(bp)
- putbuf(bp);
- putbuf(p);
- return 0;
- }
- sb->fbuf = *(Fbuf*)bp->iobuf;
- putbuf(bp);
- }
-
- bp = getbuf(dev, a, Bmod);
- memset(bp->iobuf, 0, RBUFSIZE);
- settag(bp, tag, qid);
- if(tag == Tind1 || tag == Tind2 || tag == Tdir)
- bp->flags |= Bimm;
- putbuf(bp);
- putbuf(p);
- return a;
-}
-
-/*
- * what are legal characters in a name?
- * only disallow control characters.
- * a) utf avoids control characters.
- * b) '/' may not be the separator
- */
-int
-checkname(char *n)
-{
- int i, c;
-
- for(i=0; i<NAMELEN; i++) {
- c = *n & 0xff;
- if(c == 0) {
- if(i == 0)
- return 1;
- memset(n, 0, NAMELEN-i);
- return 0;
- }
- if(c <= 040)
- return 1;
- n++;
- }
- return 1; /* too long */
-}
-
-void
-addfree(Device *dev, long addr, Superb *sb)
-{
- int n;
- Iobuf *p;
-
- n = sb->fbuf.nfree;
- if(n < 0 || n > FEPERBUF)
- panic("addfree: bad freelist");
- if(n >= FEPERBUF) {
- p = getbuf(dev, addr, Bmod|Bimm);
- if(p == 0)
- panic("addfree: getbuf");
- *(Fbuf*)p->iobuf = sb->fbuf;
- settag(p, Tfree, QPNONE);
- putbuf(p);
- n = 0;
- }
- sb->fbuf.free[n++] = addr;
- sb->fbuf.nfree = n;
- sb->tfree++;
- if(addr >= sb->fsize)
- sb->fsize = addr+1;
-}
-
-int
-Cconv(Op *o)
-{
- Chan *cp;
- char s[20];
-
- cp = *(Chan**)o->argp;
- sprint(s, "C%d.%.3d", cp->type, cp->chan);
- strconv(s, o, o->f1, o->f2);
- return sizeof(cp);
-}
-
-int
-Dconv(Op *o)
-{
- Device *d;
- int c, c1;
- char s[100];
-
- d = *(Device**)o->argp;
- if(d == 0) {
- sprint(s, "D***");
- goto out;
- }
- switch(d->type) {
- default:
- sprint(s, "D%d", d->type);
- break;
- case Devwren:
- c = 'w';
- goto d1;
- case Devworm:
- c = 'r';
- goto d1;
- case Devlworm:
- c = 'l';
- goto d1;
- d1:
- if(d->wren.ctrl == 0 && d->wren.lun == 0)
- sprint(s, "%c%d", c, d->wren.targ);
- else
- sprint(s, "%c%d.%d.%d", c, d->wren.ctrl, d->wren.targ, d->wren.lun);
- break;
- case Devmcat:
- c = '(';
- c1 = ')';
- goto d2;
- case Devmlev:
- c = '[';
- c1 = ']';
- d2:
- if(d->cat.first == d->cat.last)
- sprint(s, "%c%D%c", c, d->cat.first, c1);
- else
- if(d->cat.first->link == d->cat.last)
- sprint(s, "%c%D%D%c", c, d->cat.first, d->cat.last, c1);
- else
- sprint(s, "%c%D-%D%c", c, d->cat.first, d->cat.last, c1);
- break;
- case Devro:
- sprint(s, "o%D%D", d->ro.parent->cw.c, d->ro.parent->cw.w);
- break;
- case Devcw:
- sprint(s, "c%D%D", d->cw.c, d->cw.w);
- break;
- case Devjuke:
- sprint(s, "j%D%D", d->j.j, d->j.m);
- break;
- case Devpart:
- sprint(s, "p%ld.%ld", d->part.base, d->part.size);
- break;
- case Devswab:
- sprint(s, "x%D", d->swab.d);
- break;
- }
-out:
- strconv(s, o, o->f1, o->f2);
- return sizeof(d);
-}
-
-int
-Fconv(Op *o)
-{
- Filter* a;
- char s[30];
-
- a = *(Filter**)o->argp;
-
- sprint(s, "%lud", fdf(a->filter, a->c3*a->c1));
- strconv(s, o, o->f1, o->f2);
- return sizeof(a);
-}
-
-int
-Gconv(Op *o)
-{
- int t;
- char s[20];
-
- t = *(int*)o->argp;
- strcpy(s, "<badtag>");
- if(t >= 0 && t < MAXTAG)
- sprint(s, "%s", tagnames[t]);
- strconv(s, o, o->f1, o->f2);
- return sizeof(t);
-}
-
-int
-Econv(Op *o)
-{
- char s[64];
- uchar *p;
-
- p = *((uchar**)o->argp);
- sprint(s, "%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux",
- p[0], p[1], p[2], p[3], p[4], p[5]);
- strconv(s, o, o->f1, o->f2);
- return sizeof(uchar*);
-}
-
-int
-Iconv(Op *o)
-{
- char s[64];
- uchar *p;
-
- p = *((uchar**)o->argp);
- sprint(s, "%d.%d.%d.%d",
- p[0], p[1], p[2], p[3]);
- strconv(s, o, o->f1, o->f2);
- return sizeof(uchar*);
-}
-
-int
-Nconv(Op *o)
-{
- char s[64];
- uchar *p;
- long n;
-
- p = *((uchar**)o->argp);
- n = (p[0]<<8) | p[1];
- if(!(o->f3 & FSHORT))
- n = (n<<16) | (p[2]<<8) | p[3];
- sprint(s, "%lud", n);
- strconv(s, o, o->f1, o->f2);
- return sizeof(uchar*);
-}
-
-void
-formatinit(void)
-{
-
- fmtinstall('C', Cconv); /* print channels */
- fmtinstall('D', Dconv); /* print devices */
- fmtinstall('F', Fconv); /* print filters */
- fmtinstall('G', Gconv); /* print tags */
- fmtinstall('T', Tconv); /* print times */
- fmtinstall('E', Econv); /* print ether addresses */
- fmtinstall('I', Iconv); /* print ip addresses */
- fmtinstall('N', Nconv); /* print network order integers */
-}
-
-int
-nzip(uchar ip[Pasize])
-{
- if(ip[0] || ip[1] || ip[2] || ip[3])
- return 1;
- return 0;
-}
-
-void
-rootream(Device *dev, long addr)
-{
- Iobuf *p;
- Dentry *d;
-
- p = getbuf(dev, addr, Bmod|Bimm);
- memset(p->iobuf, 0, RBUFSIZE);
- settag(p, Tdir, QPROOT);
- d = getdir(p, 0);
- strcpy(d->name, "/");
- d->uid = -1;
- d->gid = -1;
- d->mode = DALLOC | DDIR |
- ((DREAD|DEXEC) << 6) |
- ((DREAD|DEXEC) << 3) |
- ((DREAD|DEXEC) << 0);
- d->qid = QID(QPROOT|QPDIR,0);
- d->atime = time();
- d->mtime = d->atime;
- d->wuid = 0;
- putbuf(p);
-}
-
-void
-superream(Device *dev, long addr)
-{
- Iobuf *p;
- Superb *s;
- long i;
-
- p = getbuf(dev, addr, Bmod|Bimm);
- memset(p->iobuf, 0, RBUFSIZE);
- settag(p, Tsuper, QPSUPER);
-
- s = (Superb*)p->iobuf;
- s->fstart = 2;
- s->fsize = devsize(dev);
- s->fbuf.nfree = 1;
- s->qidgen = 10;
- for(i=s->fsize-1; i>=addr+2; i--)
- addfree(dev, i, s);
- putbuf(p);
-}
-
-struct
-{
- Lock;
- Msgbuf *smsgbuf;
- Msgbuf *lmsgbuf;
-} msgalloc;
-
-void
-mbinit(void)
-{
- Msgbuf *mb;
- Rabuf *rb;
- int i;
-
- lock(&msgalloc);
- unlock(&msgalloc);
- msgalloc.lmsgbuf = 0;
- msgalloc.smsgbuf = 0;
- for(i=0; i<conf.nlgmsg; i++) {
- mb = ialloc(sizeof(Msgbuf), 0);
- if(1)
- mb->xdata = ialloc(LARGEBUF+256, 256);
- else
- mb->xdata = ialloc(LARGEBUF+OFFMSG, LINESIZE);
- mb->flags = LARGE;
- mbfree(mb);
- cons.nlarge++;
- }
- for(i=0; i<conf.nsmmsg; i++) {
- mb = ialloc(sizeof(Msgbuf), 0);
- if(1)
- mb->xdata = ialloc(SMALLBUF+256, 256);
- else
- mb->xdata = ialloc(SMALLBUF+OFFMSG, LINESIZE);
- mb->flags = 0;
- mbfree(mb);
- cons.nsmall++;
- }
- memset(mballocs, 0, sizeof(mballocs));
-
- lock(&rabuflock);
- unlock(&rabuflock);
- rabuffree = 0;
- for(i=0; i<1000; i++) {
- rb = ialloc(sizeof(*rb), 0);
- rb->link = rabuffree;
- rabuffree = rb;
- }
-}
-
-Msgbuf*
-mballoc(int count, Chan *cp, int category)
-{
- Msgbuf *mb;
-
- ilock(&msgalloc);
- if(count > SMALLBUF) {
- if(count > LARGEBUF)
- panic("msgbuf count");
- mb = msgalloc.lmsgbuf;
- if(mb == 0) {
- mb = ialloc(sizeof(Msgbuf), 0);
- if(1)
- mb->xdata = ialloc(LARGEBUF+256, 256);
- else
- mb->xdata = ialloc(LARGEBUF+OFFMSG, LINESIZE);
- cons.nlarge++;
- } else
- msgalloc.lmsgbuf = mb->next;
- mb->flags = LARGE;
- } else {
- mb = msgalloc.smsgbuf;
- if(mb == 0) {
- mb = ialloc(sizeof(Msgbuf), 0);
- if(1)
- mb->xdata = ialloc(SMALLBUF+256, 256);
- else
- mb->xdata = ialloc(SMALLBUF+OFFMSG, LINESIZE);
- cons.nsmall++;
- } else
- msgalloc.smsgbuf = mb->next;
- mb->flags = 0;
- }
- mballocs[category]++;
- iunlock(&msgalloc);
- mb->count = count;
- mb->chan = cp;
- mb->next = 0;
- mb->param = 0;
- mb->category = category;
- if(1)
- mb->data = mb->xdata+256;
- else
- mb->data = mb->xdata+OFFMSG;
- return mb;
-}
-
-void
-mbfree(Msgbuf *mb)
-{
- if(mb->flags & FREE)
- panic("mbfree already free");
-
- ilock(&msgalloc);
- mballocs[mb->category]--;
- mb->flags |= FREE;
- if(mb->flags & LARGE) {
- mb->next = msgalloc.lmsgbuf;
- msgalloc.lmsgbuf = mb;
- } else {
- mb->next = msgalloc.smsgbuf;
- msgalloc.smsgbuf = mb;
- }
- mb->data = 0;
- iunlock(&msgalloc);
-}
-
-/*
- * returns 1 if n is prime
- * used for adjusting lengths
- * of hashing things.
- * there is no need to be clever
- */
-int
-prime(long n)
-{
- long i;
-
- if((n%2) == 0)
- return 0;
- for(i=3;; i+=2) {
- if((n%i) == 0)
- return 0;
- if(i*i >= n)
- return 1;
- }
-}
-
-char*
-getwd(char *word, char *line)
-{
- int c, n;
-
- while(*line == ' ')
- line++;
- for(n=0; n<80; n++) {
- c = *line;
- if(c == ' ' || c == 0 || c == '\n')
- break;
- line++;
- *word++ = c;
- }
- *word = 0;
- return line;
-}
-
-void
-hexdump(void *a, int n)
-{
- char s1[30], s2[4];
- uchar *p;
- int i;
-
- p = a;
- s1[0] = 0;
- for(i=0; i<n; i++) {
- sprint(s2, " %.2ux", p[i]);
- strcat(s1, s2);
- if((i&7) == 7) {
- print("%s\n", s1);
- s1[0] = 0;
- }
- }
- if(s1[0])
- print("%s\n", s1);
-}
-
-void*
-recv(Queue *q, int)
-{
- User *p;
- void *a;
- int i, c;
- long s;
-
- if(q == 0)
- panic("recv null q");
- for(;;) {
- lock(q);
- c = q->count;
- if(c > 0) {
- i = q->loc;
- a = q->args[i];
- i++;
- if(i >= q->size)
- i = 0;
- q->loc = i;
- q->count = c-1;
- p = q->whead;
- if(p) {
- q->whead = p->qnext;
- if(q->whead == 0)
- q->wtail = 0;
- ready(p);
- }
- unlock(q);
- return a;
- }
- p = q->rtail;
- if(p == 0)
- q->rhead = u;
- else
- p->qnext = u;
- q->rtail = u;
- u->qnext = 0;
- s = splhi();
- u->state = Recving;
- unlock(q);
- sched();
- splx(s);
- }
- return 0;
-}
-
-void
-send(Queue *q, void *a)
-{
- User *p;
- int i, c;
- long s;
-
- if(q == 0)
- panic("send null q");
- for(;;) {
- lock(q);
- c = q->count;
- if(c < q->size) {
- i = q->loc + c;
- if(i >= q->size)
- i -= q->size;
- q->args[i] = a;
- q->count = c+1;
- p = q->rhead;
- if(p) {
- q->rhead = p->qnext;
- if(q->rhead == 0)
- q->rtail = 0;
- ready(p);
- }
- unlock(q);
- return;
- }
- p = q->wtail;
- if(p == 0)
- q->whead = u;
- else
- p->qnext = u;
- q->wtail = u;
- u->qnext = 0;
- s = splhi();
- u->state = Sending;
- unlock(q);
- sched();
- splx(s);
- }
-}
-
-Queue*
-newqueue(int size)
-{
- Queue *q;
-
- q = ialloc(sizeof(Queue) + (size-1)*sizeof(void*), 0);
- q->size = size;
- lock(q);
- unlock(q);
- return q;
-}
-
-no(void*)
-{
- return 0;
-}
-
-int
-devread(Device *d, long b, void *c)
-{
- int e;
-
-loop:
- switch(d->type)
- {
- case Devcw:
- return cwread(d, b, c);
-
- case Devjuke:
- d = d->j.m;
- goto loop;
-
- case Devro:
- return roread(d, b, c);
-
- case Devwren:
- return wrenread(d, b, c);
- case Devide:
- return ideread(d, b, c);
-
- case Devworm:
- case Devlworm:
- return wormread(d, b, c);
-
- case Devfworm:
- return fwormread(d, b, c);
-
- case Devmcat:
- return mcatread(d, b, c);
-
- case Devmlev:
- return mlevread(d, b, c);
-
- case Devpart:
- return partread(d, b, c);
-
- case Devswab:
- e = devread(d->swab.d, b, c);
- if(e == 0)
- swab(c, 0);
- return e;
- }
- panic("illegal device in read: %D %ld", d, b);
- return 1;
-}
-
-int
-devwrite(Device *d, long b, void *c)
-{
- int e;
-
-loop:
- switch(d->type)
- {
- case Devcw:
- return cwwrite(d, b, c);
-
- case Devjuke:
- d = d->j.m;
- goto loop;
-
- case Devro:
- print("write to ro device %D(%ld)\n", d, b);
- return 1;
-
- case Devwren:
- return wrenwrite(d, b, c);
- case Devide:
- return idewrite(d, b, c);
-
- case Devworm:
- case Devlworm:
- return wormwrite(d, b, c);
-
- case Devfworm:
- return fwormwrite(d, b, c);
-
- case Devmcat:
- return mcatwrite(d, b, c);
-
- case Devmlev:
- return mlevwrite(d, b, c);
-
- case Devpart:
- return partwrite(d, b, c);
-
- case Devswab:
- swab(c, 1);
- e = devwrite(d->swab.d, b, c);
- swab(c, 0);
- return e;
- }
- panic("illegal device in write: %D %ld", d, b);
- return 1;
-}
-
-long
-devsize(Device *d)
-{
-
-loop:
- switch(d->type)
- {
- case Devcw:
- case Devro:
- return cwsize(d);
-
- case Devjuke:
- d = d->j.m;
- goto loop;
-
- case Devwren:
- return wrensize(d);
- case Devide:
- return atasize(d);
-
- case Devworm:
- case Devlworm:
- return wormsize(d);
-
- case Devfworm:
- return fwormsize(d);
-
- case Devmcat:
- return mcatsize(d);
-
- case Devmlev:
- return mlevsize(d);
-
- case Devpart:
- return partsize(d);
-
- case Devswab:
- d = d->swab.d;
- goto loop;
- }
- panic("illegal device in dev_size: %D", d);
- return 0;
-}
-
-long
-superaddr(Device *d)
-{
-
-loop:
- switch(d->type) {
- default:
- return SUPER_ADDR;
-
- case Devcw:
- case Devro:
- return cwsaddr(d);
-
- case Devswab:
- d = d->swab.d;
- goto loop;
- }
-}
-
-long
-getraddr(Device *d)
-{
-
-loop:
- switch(d->type) {
- default:
- return ROOT_ADDR;
-
- case Devcw:
- case Devro:
- return cwraddr(d);
-
- case Devswab:
- d = d->swab.d;
- goto loop;
- }
-}
-
-void
-devream(Device *d, int top)
-{
- Device *l;
-
-loop:
- print(" devream: %D %d\n", d, top);
- switch(d->type) {
- default:
- print("ream: unknown dev type %D\n", d);
- return;
-
- case Devcw:
- devream(d->cw.w, 0);
- devream(d->cw.c, 0);
- if(top) {
- wlock(&mainlock);
- cwream(d);
- wunlock(&mainlock);
- }
- devinit(d);
- return;
-
- case Devfworm:
- devream(d->fw.fw, 0);
- fwormream(d);
- break;
-
- case Devpart:
- devream(d->part.d, 0);
- break;
-
- case Devmlev:
- case Devmcat:
- for(l=d->cat.first; l; l=l->link)
- devream(l, 0);
- break;
-
- case Devjuke:
- case Devworm:
- case Devlworm:
- case Devwren:
- break;
-
- case Devswab:
- d = d->swab.d;
- goto loop;
- }
- devinit(d);
- if(top) {
- wlock(&mainlock);
- rootream(d, ROOT_ADDR);
- superream(d, SUPER_ADDR);
- wunlock(&mainlock);
- }
-}
-
-void
-devrecover(Device *d)
-{
-
-loop:
- print("recover: %D\n", d);
- switch(d->type) {
- default:
- print("recover: unknown dev type %D\n", d);
- return;
-
- case Devcw:
- wlock(&mainlock); /* recover */
- cwrecover(d);
- wunlock(&mainlock);
- break;
-
- case Devswab:
- d = d->swab.d;
- goto loop;
- }
-}
-
-void
-devinit(Device *d)
-{
-
-loop:
- if(d->init)
- return;
- d->init = 1;
- print(" devinit %D\n", d);
- switch(d->type) {
- default:
- print("devinit unknown device %D\n", d);
- return;
-
- case Devro:
- cwinit(d->ro.parent);
- break;
-
- case Devcw:
- cwinit(d);
- break;
-
- case Devjuke:
- jukeinit(d);
- break;
-
- case Devwren:
- wreninit(d);
- break;
-
- case Devide:
- ideinit(d);
- case Devworm:
- case Devlworm:
- break;
-
- case Devfworm:
- fworminit(d);
- break;
-
- case Devmcat:
- mcatinit(d);
- break;
-
- case Devmlev:
- mlevinit(d);
- break;
-
- case Devpart:
- partinit(d);
- break;
-
- case Devswab:
- d = d->swab.d;
- goto loop;
- }
-}
-
-void
-swab2(void *c)
-{
- uchar *p;
- int t;
-
- p = c;
-
- t = p[0];
- p[0] = p[1];
- p[1] = t;
-}
-
-void
-swab4(void *c)
-{
- uchar *p;
- int t;
-
- p = c;
-
- t = p[0];
- p[0] = p[3];
- p[3] = t;
-
- t = p[1];
- p[1] = p[2];
- p[2] = t;
-}
-
-/*
- * swab a block
- * flag = 0 -- convert from foreign to native
- * flag = 1 -- convert from native to foreign
- */
-void
-swab(void *c, int flag)
-{
- uchar *p;
- Tag *t;
- int i, j;
- Dentry *d;
- Cache *h;
- Bucket *b;
- Superb *s;
- Fbuf *f;
- long *l;
-
- /* swab the tag */
- p = (uchar*)c;
- t = (Tag*)(p + BUFSIZE);
- if(!flag) {
- swab2(&t->pad);
- swab2(&t->tag);
- swab4(&t->path);
- }
-
- /* swab each block type */
- switch(t->tag) {
-
- default:
- print("no swab for tag=%G rw=%d\n", t->tag, flag);
- for(j=0; j<16; j++)
- print(" %.2x", p[BUFSIZE+j]);
- print("\n");
- for(i=0; i<16; i++) {
- print("%.4x", i*16);
- for(j=0; j<16; j++)
- print(" %.2x", p[i*16+j]);
- print("\n");
- }
- break;
-
- case Tsuper:
- s = (Superb*)p;
- swab4(&s->fbuf.nfree);
- for(i=0; i<FEPERBUF; i++)
- swab4(&s->fbuf.free[i]);
- swab4(&s->fstart);
- swab4(&s->fsize);
- swab4(&s->tfree);
- swab4(&s->qidgen);
- swab4(&s->cwraddr);
- swab4(&s->roraddr);
- swab4(&s->last);
- swab4(&s->next);
- break;
-
- case Tdir:
- for(i=0; i<DIRPERBUF; i++) {
- d = (Dentry*)p + i;
- swab2(&d->uid);
- swab2(&d->gid);
- swab2(&d->mode);
- swab2(&d->wuid);
- swab4(&d->qid.path);
- swab4(&d->qid.version);
- swab4(&d->size);
- for(j=0; j<NDBLOCK; j++)
- swab4(&d->dblock[j]);
- swab4(&d->iblock);
- swab4(&d->diblock);
- swab4(&d->atime);
- swab4(&d->mtime);
- }
- break;
-
- case Tind1:
- case Tind2:
- l = (long*)p;
- for(i=0; i<INDPERBUF; i++) {
- swab4(l);
- l++;
- }
- break;
-
- case Tfree:
- f = (Fbuf*)p;
- swab4(&f->nfree);
- for(i=0; i<FEPERBUF; i++)
- swab4(&f->free[i]);
- break;
-
- case Tbuck:
- for(i=0; i<BKPERBLK; i++) {
- b = (Bucket*)p + i;
- swab4(&b->agegen);
- for(j=0; j<CEPERBK; j++) {
- swab2(&b->entry[j].age);
- swab2(&b->entry[j].state);
- swab4(&b->entry[j].waddr);
- }
- }
- break;
-
- case Tcache:
- h = (Cache*)p;
- swab4(&h->maddr);
- swab4(&h->msize);
- swab4(&h->caddr);
- swab4(&h->csize);
- swab4(&h->fsize);
- swab4(&h->wsize);
- swab4(&h->wmax);
- swab4(&h->sbaddr);
- swab4(&h->cwraddr);
- swab4(&h->roraddr);
- swab4(&h->toytime);
- swab4(&h->time);
- break;
-
- case Tnone: // unitialized
- case Tfile: // someone elses problem
- case Tvirgo: // bit map -- all bytes
- case Tconfig: // configuration string -- all bytes
- break;
- }
-
- /* swab the tag */
- if(flag) {
- swab2(&t->pad);
- swab2(&t->tag);
- swab4(&t->path);
- }
-}
//GO.SYSIN DD port/sub.c
next reply other threads:[~2001-05-16 13:02 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2001-05-16 13:02 nemo [this message]
2001-05-17 4:54 ` Eric Dorman
2001-05-16 19:31 geoff
2001-05-16 21:00 ` Francisco J Ballesteros
2001-05-16 21:13 geoff
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20010516125649.67D48199E6@mail.cse.psu.edu \
--to=nemo@gsyc.escet.urjc.es \
--cc=9fans@cse.psu.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).