Plan 9 from Bell Labs’s /usr/web/sources/extra/9hist/power/devhs.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


## diffname power/devhs.c 1990/0227
## diff -e /dev/null /n/bootesdump/1990/0227/sys/src/9/mips/devhsvme.c
0a
#include	"u.h"
#include	"lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"errno.h"
#include	"devtab.h"

#include	"io.h"

enum {
	Maxtxburst=	1024,		/* maximum transmit burst size */
	Vmevec=		0xd0,		/* vme vector for interrupts */
	Intlevel=	5,		/* level to interrupt on */
};

struct hsvmestats {
	ulong	parity;
	ulong	rintr;
	ulong	tintr;
} hsvmestats;

#define ALIVE		0x0001
#define IENABLE		0x0004
#define EXOFLOW		0x0008
#define IRQ		0x0010
#define EMUTE		0x0020
#define EPARITY		0x0040
#define EFRAME		0x0080
#define EROFLOW		0x0100
#define REF		0x0800
#define XFF		0x4000
#define XHF		0x8000

#define FORCEW		0x0008
#define IPL(x)		((x)<<5)
#define NORESET		0xFF00
#define RESET		0x0000

#define CTL		0x0100
#define CHNO		0x0200
#define TXEOD		0x0400
#define NND		0x8000

Rendez hsvmer;

#define DELAY(n)	{ \
	register int N = 12*(n); \
	while (--N > 0); \
	}

static void hsvmeintr(int);

void
hsvmerestart(struct hsvme *addr)
{
	addr->csr = RESET;
	wbflush();
	DELAY(20000);

	/*
	 *  set interrupt vector
	 *  turn on addrice
	 *  set forcew to a known value
	 *  interrupt on level `Intlevel'
	 */
	addr->vector = 0xd0;
	addr->csr = NORESET|IPL(Intlevel)|IENABLE|ALIVE;
	wbflush();
	DELAY(500);
	addr->csr = NORESET|IPL(Intlevel)|FORCEW|IENABLE|ALIVE;
	wbflush();
	DELAY(500);
}

void
hsvmereset(void)
{
	struct hsvme *addr;

	addr = HSVME;
	addr->csr = RESET;
	wbflush();
	DELAY(20000);

	/*
	 *  routine to call on interrupt
	 */
	setvmevec(Vmevec, hsvmeintr);
}

void
hsvmeinit(void)
{
}

/*
 *  enable the device for interrupts
 */
static int
never(void *arg)
{
	return 0;
}
Chan*
hsvmeattach(char *spec)
{
	struct hsvme *addr;

	addr = HSVME;
	hsvmerestart(addr);
	print("hsvme csr %ux\n", addr->csr);

	return devattach('h', spec);
}

Chan*
hsvmeclone(Chan *c, Chan *nc)
{
	return devclone(c, nc);
}

int	 
hsvmewalk(Chan *c, char *name)
{
	if(c->qid != CHDIR)
		return 0;
	if(strcmp(name, "hsvme") == 0){
		c->qid = 1;
		return 1;
	}
	return 0;
}

void	 
hsvmestat(Chan *c, char *dp)
{
	print("hsvmestat\n");
	error(0, Egreg);
}

Chan*
hsvmeopen(Chan *c, int omode)
{
	c->mode = openmode(omode);
	c->flag |= COPEN;
	c->offset = 0;
	return c;
}

void	 
hsvmecreate(Chan *c, char *name, int omode, ulong perm)
{
	error(0, Eperm);
}

void	 
hsvmeclose(Chan *c)
{
}

long	 
hsvmeread(Chan *c, void *buf, long n)
{
	error(0, Egreg);
	return 0;
}

long	 
hsvmewrite(Chan *c, void *buf, long n)
{
	error(0, Egreg);
	return 0;
}

void	 
hsvmeremove(Chan *c)
{
	error(0, Eperm);
}

void	 
hsvmewstat(Chan *c, char *dp)
{
	error(0, Eperm);
}

void
hsvmeuserstr(Error *e, char *buf)
{
	consuserstr(e, buf);
}

void	 
hsvmeerrstr(Error *e, char *buf)
{
	rooterrstr(e, buf);
}

static void
hsvmeintr(int vec)
{
	ushort csr;
	struct hsvme *addr;

	print("hsvme intr\n");
	addr = HSVME;
	wbflush();
	csr = addr->csr;
	do {
		if (addr->csr & REF) {
			hsvmestats.rintr++;
			print("hsvme rintr\n");
		}
		if (addr->csr & XHF) {
			hsvmestats.tintr++;
			print("hsvme tintr\n");
		}
		if ((csr^XFF) & (XFF|EROFLOW|EFRAME|EPARITY|EXOFLOW)) {
			hsvmestats.parity++;
			hsvmerestart(addr);
			print("hsvme %ux: reset, csr = 0x%x\n",
				HSVME, csr);
		}
		wbflush();
	} while ((csr = addr->csr) & REF);
}
.
## diffname power/devhs.c 1990/0312
## diff -e /n/bootesdump/1990/0227/sys/src/9/mips/devhsvme.c /n/bootesdump/1990/0312/sys/src/9/mips/devhsvme.c
225,226c
		if(bp->rptr >= bp->wptr){
			if(bp->flags & S_DELIM){
				freeb(bp);
				break;
			}
			freeb(bp);
			bp = getq(q);
		}
	}

	/*
	 *  send the control byte if there is one
	 */
	if(ctl){
/*		print("->%.2uo\n", CTL|ctl); /**/
		addr->data = CTL|ctl;
	}

	/*
	 *  start the fifo emptying
	 */
/*	print("->%.2uo\n", TXEOD); /**/
	addr->data = TXEOD;

	qunlock(&hp->xmit);
}

/*
 *  return true if the input fifo is non-empty
 */
static int
notempty(void *arg)
{
	Device *addr;

	addr = (Device *)arg;
	return addr->csr & REF;
}

/*
 *  fill a block with what is currently buffered and send it upstream
 */
static void
upstream(Hsvme *hp, unsigned int ctl)
{
	int n;
	Block *bp;

	n = hp->wptr - hp->buf;
	bp = allocb(3 + n);
	bp->wptr[0] = hp->chan;
	bp->wptr[1] = hp->chan>>8;
	bp->wptr[2] = ctl;
	if(n)
		memcpy(&bp->wptr[3], hp->buf, n);
	bp->wptr += 3 + n;
	bp->flags |= S_DELIM;
	PUTNEXT(hp->rq, bp);
	hp->wptr = hp->buf;
}

/*
 *  Read bytes from the input fifo.  Since we take an interrupt every
 *  time the fifo goes non-empty, we need to waste time to let the
 *  fifo fill up.
 */
static void
hsvmekproc(void *arg)
{
	Hsvme *hp;
	Device *addr;
	unsigned int c;

	hp = (Hsvme *)arg;
	addr = hp->addr;
	hp->kstarted = 1;
	hp->wptr = hp->buf;

	for(;;){
		/*
		 *  die if the device is closed
		 */
		qlock(hp);
		if(hp->rq == 0){
			qunlock(hp);
			hp->kstarted = 0;
			wakeup(&hp->r);
			return;
		}

		/*
		 *  let the fifo fill a bit
		 */
		delay(1);

		/*
		 *  0xFFFF means an empty fifo
		 */
		while ((c = addr->data) != 0xFFFF) {
/*			print(" %.2uo<-\n", c); /**/
			if(c & CHNO){
				c &= 0x1FF;
				if(hp->chan == c)
					continue;
				/*
				 *  new channel, put anything saved upstream
				 */
				if(hp->wptr - hp->buf != 0)
					upstream(hp, 0);
				hp->chan = c;
			} else if(c & NND){
				/*
				 *  ctl byte, this ends a message
				 */
				upstream(hp, c);
			} else {
				/*
				 *  data byte, put in local buffer
				 */
				*hp->wptr++ = c;
				if(hp->wptr == &hp->buf[sizeof hp->buf])
					upstream(hp, 0);
			}
		}
		qunlock(hp);

		/*
		 *  sleep if input fifo empty
		 */
		if(!notempty(addr))
			sleep(&hp->kr, notempty, addr);
	}
}

/*
 *  only one flavor interrupt.   we have to use the less than half full
 *  and not empty bits to figure out whom to wake.
 */
static void
hsvmeintr(int vec)
{
	ushort csr;
	Device *addr;
	Hsvme *hp;

	hp = &hsvme[vec - Vmevec];
	if(hp < hsvme || hp > &hsvme[Nhsvme]){
		print("bad hsvme vec\n");
		return;
	}
	csr = hp->addr->csr;

	if (csr & REF) {
		hp->rintr++;
		wakeup(&hp->kr);
	}
	if (csr & XHF) {
		hp->tintr++;
		wakeup(&hp->r);
	}
	if ((csr^XFF) & (XFF|EROFLOW|EFRAME|EPARITY|EXOFLOW)) {
		hp->parity++;
		hsvmerestart(hp);
		print("hsvme %d: reset, csr = 0x%ux\n",
			HSVME, csr);
	}
.
219,223c
		n = bp->wptr - bp->rptr;
		if(n > burst)
			n = burst;
		burst -= n;
		while(n--){
/*			print("->%.2uo\n", *bp->rptr); /**/
			addr->data = *bp->rptr++;
.
215,217c
		freeb(bp);
	}
}

/*
 *  return true if the output fifo is at least half empty.
 *  the implication is that it can take at least another 1000 byte burst.
 */
static int
halfempty(void *arg)
{
	Device *addr;

	addr = (Device*)arg;
	return addr->csr & XHF;
}

/*
 *  output a block
 *
 *  the first 2 bytes of every message are the channel number,
 *  low order byte first.  the third is a possible trailing control
 *  character.
 */
void
hsvmeoput(Queue *q, Block *bp)
{
	Device *addr;
	Hsvme *hp;
	int burst;
	int chan;
	int ctl;
	int n;

	if(bp->type != M_DATA){
		freeb(bp);
		return;
	}

	/*
	 *  get a whole message before handing bytes to the device
	 */
	if(!putq(q, bp))
		return;

	/*
	 *  one transmitter at a time
	 */
	hp = (Hsvme *)q->ptr;
	qlock(&hp->xmit);
	addr = hp->addr;

	/*
	 *  parse message
	 */
	bp = getq(q);
	if(bp->wptr - bp->rptr < 3){
		freemsg(q, bp);
		qunlock(&hp->xmit);
		return;
	}
	chan = CHNO | *bp->rptr++ | (*bp->rptr++<<8);
	ctl = *bp->rptr++;

	/*
	 *  send the 8 bit data, burst are up to Maxburst (9-bit) bytes long
	 */
	if(!(addr->csr & XHF))
		sleep(&hp->r, halfempty, addr);
/*	print("->%.2uo\n", CHNO|chan);/**/
	addr->data = CHNO|chan;
	burst = Maxburst;
	while(bp){
		if(burst == 0){
			addr->data = TXEOD;
/*			print("->%.2uo\n", TXEOD); /**/
			if(!(addr->csr & XHF))
				sleep(&hp->r, halfempty, addr);
/*			print("->%.2uo\n", CHNO|chan); /**/
			addr->data = CHNO|chan;
			burst = Maxburst;
.
206,213c
	hp = &hsvme[s->dev];
	sprint(name, "**hsvme%d**", s->dev);
	q->ptr = q->other->ptr = hp;
	hp->rq = q;
	kproc(name, hsvmekproc, hp);
}

/*
 *  kill off the kernel process
 */
static int
kdead(void *arg)
{
	Hsvme *hp;

	hp = (Hsvme *)arg;
	return hp->kstarted == 0;
}
static void
hsvmestclose(Queue * q)
{
	Hsvme *hp;

	hp = (Hsvme *)q->ptr;
	qlock(hp);
	hp->rq = 0;
	qunlock(hp);
	wakeup(&hp->kr);
	sleep(&hp->r, kdead, hp);
}

/*
 *  free all blocks of a message in `q', `bp' is the first block
 *  of the message
 */
static void
freemsg(Queue *q, Block *bp)
{
	for(; bp; bp = getq(q)){
		if(bp->flags & S_DELIM){
			freeb(bp);
			return;
.
203,204c
	Hsvme *hp;
	char name[32];
.
201c
hsvmestopen(Queue *q, Stream *s)
.
199a
/*
 *	the stream routines
 */

/*
 *  create the kernel process for input
 */
.
172,173c
	return streamwrite(c, buf, n, 0);
.
165,166c
	return streamread(c, buf, n);
.
159a
	if(c->qid != CHDIR)
		streamclose(c);
.
144a
	if(c->qid == CHDIR){
		if(omode != OREAD)
			error(0, Eperm);
	}else
		streamopen(c, &hsvmeinfo);
.
138,139c
	devstat(c, dp, 0, 0, streamgen);
.
126,132c
	return devwalk(c, name, 0, 0, streamgen);
.
114c
	c = devattach('h', spec);
	c->dev = i;
	c->qid = CHDIR;
	return c;
.
110,112c
	i = strtoul(spec, 0, 0);
	if(i >= Nhsvme)
		error(0, Ebadarg);
	hp = &hsvme[i];
	hsvmerestart(hp);
	print("hsvme [%d] csr %ux\n", i, hp->addr->csr);
.
108c
	Hsvme *hp;
	int i;
	Chan *c;
.
100,104d
98c
 *  enable the device for interrupts, spec is the device number
.
84,89c
	delay(20);
.
81,82c
	for(i=0; i<Nhsvme; i++){
		hsvme[i].addr = HSVME+i;
		hsvme[i].vec = Vmevec+i;
		hsvme[i].addr->csr = RESET;
		setvmevec(hsvme[i].vec, hsvmeintr);
	}	
.
79c
	int i;
	Hsvme *hp;
.
75a
/*
 *  reset all vme boards
 */
.
73c
	delay(1);
.
70c
	delay(1);
.
67c
	addr->vector = hp->vec;
.
59c
	delay(20);
.
56a
	Device *addr;

	addr = hp->addr;

.
55c
hsvmerestart(Hsvme *hp)
.
53a
/*
 *  hsvme stream module definition
 */
static void hsvmeoput(Queue*, Block*);
static void hsvmestopen(Queue*, Stream*);
static void hsvmestclose(Queue*);
Qinfo hsvmeinfo = { nullput, hsvmeoput, hsvmestopen, hsvmestclose, "hsvme" };

/*
 *  restart a VME board
 */
.
52a
static void hsvmekproc(void*);
.
45,51d
22a
struct Hsvme {
	QLock;

	QLock	xmit;
	Device	*addr;
	int	vec;		/* interupt vector */
	Rendez	r;		/* output process */
	Rendez	kr;		/* input kernel process */
	int	chan;		/* current input channel */
	Queue	*rq;		/* read queue */
	uchar	buf[1024];	/* bytes being collected */
	uchar	*wptr;		/* pointer into buf */
	int	kstarted;	/* true if kernel process started */

	/* statistics */

	ulong	parity;		/* parity errors */
	ulong	rintr;		/* rcv interrupts */
	ulong	tintr;		/* transmit interrupts */
	ulong	in;		/* bytes in */
	ulong	out;		/* bytes out */
};

Hsvme hsvme[Nhsvme];

.
17,21c
/*
 *  hsvme datakit board
 */
struct Device {
	ushort	version;
	ushort	pad0x02;
	ushort	vector;
	ushort	pad0x06;
	ushort	csr;
	ushort	pad0x0A;
	ushort	data;
};
#define HSVME		VMEA24SUP(Device, 0xF90000)
.
14a
	Nhsvme=		1,
.
12c
	Maxburst=	1023,		/* maximum transmit burst size */
.
10a
typedef struct Hsvme	Hsvme;
typedef struct Device	Device;

.
## diffname power/devhs.c 1990/0315
## diff -e /n/bootesdump/1990/0312/sys/src/9/mips/devhsvme.c /n/bootesdump/1990/0315/sys/src/9/mips/devhsvme.c
367,368c
	chan = CHNO | bp->rptr[0] | (bp->rptr[1]<<8);
	ctl = bp->rptr[2];
	bp->rptr += 3;
.
## diffname power/devhs.c 1990/0403
## diff -e /n/bootesdump/1990/0315/sys/src/9/mips/devhsvme.c /n/bootesdump/1990/0403/sys/src/9/mips/devhsvme.c
519a
		}
.
496c
			miss = 0;
.
490,491c
		for(miss = 0; miss < 10; miss++){
.
488c
		 *  if we loop many times without finding a character, sleep
.
468a
	int miss;
.
161d
## diffname power/devhs.c 1990/0722
## diff -e /n/bootesdump/1990/0403/sys/src/9/mips/devhsvme.c /n/bootesdump/1990/0722/sys/src/9/mips/devhsvme.c
263c
	sprint(name, "hsvme%d", s->dev);
.
## diffname power/devhs.c 1990/0816
## diff -e /n/bootesdump/1990/0722/sys/src/9/mips/devhsvme.c /n/bootesdump/1990/0816/sys/src/9/mips/devhsvme.c
519d
488,491d
## diffname power/devhs.c 1990/0826
## diff -e /n/bootesdump/1990/0816/sys/src/9/mips/devhsvme.c /n/bootesdump/1990/0826/sys/src/9/mips/devhsvme.c
490a
			hp->in++;
.
## diffname power/devhs.c 1990/0930
## diff -e /n/bootesdump/1990/0826/sys/src/9/mips/devhsvme.c /n/bootesdump/1990/0930/sys/src/9/mips/devhsvme.c
557c
			vec - Vmevec, csr);
.
## diffname power/devhs.c 1990/1101
## diff -e /n/bootesdump/1990/0930/sys/src/9/mips/devhsvme.c /n/bootesdump/1990/1101/sys/src/9/mips/devhsvme.c
517a
		locked = 0;
.
479a
		locked = 1;
.
474a
	locked = 0;
	if(waserror()){
		if(locked)
			qunlock(hp);
		hp->kstarted = 0;
		wakeup(&hp->r);
		return;
	}

.
468a
	int locked;
.
## diffname power/devhs.c 1990/11151
## diff -e /n/bootesdump/1990/1101/sys/src/9/mips/devhsvme.c /n/bootesdump/1990/11151/sys/src/9/mips/devhsvme.c
91c
Qinfo hsvmeinfo =
{
	nullput,
	hsvmeoput,
	hsvmestopen,
	hsvmestclose,
	"hsvme"
};
.
## diffname power/devhs.c 1990/11211
## diff -e /n/bootesdump/1990/11151/sys/src/9/mips/devhsvme.c /n/bootesdump/1990/11211/sys/src/9/mips/devhsvme.c
241,253c
	error(Eperm);
.
235c
	error(Eperm);
.
216c
	if(c->qid.path != CHDIR)
.
210c
	error(Eperm);
.
198c
			error(Eperm);
.
196c
	if(c->qid.path == CHDIR){
.
171c
	c->qid.path = CHDIR;
.
165c
		error(Ebadarg);
.
## diffname power/devhs.c 1990/1214
## diff -e /n/bootesdump/1990/11211/sys/src/9/mips/devhsvme.c /n/bootesdump/1990/1214/sys/src/9/mips/devhsvme.c
522a
		USED(locked);
.
498d
489a
			poperror();
.
483a
		USED(locked);		/* so locked = 0 and locked = 1 stay */
.
463d
## diffname power/devhs.c 1991/0318
## diff -e /n/bootesdump/1991/0201/sys/src/9/mips/devhsvme.c /n/bootesdump/1991/0318/sys/src/9/power/devhsvme.c
445c
		memmove(&bp->wptr[3], hp->buf, n);
.
## diffname power/devhs.c 1991/0411
## diff -e /n/bootesdump/1991/0318/sys/src/9/power/devhsvme.c /n/bootesdump/1991/0411/sys/src/9/power/devhsvme.c
227c
hsvmewrite(Chan *c, void *buf, long n, ulong offset)
.
221c
hsvmeread(Chan *c, void *buf, long n, ulong offset)
.
## diffname power/devhs.c 1991/0419
## diff -e /n/bootesdump/1991/0411/sys/src/9/power/devhsvme.c /n/bootesdump/1991/0419/sys/src/9/power/devhsvme.c
186a
Chan*
hsvmeclwalk(Chan *c, char *name)
{
	return devclwalk(c, name);
}

.
## diffname power/devhs.c 1991/0427
## diff -e /n/bootesdump/1991/0419/sys/src/9/power/devhsvme.c /n/bootesdump/1991/0427/sys/src/9/power/devhsvme.c
187,192d
## diffname power/devhs.c 1991/0921
## diff -e /n/bootesdump/1991/0427/sys/src/9/power/devhsvme.c /n/bootesdump/1991/0921/sys/src/9/power/devhsvme.c
167c
	if(!hp->started)
		hsvmerestart(hp);
.
126a
	hp->started = 1;
.
47a
	int	started;
.
## diffname power/devhs.c 1991/1214
## diff -e /n/bootesdump/1991/0921/sys/src/9/power/devhsvme.c /n/bootesdump/1991/1214/sys/src/9/power/devhsvme.c
243a
	USED(c);
.
237a
	USED(c);
.
212a
	USED(c);
.
## diffname power/devhs.c 1992/0111
## diff -e /n/bootesdump/1991/1214/sys/src/9/power/devhsvme.c /n/bootesdump/1992/0111/sys/src/9/power/devhsvme.c
6c
#include	"../port/error.h"
.
## diffname power/devhs.c 1992/0117
## diff -e /n/bootesdump/1992/0111/sys/src/9/power/devhsvme.c /n/bootesdump/1992/0117/sys/src/9/power/devhsvme.c
421a
	poperror();
.
354a
	if(waserror()){
		qunlock(&hp->xmit);
		nexterror();
	}
.
## diffname power/devhs.c 1992/0123
## diff -e /n/bootesdump/1992/0117/sys/src/9/power/devhsvme.c /n/bootesdump/1992/0123/sys/src/9/power/devhsvme.c
541,542c
		if(!(addr->csr & REF)){
			if(hp->wptr == hp->buf)
				sleep(&hp->kr, notempty, addr);
			else
				tsleep(&hp->kr, notempty, addr, 100);
		}
.
539c
		 *  Sleep if input fifo empty. Make sure we don't hold onto
		 *  any byte for more tha 1/10 second.
.
533a
		if(hp->time && NOW >= hp->time)
			upstream(hp, 0);
.
528a
				if(hp->time == 0)
					hp->time = NOW + 100;
.
460a
	hp->time = 0;
.
46a
	ulong	time;		/* time byte in buf[0] arrived */
.
20a
#define NOW (MACHP(0)->ticks*MS2HZ)

.
## diffname power/devhs.c 1992/0321
## diff -e /n/bootesdump/1992/0123/sys/src/9/power/devhsvme.c /n/bootesdump/1992/0321/sys/src/9/power/devhsvme.c
2c
#include	"../port/lib.h"
.
## diffname power/devhs.c 1992/0612
## diff -e /n/bootesdump/1992/0612/sys/src/9/power/devhsvme.c /n/bootesdump/1992/0612/sys/src/9/power/devhs.c
587,589c
		hsrestart(hp);
		print("hs %d: reset, csr = 0x%ux\n",
			vec - Intvec, csr);
.
585c
	if((csr^XFF) & (XFF|EROFLOW|EFRAME|EPARITY|EXOFLOW)){
.
581c
	if(csr & XHF){
.
577c
	if(csr & REF){
.
570,572c
	hp = &hs[vec - Intvec];
	if(hp < hs || hp > &hs[Nhs]){
		print("bad hs vec\n");
.
567,568c
	HSdev *addr;
	Hs *hp;
.
564c
hsintr(int vec)
.
512c
		while((c = addr->data) != 0xFFFF){
.
480c
	hp = (Hs *)arg;
.
475,476c
	Hs *hp;
	HSdev *addr;
.
473c
hskproc(void *arg)
.
448c
upstream(Hs *hp, unsigned int ctl)
.
440c
	addr = (HSdev *)arg;
.
438c
	HSdev *addr;
.
371a
		poperror();
.
362d
357c
	hp = (Hs *)q->ptr;
	qlock(&hp->xmit);
.
336,337c
	HSdev *addr;
	Hs *hp;
.
334c
hsoput(Queue *q, Block *bp)
.
322c
	addr = (HSdev*)arg;
.
320c
	HSdev *addr;
.
293,294c
	while(waserror())
		;
	while(hp->kstarted){
		wakeup(&hp->kr);
		sleep(&hp->r, kdead, hp);
	}
	poperror();
.
289c
	hp = (Hs *)q->ptr;
.
287c
	Hs *hp;
.
285c
hsstclose(Queue * q)
.
281c
	hp = (Hs *)arg;
.
279c
	Hs *hp;
.
274c
 *  ask kproc to die and wait till it happens
.
270c
	kproc(name, hskproc, hp);
.
266,267c
	hp = &hs[s->dev];
	sprint(name, "hs%d", s->dev);
.
263c
	Hs *hp;
.
261c
hsstopen(Queue *q, Stream *s)
.
247c
hswstat(Chan *c, char *dp)
.
240c
hsremove(Chan *c)
.
234c
hswrite(Chan *c, void *buf, long n, ulong offset)
.
228c
hsread(Chan *c, void *buf, long n, ulong offset)
.
221c
hsclose(Chan *c)
.
214c
hscreate(Chan *c, char *name, int omode, ulong perm)
.
206c
		streamopen(c, &hsinfo);
.
200c
hsopen(Chan *c, int omode)
.
194c
hsstat(Chan *c, char *dp)
.
188c
hswalk(Chan *c, char *name)
.
182c
hsclone(Chan *c, Chan *nc)
.
173c
		hsrestart(hp);
.
171c
	hp = &hs[i];
.
169c
	if(i >= Nhs)
.
164c
	Hs *hp;
.
162c
hsattach(char *spec)
.
154c
hsinit(void)
.
143,147c
	for(i=0; i<Nhs; i++){
		hp = &hs[i];
		hp->addr = HSDEV+i;
		hp->vec = Intvec+i;
		hp->addr->csr = RESET;
		setvmevec(hp->vec, hsintr);
.
141c
	Hs *hp;
.
138c
hsreset(void)
.
120c
	 *  turn on device
.
110c
	HSdev *addr;
.
108c
hsrestart(Hs *hp)
.
104,106d
98,101c
	hsoput,
	hsstopen,
	hsstclose,
	"hs"
.
92,95c
static void hsoput(Queue*, Block*);
static void hsstopen(Queue*, Stream*);
static void hsstclose(Queue*);
Qinfo hsinfo =
.
90c
 *  hs stream module definition
.
76,88d
64,74c
static void hsintr(int);
static void hskproc(void*);
.
62c
Hs hs[Nhs];
.
41c
	HSdev	*addr;
.
37c
#define NOW (MACHP(0)->ticks*MS2HZ)
#define IPL(x)		((x)<<5)

struct Hs {
.
35d
23,33c
	/*
	 * csr reset flags
	 */
	FORCEW		= 0x0008,
	NORESET		= 0xFF00,
	RESET		= 0x0000,

	/*
	 * data flags
	 */
	CTL		= 0x0100,
	CHNO		= 0x0200,
	TXEOD		= 0x0400,
	NND		= 0x8000,
.
21c
	/*
	 * csr flags
	 */
	ALIVE		= 0x0001,
	IENABLE		= 0x0004,
	EXOFLOW		= 0x0008,
	IRQ		= 0x0010,
	EMUTE		= 0x0020,
	EPARITY		= 0x0040,
	EFRAME		= 0x0080,
	EROFLOW		= 0x0100,
	REF		= 0x0800,
	XFF		= 0x4000,
	XHF		= 0x8000,
.
18,19c
	Nhs=		1,
.
16c
	Intvec=		0xd0,		/* vme vector for interrupts */
.
11,12c
typedef struct Hs	Hs;
.
## diffname power/devhs.c 1992/0623
## diff -e /n/bootesdump/1992/0612/sys/src/9/power/devhs.c /n/bootesdump/1992/0623/sys/src/9/power/devhs.c
366,371d
343a
	if(BLEN(bp) < 3){
		bp = pullup(bp, 3);
		if(bp == 0){
			print("hsoput pullup failed\n");
			return;
		}
	}
.
## diffname power/devhs.c 1992/0703
## diff -e /n/bootesdump/1992/0623/sys/src/9/power/devhs.c /n/bootesdump/1992/0703/sys/src/9/power/devhs.c
551c
				tsleep(&hp->kr, notempty, addr, 2000);
.
547c
		 *  any byte for more than 1/10 second.
.
## diffname power/devhs.c 1992/0711
## diff -e /n/bootesdump/1992/0703/sys/src/9/power/devhs.c /n/bootesdump/1992/0711/sys/src/9/power/devhs.c
566d
241a
	USED(dp);
.
227a
	USED(offset);
.
221a
	USED(offset);
.
208a
	USED(name);
	USED(omode);
	USED(perm);
.
## diffname power/devhs.c 1993/0806 # deleted
## diff -e /n/bootesdump/1992/0711/sys/src/9/power/devhs.c /n/fornaxdump/1993/0806/sys/src/brazil/power/devhs.c
1,595d

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.