9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
From: nemo@gsyc.escet.urjc.es
To: 9fans@cse.psu.edu
Subject: [9fans] ide fs patch for the current plan9 version
Date: Wed, 16 May 2001 15:02:52 +0200	[thread overview]
Message-ID: <20010516125649.67D48199E6@mail.cse.psu.edu> (raw)

[-- Attachment #1: Type: text/plain, Size: 1121 bytes --]

Hi,

this is just edorman's  patch for the fs kernel to let it work
with ide disks. Unlike the original patch as posted in 9fans,
this one can be `applied'  to the   current fs
kernel source. There is almost no change actually.


I don't know if the patch might break the fs code for regular scsi disks,
since it is `removing' some code which seems to be working on a scsi-based
fs. I couldn't try because I don't have scsi disks around. 

In any case,  I'm using the current fs code w/ this patch applied and it
seems to work ok. 
My configuration string (if I remember well) is ch0fh2. The
block size is 16K, but you may change the define for RBUFSIZE in
plan9pc/dat.h.

I'll try to keep the patch up-to-date wrt the distributed fs code
until the day when the new integrated fs code be done and released.

To apply the patch, I suggest you create two directories
./idefs/port and ./idefs/plan9pc, then run rc idefs.rc on ./idefs and
bind -bc ./idefs/port /sys/src/fs/port 
bind -bc ./idefs/plan9pc /sys/src/fs/plan9pc

after that you can mk in /sys/src/fs/plan9pc.  

hope this helps




[-- Attachment #2: Type: message/rfc822, Size: 105984 bytes --]


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

             reply	other threads:[~2001-05-16 13:02 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-05-16 13:02 nemo [this message]
2001-05-17  4:54 ` Eric Dorman
2001-05-16 19:31 geoff
2001-05-16 21:00 ` Francisco J Ballesteros
2001-05-16 21:13 geoff

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20010516125649.67D48199E6@mail.cse.psu.edu \
    --to=nemo@gsyc.escet.urjc.es \
    --cc=9fans@cse.psu.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).