~kris/9p

9hist

dce0b3ea5e6472bf9439edd32b33623e28cf6e91 — David du Colombier 26 years ago 4efbe6d
Plan 9 from Bell Labs 2000-07-18
6 files changed, 196 insertions(+), 54 deletions(-)

M pc/ether2114x.c
M pc/sdmylex.c
M port/dev.c
M port/devsrv.c
M port/latin1.h
M port/portfns.h
M pc/ether2114x.c => pc/ether2114x.c +106 -13
@@ 19,7 19,7 @@

#include "etherif.h"

#define DEBUG		0
#define DEBUG		(1)
#define debug		if(DEBUG)print

enum {


@@ 27,6 27,8 @@ enum {
	Ntde		= 64,
};

#define Rbsz		ROUNDUP(sizeof(Etherpkt)+4, 4)

enum {					/* CRS0 - Bus Mode */
	Swr		= 0x00000001,	/* Software Reset */
	Bar		= 0x00000002,	/* Bus Arbitration */


@@ 181,12 183,20 @@ enum {					/* PHY registers */
	Aner		= 6,		/* Auto-Negotiation Expansion */
};

enum {					/* Variants */
	Tulip0		= (0x0009<<16)|0x1011,
	Tulip3		= (0x0019<<16)|0x1011,
	Pnic		= (0x0002<<16)|0x11AD,
	Pnic2		= (0xC115<<16)|0x11AD,
};

typedef struct Ctlr Ctlr;
typedef struct Ctlr {
	int	port;
	Pcidev*	pcidev;
	Ctlr*	next;
	int	active;
	int	id;			/* (pcidev->did<<16)|pcidev->vid */

	uchar	srom[128];
	uchar*	sromea;			/* MAC address */


@@ 455,7 465,7 @@ interrupt(Ureg*, void* arg)
					if(des->status & De)
						ctlr->de++;
				}
				else if(bp = iallocb(sizeof(Etherpkt)+4)){
				else if(bp = iallocb(Rbsz)){
					len = ((des->status & Fl)>>16)-4;
					des->bp->wp = des->bp->rp+len;
					etheriq(ether, des->bp, 1);


@@ 464,7 474,7 @@ interrupt(Ureg*, void* arg)
				}

				des->control &= Er;
				des->control |= ROUNDUP(sizeof(Etherpkt)+4, 4);
				des->control |= Rbsz;
				coherence();
				des->status = Own;



@@ 566,9 576,9 @@ ctlrinit(Ether* ether)
	 */
	ctlr->rdr = malloc(ctlr->nrdr*sizeof(Des));
	for(des = ctlr->rdr; des < &ctlr->rdr[ctlr->nrdr]; des++){
		des->bp = allocb(ROUNDUP(sizeof(Etherpkt)+4, 4));
		des->bp = allocb(Rbsz);
		des->status = Own;
		des->control = ROUNDUP(sizeof(Etherpkt)+4, 4);
		des->control = Rbsz;
		des->addr = PADDR(des->bp->rp);
	}
	ctlr->rdr[ctlr->nrdr-1].control |= Er;


@@ 581,7 591,12 @@ ctlrinit(Ether* ether)
	ctlr->tdri = 0;
	csr32w(ctlr, 4, PADDR(ctlr->tdr));

	/*
	 * Clear any bits in the Status Register (CSR5) as
	 * the PNIC has a different reset value from a true 2114x.
	 */
	ctlr->mask = Nis|Ais|Fbe|Rwt|Rps|Ru|Ri|Unf|Tjt|Tps|Ti;
	csr32w(ctlr, 5, ctlr->mask);
	csr32w(ctlr, 7, ctlr->mask);
	ctlr->csr6 |= St;
	csr32w(ctlr, 6, ctlr->csr6);


@@ 652,7 667,20 @@ miimdo(Ctlr* ctlr, int bits, int n)
static int
miir(Ctlr* ctlr, int phyad, int regad)
{
	int data;
	int data, i;

	if(ctlr->id == Pnic){
		i = 1000;
		csr32w(ctlr, 20, 0x60020000|(phyad<<23)|(regad<<18));
		do{
			microdelay(1);
			data = csr32r(ctlr, 20);
		}while((data & 0x80000000) && --i);

		if(i == 0)
			return -1;
		return data & 0xFFFF;
	}

	/*
	 * Preamble;


@@ 690,6 718,17 @@ sromr(Ctlr* ctlr, int r)
{
	int i, op, data;

	if(ctlr->id == Pnic){
		i = 1000;
		csr32w(ctlr, 19, 0x600|r);
		do{
			microdelay(1);
			data = csr32r(ctlr, 19);
		}while((data & 0x80000000) && --i);

		return csr32r(ctlr, 9) & 0xFFFF;
	}

	/*
	 * This sequence for reading a 16-bit register 'r'
	 * in the EEPROM is taken straight from Section


@@ 760,7 799,7 @@ type5block(Ctlr* ctlr, uchar* block)
	 * sequence.
	 */
	len = *block++;
	if(ctlr->pcidev->did == 0x0009){
	if(ctlr->id != Tulip3){
		for(i = 0; i < len; i++){
			csr32w(ctlr, 12, *block);
			block++;


@@ 1139,6 1178,30 @@ static uchar* leaf21140[] = {
	nil,
};

/*
 * Copied to ctlr->srom at offset 20.
 */
static uchar leafpnic[] = {
	0x00, 0x00, 0x00, 0x00,		/* MAC address */
	0x00, 0x00,
	0x00,				/* controller 0 device number */
	0x1E, 0x00,			/* controller 0 info leaf offset */
	0x00,				/* reserved */
	0x00, 0x08,			/* selected connection type */
	0x00,				/* general purpose control */
	0x01,				/* block count */

	0x8C,				/* format indicator and count */
	0x01,				/* block type */
	0x00,				/* PHY number */
	0x00,				/* GPR sequence length */
	0x00,				/* reset sequence length */
	0x00, 0x78,			/* media capabilities */
	0xE0, 0x01,			/* Nway advertisment */
	0x00, 0x50,			/* FDX bitmap */
	0x00, 0x18,			/* TTM bitmap */
};

static int
srom(Ctlr* ctlr)
{


@@ 1180,6 1243,19 @@ srom(Ctlr* ctlr)
	}

	/*
	 * Fake up the SROM for the PNIC.
	 * It looks like a 21140 with a PHY.
	 * The MAC address is byte-swapped in the orginal SROM data.
	 */
	if(ctlr->id == Pnic){
		memmove(&ctlr->srom[20], leafpnic, sizeof(leafpnic));
		for(i = 0; i < Eaddrlen; i += 2){
			ctlr->srom[20+i] = ctlr->srom[i+1];
			ctlr->srom[20+i+1] = ctlr->srom[i];
		}
	}

	/*
	 * Next, try to find the info leaf in the SROM for media detection.
	 * If it's a non-conforming card try to match the vendor ethernet code
	 * and point p at a fake info leaf with compact 21140 entries.


@@ 1212,7 1288,7 @@ srom(Ctlr* ctlr)
	ctlr->leaf = p;
	ctlr->sct = *p++;
	ctlr->sct |= *p++<<8;
	if(ctlr->pcidev->did == 0x0009){
	if(ctlr->id != Tulip3){
		csr32w(ctlr, 12, Gpc|*p++);
		delay(200);
	}


@@ 1227,7 1303,7 @@ srom(Ctlr* ctlr)
		 * The RAMIX PMC665 has a badly-coded SROM,
		 * hence the test for 21143 and type 3.
		 */
		if((*p & 0x80) || (ctlr->pcidev->did == 0x0019 && *(p+1) == 3)){
		if((*p & 0x80) || (ctlr->id == Tulip3 && *(p+1) == 3)){
			*p |= 0x80;
			if(*(p+1) == 1 || *(p+1) == 3)
				phy = 1;


@@ 1278,12 1354,14 @@ dec2114xpci(void)
	int x;

	p = nil;
	while(p = pcimatch(p, 0x1011, 0)){
		switch(p->did){
	while(p = pcimatch(p, 0, 0)){
		if(p->ccrb != 0x02 || p->ccru != 0)
			continue;
		switch((p->did<<16)|p->vid){
		default:
			continue;

		case 0x0019:		/* 21143 */
		case Tulip3:			/* 21143 */
			/*
			 * Exit sleep mode.
			 */


@@ 1292,7 1370,9 @@ dec2114xpci(void)
			pcicfgw32(p, 0x40, x);
			/*FALLTHROUGH*/

		case 0x0009:		/* 21140 */
		case Pnic:			/* PNIC */
		case Pnic2:			/* PNIC-II */
		case Tulip0:			/* 21140 */
			break;
		}



@@ 1303,6 1383,7 @@ dec2114xpci(void)
		ctlr = malloc(sizeof(Ctlr));
		ctlr->port = p->mem[0].bar & ~0x01;
		ctlr->pcidev = p;
		ctlr->id = (p->did<<16)|p->vid;

		if(ioalloc(ctlr->port, p->mem[0].size, 0, "dec2114x") < 0){
			print("dec2114x: port 0x%uX in use\n", ctlr->port);


@@ 1323,6 1404,18 @@ dec2114xpci(void)
			break;
		}

		switch(ctlr->id){
		default:
			break;

		case Pnic:			/* PNIC */
			/*
			 * Turn off the jabber timer.
			 */
			csr32w(ctlr, 15, 0x00000001);
			break;
		}

		if(ctlrhead != nil)
			ctlrtail->next = ctlr;
		else

M pc/sdmylex.c => pc/sdmylex.c +63 -26
@@ 4,7 4,6 @@
 * 24-bit mode works for Adaptec AHA-154xx series too.
 *
 * To do:
 *	tidy the PCI probe and do EISA;
 *	allocate more Ccb's as needed, up to NMbox-1;
 *	add nmbox and nccb to Ctlr struct for the above;
 *	64-bit LUN/explicit wide support necessary?


@@ 54,7 53,7 @@ enum {					/* Rstatus */
enum {					/* Rcpr */
	Cinitialise	= 0x01,		/* Initialise Mailbox */
	Cstart		= 0x02,		/* Start Mailbox Command */
	Cinquiry	= 0x04,		/* Adapter Anquiry */
	Cinquiry	= 0x04,		/* Adapter Inquiry */
	Ceombri		= 0x05,		/* Enable OMBR Interrupt */
	Cinquire	= 0x0B,		/* Inquire Configuration */
	Cextbios	= 0x28,		/* AHA-1542: extended BIOS info. */


@@ 224,7 223,7 @@ enum {
	NCcb		= NMbox-1,	/* number of Ccb's */
};

#define PADDR24(a, n)	(PADDR(a)+n <= (1<<24))
#define PADDR24(a, n)	((PADDR(a)+(n)) <= (1<<24))

static void
ccbfree(Ctlr* ctlr, Ccb* ccb)


@@ 253,7 252,7 @@ ccballoc(Ctlr* ctlr)

	for(;;){
		lock(&ctlr->ccblock);
		if(ccb = ctlr->ccb){
		if((ccb = ctlr->ccb) != nil){
			if(ctlr->bus == 24)
				 ctlr->ccb = ((Ccb24*)ccb)->ccb;
			else


@@ 303,7 302,7 @@ mylex24rio(SDreq* r)
	 * from the last completed Ccb, return it immediately.
	 */
	lock(&ctlr->cachelock);
	if(ccb = ctlr->cache[target]){
	if((ccb = ctlr->cache[target]) != nil){
		ctlr->cache[target] = nil;
		if(r->cmd[0] == 0x03
		&& ccb->sdstat == SDcheck && lun == ((ccb->cs[1]>>5) & 0x07)){


@@ 410,9 409,21 @@ mylex24rio(SDreq* r)
	 */
	while(waserror())
		;
	sleep(ccb, done24, ccb);
	tsleep(ccb, done24, ccb, 30*1000);
	poperror();

	if(!done24(ccb)){
		print("%s: %d/%d: sd24rio timeout\n",
			ctlr->sdev->name, target, r->lun);
		if(ccb->data != nil){
			free(data);
			ccb->data = nil;
		}
		ccbfree(ctlr, (Ccb*)ccb);

		return SDtimeout;
	}

	/*
	 * Save the status and patch up the number of
	 * bytes actually transferred.


@@ 434,7 445,7 @@ mylex24rio(SDreq* r)
	/*
	 * Tidy things up if a staging area was used for the data,
	 */
	if(ccb->data){
	if(ccb->data != nil){
		if(sdstat == SDok && btstat == 0 && !r->write)
			memmove(ccb->data, data, n);
		free(data);


@@ 545,10 556,10 @@ mylex32rio(SDreq* r)
	 * from the last completed Ccb, return it immediately.
	 */
	lock(&ctlr->cachelock);
	if(ccb = ctlr->cache[target]){
	if((ccb = ctlr->cache[target]) != nil){
		ctlr->cache[target] = nil;
		if(r->cmd[0] == 0x03
		  && ccb->sdstat == SDcheck && lun == (ccb->luntag & 0x07)){
		&& ccb->sdstat == SDcheck && lun == (ccb->luntag & 0x07)){
			unlock(&ctlr->cachelock);
			if(r->dlen){
				n = 8+ccb->sense[7];


@@ 572,11 583,11 @@ mylex32rio(SDreq* r)

	n = r->dlen;
	if(n == 0)
		ccb->datadir |= CCBdataout|CCBdatain;
		ccb->datadir = CCBdataout|CCBdatain;
	else if(!r->write)
		ccb->datadir |= CCBdatain;
		ccb->datadir = CCBdatain;
	else
		ccb->datadir |= CCBdataout;
		ccb->datadir = CCBdataout;

	ccb->cdblen = r->clen;



@@ 631,9 642,17 @@ mylex32rio(SDreq* r)
	 */
	while(waserror())
		;
	sleep(ccb, done32, ccb);
	tsleep(ccb, done32, ccb, 30*1000);
	poperror();

	if(!done32(ccb)){
		print("%s: %d/%d: sd32rio timeout\n",
			ctlr->sdev->name, target, r->lun);
		ccbfree(ctlr, (Ccb*)ccb);

		return SDtimeout;
	}

	/*
	 * Save the status and patch up the number of
	 * bytes actually transferred.


@@ 972,6 991,8 @@ buggery:
			outb(0x0A, 0x00);
			break;
		default:
			if(ctlr->bus == 24)
				goto buggery;
			break;
		}
	


@@ 1021,7 1042,8 @@ mylexpnp(void)
{
	Pcidev *p;
	Ctlr *ctlr;
	int cfg, i, x;
	ISAConf isa;
	int cfg, ctlrno, i, x;
	SDev *sdev, *head, *tail;

	p = nil;


@@ 1040,17 1062,33 @@ mylexpnp(void)
		tail = sdev;
	}

	if(strncmp(KADDR(0xFFFD9), "EISA", 4))
		return head;
	for(cfg = 0x1000; cfg < MaxEISA*0x1000; cfg += 0x1000){
		x = 0;
		for(i = 0; i < 4; i++)
			x |= inb(cfg+CfgEISA+i)<<(i*8);
		if(x != 0x0142B30A && x != 0x0242B30A)
			continue;
	if(strncmp(KADDR(0xFFFD9), "EISA", 4) == 0){
		for(cfg = 0x1000; cfg < MaxEISA*0x1000; cfg += 0x1000){
			x = 0;
			for(i = 0; i < 4; i++)
				x |= inb(cfg+CfgEISA+i)<<(i*8);
			if(x != 0x0142B30A && x != 0x0242B30A)
				continue;
	
			x = inb(cfg+0xC8C);
			if((sdev = mylexprobe(mylexport[x & 0x07], -1)) == nil)
				continue;
	
			if(head != nil)
				tail->next = sdev;
			else
				head = sdev;
			tail = sdev;
		}
	}

		x = inb(cfg+0xC8C);
		if((sdev = mylexprobe(mylexport[x & 0x07], -1)) == nil)
	for(ctlrno = 0; ctlrno < 4; ctlrno++){
		memset(&isa, 0, sizeof(isa));
		if(!isaconfig("scsi", ctlrno, &isa))
			continue;
		if(strcmp(isa.type, "aha1542"))
			continue;
		if((sdev = mylexprobe(isa.port, -1)) == nil)
			continue;

		if(head != nil)


@@ 1104,9 1142,8 @@ mylex24enable(Ctlr* ctlr)
	cmd[2] = p>>16;
	cmd[3] = p>>8;
	cmd[4] = p;
	len = 5;

	return issue(ctlr, cmd, len, 0, 0);
	return issue(ctlr, cmd, 5, 0, 0);
}

static int

M port/dev.c => port/dev.c +24 -14
@@ 209,13 209,33 @@ devdirread(Chan *c, char *d, long n, Dirtab *tab, int ntab, Devgen *gen)
	return m;
}

/*
 * error(Eperm) if open permission not granted for up->user.
 */
void
devpermcheck(char *fileuid, ulong perm, int omode)
{
	ulong t;
	static int access[] = { 0400, 0200, 0600, 0100 };

	if(strcmp(up->user, fileuid) == 0)
		perm <<= 0;
	else
	if(strcmp(up->user, eve) == 0)
		perm <<= 3;
	else
		perm <<= 6;

	t = access[omode&3];
	if((t&perm) != t)
		error(Eperm);
}

Chan*
devopen(Chan *c, int omode, Dirtab *tab, int ntab, Devgen *gen)
{
	int i;
	Dir dir;
	ulong t, mode;
	static int access[] = { 0400, 0200, 0600, 0100 };

	for(i=0;; i++) {
		switch((*gen)(c, tab, ntab, i, &dir)){


@@ 225,18 245,8 @@ devopen(Chan *c, int omode, Dirtab *tab, int ntab, Devgen *gen)
			break;
		case 1:
			if(c->qid.path == dir.qid.path) {
				if(strcmp(up->user, dir.uid) == 0)
					mode = dir.mode;
				else
				if(strcmp(up->user, eve) == 0)
					mode = dir.mode<<3;
				else
					mode = dir.mode<<6;

				t = access[omode&3];
				if((t & mode) == t)
					goto Return;
				error(Eperm);
				devpermcheck(dir.uid, dir.mode, omode);
				goto Return;
			}
			break;
		}

M port/devsrv.c => port/devsrv.c +1 -0
@@ 122,6 122,7 @@ srvopen(Chan *c, int omode)
		error("srv file already exists");
	if(openmode(omode)!=sp->chan->mode && sp->chan->mode!=ORDWR)
		error(Eperm);
	devpermcheck(sp->owner, sp->perm, omode);

	cclose(c);
	incref(sp->chan);

M port/latin1.h => port/latin1.h +1 -1
@@ 61,7 61,7 @@
	"T", "-u",	L"Ŧ⊨",
	"V", "=",	L"⇐",
	"Y", "R",	L"Ʀ",
	"Z", "-Z",	L"Ƶℤ",
	"Z", "-ACSZ",	L"Ƶℤ",
	"^", "ACEGHIJOSUWYaceghijosuwy",	L"ÂĈÊĜĤÎĴÔŜÛŴŶâĉêĝĥîĵôŝûŵŷ",
	"_\"", "AUau",	L"ǞǕǟǖ",
	"_,", "Oo",	L"Ǭǭ",

M port/portfns.h => port/portfns.h +1 -0
@@ 74,6 74,7 @@ Devgen		devgen;
void		devinit(void);
int		devno(int, int);
Chan*		devopen(Chan*, int, Dirtab*, int, Devgen*);
void		devpermcheck(char*, ulong, int);
void		devremove(Chan*);
void		devreset(void);
void		devstat(Chan*, char*, Dirtab*, int, Devgen*);