plan 9 kernel history: overview | file list | diff list

1991/0306/power/devhotrod.c (diff list | history)

1991/0304/sys/src/9/power/devhotrod.c:10,411991/0306/sys/src/9/power/devhotrod.c:10,37 (short | long | prev | next)
1990/1013    
#include	"io.h" 
1991/0215    
#include	"hrod.h" 
1990/1013    
 
1991/0306    
/* 
 * If defined, causes memory test to be run at device open 
 */ 
#ifdef	ENABMEMTEST 
1991/0303    
void	mem(Hot*, ulong*, ulong); 
1991/0306    
#endif 
1991/0303    
 
/* 
 * If set, causes data transfers to have checksums 
 */ 
1991/0304    
#define	ENABCKSUM	0 
1991/0306    
#define	ENABCKSUM	1 
1991/0303    
 
1990/1013    
typedef struct Hotrod	Hotrod; 
1991/0209    
typedef struct HotQ	HotQ; 
1990/1013    
 
enum { 
1991/0306    
enum{ 
1990/1013    
	Vmevec=		0xd2,		/* vme vector for interrupts */ 
	Intlevel=	5,		/* level to interrupt on */ 
1991/0209    
	Qdir=		0,		/* Qid's */ 
	Qhotrod=	1, 
1991/0215    
	NhotQ=		NRQ,		/* size of communication queues */ 
1991/0209    
	Nhotrod=	1, 
1990/1013    
}; 
 
1991/0209    
struct HotQ{ 
	ulong	i;			/* index into queue */ 
	Hotmsg	*msg[NhotQ];		/* pointer to command buffer */ 
	ulong	pad[3];			/* unused; for hotrod prints */ 
}; 
1990/1013    
                 
1991/0209    
                 
struct Hotrod{ 
	QLock; 
1991/0212    
	QLock		buflock; 
1991/0304/sys/src/9/power/devhotrod.c:42,521991/0306/sys/src/9/power/devhotrod.c:38,46
1991/0209    
	Lock		busy; 
1991/0215    
	Hot		*addr;		/* address of the device */ 
1990/1106    
	int		vec;		/* vme interrupt vector */ 
1991/0209    
	HotQ		*wq;		/* write this queue to send cmds */ 
	int		wi;		/* where to write next cmd */ 
	HotQ		rq;		/* read this queue to receive replies */ 
1991/0306    
	ulong		rq[NRQ];	/* read this queue to receive replies */ 
1991/0209    
	int		ri;		/* where to read next response */ 
1990/1106    
	Rendez		r; 
1991/0220    
	uchar		buf[MAXFDATA+MAXMSG]; 
1990/1013    
}; 
 
1991/0304/sys/src/9/power/devhotrod.c:74,831991/0306/sys/src/9/power/devhotrod.c:68,77
1991/0304    
	long l; 
 
1991/0220    
/* print("hotsend send %d %d %lux %lux\n", h->wi, m->cmd, m, m->param[0]); /**/ 
1991/0304    
	mp = &h->wq->msg[h->wi]; 
1991/0306    
	mp = (Hotmsg**)&h->addr->hostrq[h->wi]; 
1991/0304    
	*mp = (Hotmsg*)MP2VME(m); 
1991/0209    
	h->wi++; 
	if(h->wi >= NhotQ) 
1991/0306    
	if(h->wi >= NRQ) 
1991/0209    
		h->wi = 0; 
1991/0304    
	l = 0; 
	while(*mp){ 
1991/0304/sys/src/9/power/devhotrod.c:103,1091991/0306/sys/src/9/power/devhotrod.c:97,102
1991/0209    
		/* 
		 * Write queue is at end of hotrod memory 
		 */ 
1991/0215    
		hp->wq = (HotQ*)(&hp->addr->hostrp); 
1991/0209    
		hp->vec = Vmevec+i; 
		setvmevec(hp->vec, hotrodintr); 
1990/1013    
	}	 
1991/0304/sys/src/9/power/devhotrod.c:181,1881991/0306/sys/src/9/power/devhotrod.c:174,181
1991/0209    
		/* 
		 * Clear communications region 
		 */ 
		memset(hp->wq->msg, 0, sizeof(hp->wq->msg)); 
		hp->wq->i = 0; 
1991/0306    
		memset(hp->addr->hostrq, 0, NRQ*sizeof(ulong)); 
		hp->addr->hostrp = 0; 
1991/0209    
 
		/* 
		 * Issue reset 
1991/0304/sys/src/9/power/devhotrod.c:191,2031991/0306/sys/src/9/power/devhotrod.c:184,196
1991/0209    
		hp->ri = 0; 
1991/0212    
		mp = &u->khot; 
		mp->cmd = RESET; 
		mp->param[0] = MP2VME(&hp->rq); 
		mp->param[1] = NhotQ; 
1991/0306    
		mp->param[0] = MP2VME(hp->rq); 
		mp->param[1] = NRQ; 
1991/0209    
		hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot); 
1991/0215    
		delay(100); 
1991/0214    
		print("reset\n"); 
1991/0219    
 
1991/0302    
#ifdef asdf 
1991/0306    
#ifdef ENABMEMTEST 
1991/0219    
		/* 
		 * Issue test 
		 */ 
1991/0304/sys/src/9/power/devhotrod.c:253,2581991/0306/sys/src/9/power/devhotrod.c:246,257
1991/0303    
	return sum; 
} 
 
1991/0306    
int 
hotmsgintr(Hotmsg *hm) 
{ 
	return hm->intr; 
} 
 
1990/1013    
/* 
1991/0212    
 * Read and write use physical addresses if they can, which they usually can. 
 * Most I/O is from devmnt, which has local buffers.  Therefore just check 
1991/0304/sys/src/9/power/devhotrod.c:264,2701991/0306/sys/src/9/power/devhotrod.c:263,269
1990/1013    
{ 
	Hotrod *hp; 
1991/0212    
	Hotmsg *mp; 
1991/0303    
	ulong l, m; 
1991/0306    
	ulong l, m, isflush; 
1990/1013    
 
	hp = &hotrod[c->dev]; 
1991/0212    
	switch(c->qid.path){ 
1991/0304/sys/src/9/power/devhotrod.c:277,2831991/0306/sys/src/9/power/devhotrod.c:276,287
1991/0212    
			/* 
			 *  use supplied buffer, no need to lock for reply 
			 */ 
			mp = &u->khot; 
1991/0306    
			isflush = 0; 
			mp = &((User*)(u->p->upage->pa|KZERO))->khot; 
			if(mp->abort){	/* use reserved flush msg */ 
				mp = &((User*)(u->p->upage->pa|KZERO))->fhot; 
				isflush = 1; 
			} 
1991/0303    
			mp->param[2] = 0;	/* checksum */ 
			mp->param[3] = 0;	/* reply count */ 
1991/0212    
			qlock(hp); 
1991/0304/sys/src/9/power/devhotrod.c:284,2951991/0306/sys/src/9/power/devhotrod.c:288,310
1991/0212    
			mp->cmd = READ; 
			mp->param[0] = MP2VME(buf); 
			mp->param[1] = n; 
			hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot); 
1991/0306    
			mp->abort = isflush; 
			mp->intr = 0; 
			hotsend(hp, mp); 
1991/0212    
			qunlock(hp); 
1991/0220    
			l = 100*1000*1000; 
1991/0212    
			do 
1991/0306    
			if(isflush){		/* busy loop */ 
				l = 100*1000*1000; 
				do 
					m = mp->param[3]; 
				while(m==0 && --l>0); 
			}else{ 
				if(waserror()){ 
					mp->abort = 1; 
					nexterror(); 
				} 
				sleep(&mp->r, hotmsgintr, mp); 
1991/0303    
				m = mp->param[3]; 
			while(m==0 && --l>0); 
1991/0306    
			} 
1991/0303    
			if(m==0 || m>n){ 
				print("devhotrod: count %ld %ld\n", m, n); 
1991/0215    
				error(Egreg); 
1991/0304/sys/src/9/power/devhotrod.c:299,3091991/0306/sys/src/9/power/devhotrod.c:314,326
1991/0303    
					hotsum(buf, n, 1), mp->param[2]); 
				error(Eio); 
			} 
1991/0306    
			if(!isflush) 
				poperror(); 
1991/0212    
		}else{ 
			/* 
1991/0215    
			 *  use hotrod buffer.  lock the buffer until the reply 
1991/0306    
			 * use hotrod buffer. lock the buffer until the reply 
1991/0212    
			 */ 
			mp = &u->uhot; 
1991/0306    
			mp = &((User*)(u->p->upage->pa|KZERO))->uhot; 
1991/0303    
			mp->param[2] = 0;	/* checksum */ 
			mp->param[3] = 0;	/* reply count */ 
1991/0212    
			qlock(&hp->buflock); 
1991/0304/sys/src/9/power/devhotrod.c:311,3171991/0306/sys/src/9/power/devhotrod.c:328,336
1991/0212    
			mp->cmd = READ; 
			mp->param[0] = MP2VME(hp->buf); 
			mp->param[1] = n; 
			hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->uhot); 
1991/0306    
			mp->abort = 1; 
			mp->intr = 0; 
			hotsend(hp, mp); 
1991/0212    
			qunlock(hp); 
1991/0215    
			l = 100*1000*1000; 
1991/0212    
			do 
1991/0304/sys/src/9/power/devhotrod.c:338,3461991/0306/sys/src/9/power/devhotrod.c:357,362
1991/0212    
	return 0; 
1990/1013    
} 
 
/* 
 *  write hotrod memory 
 */ 
long	  
hotrodwrite(Chan *c, void *buf, long n) 
{ 
1991/0304/sys/src/9/power/devhotrod.c:356,3761991/0306/sys/src/9/power/devhotrod.c:372,394
1991/0220    
		} 
1991/0212    
		if((((ulong)buf)&(KSEGM|3)) == KSEG0){ 
			/* 
			 *  use supplied buffer, no need to lock for reply 
1991/0306    
			 * use supplied buffer, no need to lock for reply 
1991/0212    
			 */ 
			mp = &u->khot; 
1991/0306    
			mp = &((User*)(u->p->upage->pa|KZERO))->khot; 
			if(mp->abort)	/* use reserved flush msg */ 
				mp = &((User*)(u->p->upage->pa|KZERO))->fhot; 
1991/0212    
			qlock(hp); 
			mp->cmd = WRITE; 
			mp->param[0] = MP2VME(buf); 
			mp->param[1] = n; 
1991/0303    
			mp->param[2] = hotsum(buf, n, ENABCKSUM); 
1991/0212    
			hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot); 
1991/0306    
			hotsend(hp, mp); 
1991/0212    
			qunlock(hp); 
		}else{ 
			/* 
1991/0304    
			 *  use hotrod buffer.  lock the buffer until the reply 
1991/0306    
			 * use hotrod buffer.  lock the buffer until the reply 
1991/0212    
			 */ 
			mp = &u->uhot; 
1991/0306    
			mp = &((User*)(u->p->upage->pa|KZERO))->uhot; 
1991/0212    
			qlock(&hp->buflock); 
			qlock(hp); 
			memcpy(hp->buf, buf, n); 
1991/0304/sys/src/9/power/devhotrod.c:378,3841991/0306/sys/src/9/power/devhotrod.c:396,402
1991/0212    
			mp->param[0] = MP2VME(hp->buf); 
			mp->param[1] = n; 
1991/0303    
			mp->param[2] = hotsum((ulong*)hp->buf, n, ENABCKSUM); 
1991/0212    
			hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->uhot); 
1991/0306    
			hotsend(hp, mp); 
1991/0212    
			qunlock(hp); 
			qunlock(&hp->buflock); 
		} 
1991/0304/sys/src/9/power/devhotrod.c:404,4201991/0306/sys/src/9/power/devhotrod.c:422,448
1990/1106    
void 
1990/1013    
hotrodintr(int vec) 
{ 
	Hotrod *hp; 
1991/0306    
	Hotrod *h; 
	Hotmsg *hm; 
1990/1013    
 
1991/0220    
/*	print("hotrod%d interrupt\n", vec - Vmevec); /**/ 
1990/1013    
	hp = &hotrod[vec - Vmevec]; 
	if(hp < hotrod || hp > &hotrod[Nhotrod]){ 
1991/0306    
	h = &hotrod[vec - Vmevec]; 
	if(h < hotrod || h > &hotrod[Nhotrod]){ 
1990/1013    
		print("bad hotrod vec\n"); 
		return; 
	} 
1991/0219    
	hp->addr->lcsr3 &= ~INT_VME; 
1991/0306    
	h->addr->lcsr3 &= ~INT_VME; 
	hm = (Hotmsg*)VME2MP(h->rq[h->ri]); 
	h->rq[h->ri] = 0; 
	h->ri++; 
	if(h->ri >= NRQ) 
		h->ri = 0; 
	hm->intr = 1; 
	if(hm->abort) 
		return; 
	wakeup(&hm->r); 
1991/0303    
} 
 
1991/0306    
#ifdef	ENABMEMTEST 
1991/0303    
void 
mem(Hot *hot, ulong *buf, ulong size) 
{ 
1991/0304/sys/src/9/power/devhotrod.c:504,5061991/0306/sys/src/9/power/devhotrod.c:532,535
1991/0303    
		} 
	} 
1990/1013    
} 
1991/0306    
#endif 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)