~kris/9p

9hist

af5e5bd8e9d3c4dde463b256bef7e8ff900486f2 — David du Colombier 32 years ago a8e3f54
Plan 9 from Bell Labs 1994-01-28
7 files changed, 107 insertions(+), 43 deletions(-)

M pc/clock.c
M pc/devhard.c
M pc/ether2000.c
M pc/ether8003.c
M pc/ether8390.c
M pc/etherif.h
M pc/fns.h
M pc/clock.c => pc/clock.c +1 -0
@@ 54,6 54,7 @@ clock(Ureg *ur, void *arg)

	checkalarms();
	mouseclock();
	hardclock();

	/*
	 *  process time accounting

M pc/devhard.c => pc/devhard.c +56 -1
@@ 44,6 44,11 @@ enum
	Csetbuf=	0xEF,
	Cinitparam=	0x91,

	/* conner specific commands */
	Cstandby=	0xE0,
	Cidle=		0xE1,
	Cpowerdown=	0xE3,

	/* file types */
	Qdir=		0,



@@ 86,6 91,8 @@ struct Drive
	int	npart;		/* number of real partitions */
	Partition p[Npart];
	Repl	repl;
	ulong	usetime;
	int	state;

	ulong	cap;		/* total bytes */
	int	bytes;		/* bytes/sector */


@@ 94,6 101,14 @@ struct Drive
	long	cyl;		/* cylinders/drive */
};

enum
{
	Sspinning,
	Sstandby,
	Sidle,
	Spowerdown,
};

/*
 *  a controller for 2 drives
 */


@@ 120,6 135,7 @@ struct Controller

Controller	*hardc;
Drive		*hard;
static int	spindowntime;

static void	hardintr(Ureg*, void*);
static long	hardxfer(Drive*, Partition*, int, long, long, char*);


@@ 170,10 186,15 @@ hardreset(void)
	Controller *cp;
	int drive;
	uchar equip;
	char *p;

	hard = xalloc(conf.nhard * sizeof(Drive));
	hardc = xalloc(((conf.nhard+1)/2) * sizeof(Controller));
	
	p = getconf("spindowntime");
	if(p)
		spindowntime = atoi(p);
	
	/*
	 *  read nvram for number of hard drives (2 max)
	 */


@@ 418,7 439,7 @@ cmdreadywait(Controller *cp)

	start = m->ticks;
	while((inb(cp->pbase+Pstatus) & (Sready|Sbusy)) != Sready)
		if(TK2MS(m->ticks - start) > 5){
		if(TK2MS(m->ticks - start) > 10){
			DPRINT("cmdreadywait failed\n");
			error(Eio);
		}


@@ 526,6 547,8 @@ hardxfer(Drive *dp, Partition *pp, int cmd, long start, long len, char *buf)
		}
	}
	sleep(&cp->r, cmddone, cp);
	dp->state = Sspinning;
	dp->usetime = m->ticks;
	poperror();
	if(loop)
		nexterror();


@@ 1011,3 1034,35 @@ hardintr(Ureg *ur, void *arg)
		break;
	}
}

void
hardclock(void)
{
	int drive;
	Drive *dp;
	Controller *cp;
	int diff;

	if(spindowntime <= 0)
		return;

	for(drive = 0; drive < conf.nhard; drive++){
		dp = &hard[drive];
		cp = dp->cp;
		if(canqlock(cp) == 0)
			continue;

		diff = TK2SEC(m->ticks - dp->usetime);
		switch(dp->state){
		case Sspinning:
			if(diff >= spindowntime){
				cp->cmd = Cstandby;
				outb(cp->pbase+Pdh, 0x20 | (dp->drive<<4) | 0);
				outb(cp->pbase+Pcmd, cp->cmd);
				dp->state = Sstandby;
			}
			break;
		}
		qunlock(dp->cp);
	}
}

M pc/ether2000.c => pc/ether2000.c +39 -38
@@ 3,11 3,11 @@
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "../port/error.h"
#include "io.h"
#include "devtab.h"
#include "../port/error.h"
#include "../port/netif.h"

#include "ether.h"
#include "etherif.h"

/*
 * Driver written for the 'Notebook Computer Ethernet LAN Adapter',


@@ 25,10 25,12 @@ enum {
	Reset		= 0x18,		/* offset from I/O base of reset port */
};

int
ne2000reset(Ctlr *ctlr)
static int
reset(Ether *ether)
{
	ushort buf[16];
	ulong port;
	Dp8390 *dp8390;
	int i;

	/*


@@ 36,41 38,35 @@ ne2000reset(Ctlr *ctlr)
	 * Use defaults for port, irq, mem and size
	 * if not specified.
	 */
	if(ctlr->card.port == 0)
		ctlr->card.port = 0x300;
	if(ctlr->card.irq == 0)
		ctlr->card.irq = 2;
	if(ctlr->card.mem == 0)
		ctlr->card.mem = 0x4000;
	if(ctlr->card.size == 0)
		ctlr->card.size = 16*1024;
	if(ether->port == 0)
		ether->port = 0x300;
	if(ether->irq == 0)
		ether->irq = 2;
	if(ether->mem == 0)
		ether->mem = 0x4000;
	if(ether->size == 0)
		ether->size = 16*1024;
	port = ether->port;

	ctlr->card.reset = ne2000reset;
	ctlr->card.attach = dp8390attach;
	ctlr->card.mode = dp8390mode;
	ctlr->card.read = dp8390read;
	ctlr->card.write = dp8390write;
	ctlr->card.receive = dp8390receive;
	ctlr->card.transmit = dp8390transmit;
	ctlr->card.intr = dp8390intr;
	ctlr->card.watch = dp8390watch;
	ctlr->card.overflow = dp8390overflow;
	ether->private = malloc(sizeof(Dp8390));
	dp8390 = ether->private;
	dp8390->bit16 = 1;
	dp8390->ram = 0;

	ctlr->card.bit16 = 1;
	ctlr->card.dp8390 = ctlr->card.port;
	ctlr->card.data = ctlr->card.port+Data;
	dp8390->dp8390 = port;
	dp8390->data = port+Data;

	ctlr->card.tstart = HOWMANY(ctlr->card.mem, Dp8390BufSz);
	ctlr->card.pstart = ctlr->card.tstart + HOWMANY(sizeof(Etherpkt), Dp8390BufSz);
	ctlr->card.pstop = ctlr->card.tstart + HOWMANY(ctlr->card.size, Dp8390BufSz);
	dp8390->tstart = HOWMANY(ether->mem, Dp8390BufSz);
	dp8390->pstart = dp8390->tstart + HOWMANY(sizeof(Etherpkt), Dp8390BufSz);
	dp8390->pstop = dp8390->tstart + HOWMANY(ether->size, Dp8390BufSz);

	/*
	 * Reset the board. This is done by doing a read
	 * followed by a write to the Reset address.
	 */
	buf[0] = inb(ctlr->card.port+Reset);
	buf[0] = inb(port+Reset);
	delay(2);
	outb(ctlr->card.port+Reset, buf[0]);
	outb(port+Reset, buf[0]);
	
	/*
	 * Init the (possible) chip, then use the (possible)


@@ 81,20 77,25 @@ ne2000reset(Ctlr *ctlr)
	 * enough, there are other ethernet boards which could
	 * match.
	 */
	dp8390reset(ctlr);
	dp8390reset(ether);
	memset(buf, 0, sizeof(buf));
	dp8390read(ctlr, buf, 0, sizeof(buf));
	if((buf[0x0E] & 0xFF) != 0x57 || (buf[0x0F] & 0xFF) != 0x57)
	dp8390read(dp8390, buf, 0, sizeof(buf));
	if((buf[0x0E] & 0xFF) != 0x57 || (buf[0x0F] & 0xFF) != 0x57){
		free(ether->private);
		return -1;
	}

	/*
	 * Stupid machine. We asked for shorts, we got shorts,
	 * although the PROM is a byte array.
	 * Now we can set the ethernet address.
	 */
	for(i = 0; i < sizeof(ctlr->ea); i++)
		ctlr->ea[i] = buf[i];
	dp8390setea(ctlr);
	if((ether->ea[0]|ether->ea[1]|ether->ea[2]|ether->ea[3]|ether->ea[4]|ether->ea[5]) == 0){
		for(i = 0; i < sizeof(ether->ea); i++)
			ether->ea[i] = buf[i];
	}

	dp8390setea(ether);

	return 0;
}


@@ 102,5 103,5 @@ ne2000reset(Ctlr *ctlr)
void
ether2000link(void)
{
	addethercard("NE2000", ne2000reset);
	addethercard("NE2000", reset);
}

M pc/ether8003.c => pc/ether8003.c +6 -2
@@ 66,7 66,7 @@ static int
reset(Ether *ether)
{
	int i;
	uchar ic[8], sum;
	uchar ea[Eaddrlen], ic[8], sum;
	ulong port;
	Dp8390 *dp8390;



@@ 95,7 95,7 @@ reset(Ether *ether)
	port = ether->port;
	sum = 0;
	for(i = 0; i < sizeof(ether->ea); i++){
		ether->ea[i] = inb(port+Lar+i);
		ea[i] = inb(port+Lar+i);
		sum += ether->ea[i];
		ic[i] = inb(port+i);
	}


@@ 184,6 184,10 @@ reset(Ether *ether)
	 * ethernet address.
	 */
	dp8390reset(ether);
	if((ether->ea[0]|ether->ea[1]|ether->ea[2]|ether->ea[3]|ether->ea[4]|ether->ea[5]) == 0){
		for(i = 0; i < sizeof(ether->ea); i++)
			ether->ea[i] = ea[i];
	}
	dp8390setea(ether);

	return 0;

M pc/ether8390.c => pc/ether8390.c +2 -2
@@ 228,7 228,7 @@ dp8390getea(Ether *ether)
	dp8390outb(port+Cr, cr);
}

static void*
void*
dp8390read(Dp8390 *dp8390, void *to, ulong from, ulong len)
{
	ulong port = dp8390->dp8390;


@@ 279,7 279,7 @@ dp8390read(Dp8390 *dp8390, void *to, ulong from, ulong len)
	return to;
}

static void*
void*
dp8390write(Dp8390 *dp8390, ulong to, void *from, ulong len)
{
	ulong port = dp8390->dp8390;

M pc/etherif.h => pc/etherif.h +2 -0
@@ 40,6 40,8 @@ typedef struct {
extern int dp8390reset(Ether*);
extern void dp8390getea(Ether*);
extern void dp8390setea(Ether*);
extern void *dp8390read(Dp8390*, void*, ulong, ulong);
extern void *dp8390write(Dp8390*, ulong, void*, ulong);

#define NEXT(x, l)	(((x)+1)%(l))
#define	HOWMANY(x, y)	(((x)+((y)-1))/(y))

M pc/fns.h => pc/fns.h +1 -0
@@ 27,6 27,7 @@ ulong	getcr0(void);
ulong	getcr2(void);
char*	getconf(char*);
ulong	getstatus(void);
void	hardclock(void);
void	i8042a20(void);
void	i8042reset(void);
void	ident(void);