* Re: [9fans] ide fs patch for the current plan9 version
@ 2001-05-16 19:31 geoff
2001-05-16 21:00 ` Francisco J Ballesteros
0 siblings, 1 reply; 5+ messages in thread
From: geoff @ 2001-05-16 19:31 UTC (permalink / raw)
To: 9fans
> 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.
You probably ought to "mk clean" before you "mk" in
/sys/src/fs/plan9pc. We tried this sort of overlaid source tree and
found a couple of hazards: existing object (.8) files in the
underlying tree (/sys/src/fs in this case) can cause trouble if they
are unwritable (e.g., due to lack of permission) or if they are newer
than source files in the overlaying tree (./idefs in this case).
Russ and I didn't quite finish a program called stitch to perform this
sort of overlay dynamically (it worked under light load). Stitch
changed the semantics of creation slightly so that new files in the
served tree were always created in the uppermost layer, though that
could be easily adjusted. I also made a small tweak to mk to
understand enough about overlays that it would ignore targets (e.g.,
newer object files) in lower layers for the purpose of computing work
to be done.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [9fans] ide fs patch for the current plan9 version
2001-05-16 19:31 [9fans] ide fs patch for the current plan9 version geoff
@ 2001-05-16 21:00 ` Francisco J Ballesteros
0 siblings, 0 replies; 5+ messages in thread
From: Francisco J Ballesteros @ 2001-05-16 21:00 UTC (permalink / raw)
To: 9fans
geoff@collyer.net wrote:
> You probably ought to "mk clean" before you "mk" in
> /sys/src/fs/plan9pc. We tried this sort of overlaid source tree and
> found a couple of hazards: existing object (.8) files in the
> underlying tree (/sys/src/fs in this case) can cause trouble if they
> are unwritable (e.g., due to lack of permission) or if they are newer
> than source files in the overlaying tree (./idefs in this case).
>
> Russ and I didn't quite finish a program called stitch to perform this
> sort of overlay dynamically (it worked under light load). Stitch
Isn't it more simple just to keep the source directory always clean and
always overlay your one before mk'ing?
Or am I missing something?
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [9fans] ide fs patch for the current plan9 version
2001-05-16 13:02 nemo
@ 2001-05-17 4:54 ` Eric Dorman
0 siblings, 0 replies; 5+ messages in thread
From: Eric Dorman @ 2001-05-17 4:54 UTC (permalink / raw)
To: 9fans
nemo@gsyc.escet.urjc.es wrote:
> Hi,
> 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.
good deal. doesn't look like i'm going to get back
to it... Real Life(TM) intrudes...
--eld
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [9fans] ide fs patch for the current plan9 version
@ 2001-05-16 21:13 geoff
0 siblings, 0 replies; 5+ messages in thread
From: geoff @ 2001-05-16 21:13 UTC (permalink / raw)
To: 9fans
Yes, it is simpler to just keep the source tree clean, if you have
that option. My ex-department tried the experiment of overlaying the
contents of our file server, which we kept pretty lean, on top of the
main Plan 9 file server. It kept us current yet allowed us to
implement different administrative policies and in general substitute
our own files for those on the main file server. We didn't have
permission to clean the main source tree.
^ permalink raw reply [flat|nested] 5+ messages in thread
* [9fans] ide fs patch for the current plan9 version
@ 2001-05-16 13:02 nemo
2001-05-17 4:54 ` Eric Dorman
0 siblings, 1 reply; 5+ messages in thread
From: nemo @ 2001-05-16 13:02 UTC (permalink / raw)
To: 9fans
[-- 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
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2001-05-17 4:54 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-05-16 19:31 [9fans] ide fs patch for the current plan9 version geoff
2001-05-16 21:00 ` Francisco J Ballesteros
-- strict thread matches above, loose matches on Subject: below --
2001-05-16 21:13 geoff
2001-05-16 13:02 nemo
2001-05-17 4:54 ` Eric Dorman
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).