~kris/9p

9hist

29767900ef1d5be30d064af05dbb8397679a498f — David du Colombier 31 years ago cc1412a
Plan 9 from Bell Labs 1995-03-29
9 files changed, 110 insertions(+), 44 deletions(-)

M pc/devi82365.c
M pc/main.c
M pc/scsi.c
M pc/trap.c
M port/devns16552.c
M port/devsd.c
M port/portfns.h
M port/proc.c
M port/sysproc.c
M pc/devi82365.c => pc/devi82365.c +56 -31
@@ 41,6 41,9 @@ enum
	Rwe= 		0x6,		/* address window enable */
	 Fmem16=	 (1<<5),	/*  use A23-A12 to decode address */
	Rio= 		0x7,		/* I/O control */
	 Fwidth16=	 (1<<0),	/*  16 bit data width */
	 Fiocs16=	 (1<<1),	/*  IOCS16 determines data width */
	 Ftiming=	 (1<<3),	/*  timing register to use */
	Riobtm0lo=	0x8,		/* I/O address 0 start low byte */
	Riobtm0hi=	0x9,		/* I/O address 0 start high byte */
	Riotop0lo=	0xa,		/* I/O address 0 stop low byte */


@@ 126,6 129,7 @@ struct Conftab
	int	index;
	ushort	irqs;		/* legal irqs */
	ushort	port;		/* port address */
	uchar	irqtype;
	uchar	nioregs;	/* number of io registers */
	uchar	bit16;		/* true for 16 bit access */
	uchar	vpp1;


@@ 239,11 243,17 @@ slotena(Slot *pp)
	if(pp->enabled)
		return;

	/* power up and reset, wait's are empirical (???) */
	/* power up and unreset, wait's are empirical (???) */
	wrreg(pp, Rpc, Fautopower|Foutena|Fcardena);
	delay(300);
	wrreg(pp, Rigc, Fnotreset);
	delay(500);

	wrreg(pp, Rpc, 0);
	delay(500);

	wrreg(pp, Rpc, Fautopower|Foutena|Fcardena);
	delay(300);
	wrreg(pp, Rigc, 0);
	delay(100);
	wrreg(pp, Rigc, Fnotreset);
	delay(500);



@@ 253,7 263,7 @@ slotena(Slot *pp)
		cisread(pp);
		pp->enabled = 1;
	} else
		wrreg(pp, Rpc, Fautopower);
		wrreg(pp, Rpc, 0);
}

/*


@@ 262,8 272,8 @@ slotena(Slot *pp)
static void
slotdis(Slot *pp)
{
	wrreg(pp, Rpc, Fautopower);		/* turn off card */
	wrreg(pp, Rwe, 0);			/* no windows */
	wrreg(pp, Rwe, 0);		/* no windows */
	wrreg(pp, Rpc, 0);		/* turn off card power */
	pp->enabled = 0;
}



@@ 606,10 616,7 @@ i82365reset(void)
			pp->memlen = 64*MB;
			pp->base = (cp->dev<<7) | (j<<6);
			pp->cp = cp;
if(pp == slot)i82365dump(pp);
/*
			slotdis(pp);
*/

			/* interrupt on status change */
			wrreg(pp, Rcscic, ((PCMCIAvec-Int0vec)<<4) | Fchangeena);


@@ 796,6 803,16 @@ i82365read(Chan *c, void *a, long n, ulong offset)
		if(pp->busy)
			cp += sprint(cp, "busy\n");
		cp += sprint(cp, "battery lvl %d\n", pp->battery);
{
	int i;

	for(i = 0; i < 0x40; i++){
		if((i&0x7) == 0)
			cp += sprint(cp, "\n%ux:	", i);
		cp += sprint(cp, "%ux ", rdreg(pp, i));
	}
	cp += sprint(cp, "\n");
}
		*cp = 0;
		return readstr(offset, a, n, buf);
	default:


@@ 915,13 932,16 @@ pcmio(int slotno, ISAConf *isa)
		isa->irq = 9;
	wrreg(pp, Rigc, isa->irq | Fnotreset | Fiocard);
	
	/* set power and enable slotnoice */
	/* set power and enable device */
	x = vcode(ct->vpp1);
	wrreg(pp, Rpc, x|Fautopower|Foutena|Fcardena);

	/* 16-bit data path */
	if(ct->bit16)
		wrreg(pp, Rio, (1<<0)|(1<<1));
		x = Fiocs16|Fwidth16;
	else
		x = 0;
	wrreg(pp, Rio, Ftiming|x);

	/* enable io port map 0 */
	if(isa->port == 0)


@@ 929,8 949,8 @@ pcmio(int slotno, ISAConf *isa)
	we = rdreg(pp, Rwe);
	wrreg(pp, Riobtm0lo, isa->port);
	wrreg(pp, Riobtm0hi, isa->port>>8);
	wrreg(pp, Riotop0lo, (isa->port+ct->nioregs));
	wrreg(pp, Riotop0hi, (isa->port+ct->nioregs)>>8);
	wrreg(pp, Riotop0lo, (isa->port+ct->nioregs-1));
	wrreg(pp, Riotop0hi, (isa->port+ct->nioregs-1)>>8);
	wrreg(pp, Rwe, we | (1<<6));

	/* only touch Rconfig if it is present */


@@ 938,21 958,14 @@ pcmio(int slotno, ISAConf *isa)
		/*  Reset adapter */
		m = pcmmap(slotno, pp->caddr + Rconfig, 1, 1);
		p = (uchar*)(KZERO|(m->isa + pp->caddr + Rconfig - m->ca));
if(strstr(pp->verstr, "KeepInTouch") == 0){
		*p = Creset;
		delay(5);
		*p = 0;
		delay(5);
}

		/* set configuration */
if(strstr(pp->verstr, "KeepInTouch") == 0){
		if(isa->irq > 7)
			*p = Clevel | ct->index;
		else
			*p = ct->index;
		/* set configuration and interrupt type */
		x = ct->index;
		if((ct->irqtype & 0x20) && ((ct->irqtype & 0x40)==0 || isa->irq>7))
			x |= Clevel;
		*p = x|ct->index;
		delay(5);
} else i82365dump(pp);

		pcmunmap(slotno, m);
	}
	return 0;


@@ 1066,15 1079,26 @@ microvolt(Slot *pp)
{
	uchar c;
	ulong microvolts;
	ulong exp;

	if(readc(pp, &c) != 1)
		return 0;
	microvolts = vexp[c&0x7]*vmant[(c>>3)&0xf];
	exp = vexp[c&0x7];
	microvolts = vmant[(c>>3)&0xf]*exp;
	while(c & 0x80){
		if(readc(pp, &c) != 1)
			return 0;
		if(c == 0x7d || c == 0x7e || c == 0x7f)
			microvolts = 0;
		switch(c){
		case 0x7d:
			break;		/* high impedence when sleeping */
		case 0x7e:
		case 0x7f:
			microvolts = 0;	/* no connection */
			break;
		default:
			exp /= 10;
			microvolts += exp*(c&0x7f);
		}
	}
	return microvolts;
}


@@ 1121,7 1145,7 @@ power(Slot *pp)
		nanoamps(pp);
	if(feature & 0x20)
		nanoamps(pp);
	if(feature & 0x20)
	if(feature & 0x40)
		nanoamps(pp);
	return mv/1000000;
}


@@ 1195,6 1219,7 @@ irq(Slot *pp, Conftab *ct)

	if(readc(pp, &c) != 1)
		return;
	ct->irqtype = c & 0xe0;
	if(c & 0x10)
		ct->irqs = getlong(pp, 2);
	else


@@ 1271,7 1296,7 @@ tentry(Slot *pp, int ttype)
		iospaces(pp, ct);
	if(feature&0x10)
		irq(pp, ct);
	switch(feature&0x3){
	switch((feature>>5)&0x3){
	case 1:
		memspace(pp, 0, 2, 0);
		break;

M pc/main.c => pc/main.c +1 -1
@@ 59,8 59,8 @@ main(void)
	kbdinit();
	procinit0();
	initseg();
	links();
	printcpufreq();
	links();
	chandevreset();
	swapinit();
	userinit();

M pc/scsi.c => pc/scsi.c +22 -6
@@ 12,8 12,14 @@ enum {
	Ninq		= 255,
	Nscratch	= 255,

	CMDtest		= 0x00,
	CMDreqsense	= 0x03,
	CMDread6	= 0x08,
	CMDwrite6	= 0x0A,
	CMDinquire	= 0x12,
	CMDstart	= 0x1B,
	CMDread10	= 0x28,
	CMDwrite10	= 0x2A,
};

typedef struct {


@@ 142,14 148,12 @@ scsiprobe(Ctlr *ctlr)
		}

		/*
		 * Inquire to find out what the device is
		 * Inquire to find out what the device is.
		 * Drivers then use the result to attach to targets
		 */
		memset(t->inq, 0, Ninq);
		cmd[0] = CMDinquire;
		cmd[4] = Ninq;
		nbytes = Ninq;
		s = scsiexec(t, SCSIread, cmd, sizeof(cmd), t->inq, &nbytes);
		s = scsiinquiry(t, 0, t->inq, &nbytes);
		if(s < 0) {
			print("scsi%d: unit %d inquire failed, status %d\n", t->ctlrno, i, s);
			continue;


@@ 196,7 200,7 @@ scsiinv(int devno, int type, Target **rt, uchar **inq, char *id)

		t = &scsi[ctlr]->target[unit];
		devno++;
		if(t->ok && (t->inq[0]&0x0F) == type){
		if(t->ok && (t->inq[0]&0x1F) == type){
			*rt = t;
			*inq = t->inq;
			sprint(id, "scsi%d: unit %d", ctlr, unit);


@@ 212,13 216,25 @@ scsistart(Target *t, char lun, int s)
	uchar cmd[6];

	memset(cmd, 0, sizeof cmd);
	cmd[0] = 0x1b;
	cmd[0] = CMDstart;
	cmd[1] = lun<<5;
	cmd[4] = s ? 1 : 0;
	return scsiexec(t, SCSIread, cmd, sizeof(cmd), 0, 0);
}

int
scsiinquiry(Target *t, char lun, void *data, int *datalen)
{
	uchar cmd[6];

	memset(cmd, 0, sizeof cmd);
	cmd[0] = CMDinquire;
	cmd[1] = lun<<5;
	cmd[4] = *datalen;
	return scsiexec(t, SCSIread, cmd, sizeof(cmd), data, datalen);
}

int
scsicap(Target *t, char lun, ulong *size, ulong *bsize)
{
	int s, nbytes;

M pc/trap.c => pc/trap.c +1 -1
@@ 199,7 199,7 @@ trapinit(void)
	/*
	 *  Set up the second 8259 interrupt processor.
	 *  Make 8259 interrupts start at CPU vector Int1vec.
	 *  Set the 8259 as master with level triggered
	 *  Set the 8259 as master with edge triggered
	 *  input with fully nested interrupts.
	 */
	outb(Int1ctl, (1<<4)|(1<<3)|(1<<0));	/* ICW1 - master, level triggered,

M port/devns16552.c => port/devns16552.c +9 -2
@@ 414,7 414,8 @@ ns16552kick(Uart *p)
	x = splhi();
	lock(&p->plock);
	if(p->printing == 0 || (uartrdreg(p, Lstat) & Outready))
	if(p->cts && p->blocked == 0){
	if(p->cts && p->blocked == 0)
	if(p->op < p->oe || stageoutput(p)){
		n = 0;
		while((uartrdreg(p, Lstat) & Outready) == 0){
			if(++n > 100000){


@@ 423,9 424,9 @@ ns16552kick(Uart *p)
			}
		}
		do{
			outb(p->port + Data, *(p->op++));
			if(p->op >= p->oe && stageoutput(p) == 0)
				break;
			outb(p->port + Data, *(p->op++));
		}while(uartrdreg(p, Lstat) & Outready);
	}
	unlock(&p->plock);


@@ 813,6 814,12 @@ uartstatus(Chan *c, Uart *p, void *buf, long n, long offset)
		strcat(str, " dtr");
	if(tstat & Rts)
		strcat(str, " rts");
{
int i, j;

i = strlen(str);
for(j = 0; j < 8; j++) i+=sprint(str+i, " %ux", uartrdreg(p, j));
}
	strcat(str, "\n");
	return readstr(offset, buf, n, str);
}

M port/devsd.c => port/devsd.c +13 -1
@@ 87,7 87,8 @@ sdinit(void)
{
	Disk *d;
	ulong s, b;
	int dev, i;
	uchar inq[255];
	int dev, i, nbytes;

	dev = 0;
	for(;;) {


@@ 102,8 103,19 @@ sdinit(void)
		/* Search for other lun's */
		for(i = 0; i < Nlun; i++) {
			d->lun = i;

			scsireqsense(d->t, d->lun, 1);

			/*
			 * A SCSI target does not support a lun if the
			 * the peripheral device type and qualifier fields
			 * in the response to an inquiry command are 0x7F.
			 */
			memset(inq, 0, sizeof(inq));
			nbytes = sizeof(inq);
			if(scsiinquiry(d->t, d->lun, inq, &nbytes) != STok || inq[0] == 0x7F)
				continue;

			/* NCR Raid only seems to answer second capacity
			 * command if lun != 0
			 */

M port/portfns.h => port/portfns.h +1 -0
@@ 239,6 239,7 @@ int		scsibio(Target*, char, int, void*, long, long, long);
int		scsicap(Target*, char, ulong*, ulong*);
int		scsiexec(Target*, int, uchar*, int, void*, int*);
#define		scsifree(p)	free(p)
int		scsiinquiry(Target*, char, void*, int*);
int		scsiinv(int, int, Target**, uchar**, char*);
int		scsireqsense(Target*, char, int);
int		scsistart(Target*, char, int);

M port/proc.c => port/proc.c +1 -0
@@ 666,6 666,7 @@ pexit(char *exitstr, int freemem)
		if(exitstr && exitstr[0]){
			n = sprint(wq->w.msg, "%s %d:", up->text, up->pid);
			strncpy(wq->w.msg+n, exitstr, ERRLEN-n);
			wq->w.msg[ERRLEN-1] = 0;
		}
		else
			wq->w.msg[0] = '\0';

M port/sysproc.c => port/sysproc.c +6 -2
@@ 486,6 486,7 @@ sysexits(ulong *arg)
{
	char *status;
	char *inval = "invalid exit string";
	char buf[ERRLEN];

	status = (char*)arg[0];
	if(status){


@@ 493,8 494,11 @@ sysexits(ulong *arg)
			status = inval;
		else{
			validaddr((ulong)status, 1, 0);
			if(vmemchr(status, 0, ERRLEN) == 0)
				status = inval;
			if(vmemchr(status, 0, ERRLEN) == 0){
				memmove(buf, status, ERRLEN);
				buf[ERRLEN-1] = 0;
				status = buf;
			}
		}
		poperror();