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

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

1991/0209/sys/src/9/power/devhotrod.c:5,101991/0212/sys/src/9/power/devhotrod.c:5,11 (short | long | prev | next)
1990/1013    
#include	"fns.h" 
#include	"errno.h" 
#include	"devtab.h" 
1991/0212    
#include	"fcall.h" 
1990/1013    
 
#include	"io.h" 
 
1991/0209/sys/src/9/power/devhotrod.c:42,471991/0212/sys/src/9/power/devhotrod.c:43,49
1991/0209    
 
struct Hotrod{ 
	QLock; 
1991/0212    
	QLock		buflock; 
1991/0209    
	Lock		busy; 
1990/1106    
	Device		*addr;		/* address of the device */ 
	int		vec;		/* vme interrupt vector */ 
1991/0209/sys/src/9/power/devhotrod.c:50,551991/0212/sys/src/9/power/devhotrod.c:52,58
1991/0209    
	HotQ		rq;		/* read this queue to receive replies */ 
	int		ri;		/* where to read next response */ 
1990/1106    
	Rendez		r; 
1991/0212    
	uchar		buf[MAXFDATA+100]; 
1990/1013    
}; 
 
Hotrod hotrod[Nhotrod]; 
1991/0209/sys/src/9/power/devhotrod.c:62,671991/0212/sys/src/9/power/devhotrod.c:65,72
1991/0209    
enum{ 
	RESET=	0,	/* params: Q address, length of queue */ 
	REBOOT=	1,	/* params: none */ 
1991/0212    
	READ=	2,	/* params: buffer, count, returned count */ 
	WRITE=	3,	/* params: buffer, count */ 
1991/0209    
}; 
 
void 
1991/0209/sys/src/9/power/devhotrod.c:68,741991/0212/sys/src/9/power/devhotrod.c:73,79
1991/0209    
hotsend(Hotrod *h, Hotmsg *m) 
1990/1013    
{ 
1991/0209    
print("hotsend send %d %lux %lux\n", m->cmd, m, m->param[0]); 
	h->wq->msg[h->wi] = m; 
1991/0212    
	h->wq->msg[h->wi] = (Hotmsg*)MP2VME(m); 
1991/0209    
	while(h->wq->msg[h->wi]) 
		; 
print("hotsend done\n"); 
1991/0209/sys/src/9/power/devhotrod.c:155,1601991/0212/sys/src/9/power/devhotrod.c:160,166
1990/1013    
{ 
1990/1106    
	Device *dp; 
	Hotrod *hp; 
1991/0212    
	Hotmsg *mp; 
1990/1106    
 
1990/11211    
	if(c->qid.path == CHDIR){ 
1990/1013    
		if(omode != OREAD) 
1991/0209/sys/src/9/power/devhotrod.c:174,1821991/0212/sys/src/9/power/devhotrod.c:180,189
1991/0209    
		 */ 
		hp->wi = 0; 
		hp->ri = 0; 
		u->khot.cmd = RESET; 
		u->khot.param[0] = (ulong)&hp->rq; 
		u->khot.param[1] = NhotQ; 
1991/0212    
		mp = &u->khot; 
		mp->cmd = RESET; 
		mp->param[0] = MP2VME(&hp->rq); 
		mp->param[1] = NhotQ; 
1991/0209    
		hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot); 
1990/1018    
	} 
1990/1013    
	c->mode = openmode(omode); 
1991/0209/sys/src/9/power/devhotrod.c:205,2491991/0212/sys/src/9/power/devhotrod.c:212,271
1990/1013    
} 
 
/* 
 *  read the hotrod memory 
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 
 * that buf is in KSEG0 and is at an even address. 
1990/1013    
 */ 
1991/0212    
 
1990/1013    
long	  
hotrodread(Chan *c, void *buf, long n) 
{ 
	Hotrod *hp; 
	Device *dp; 
1990/1018    
	ulong *from; 
	ulong *to; 
	ulong *end; 
1991/0212    
	Hotmsg *mp; 
1990/1013    
 
1991/0209    
	if(c->qid.path != Qhotrod) 
		error(Egreg); 
1990/1018    
                 
	/* 
	 *  allow full word access only 
	 */ 
	if((c->offset&(sizeof(ulong)-1)) || (n&(sizeof(ulong)-1))) 
1990/11211    
		error(Ebadarg); 
1990/1018    
                 
1990/1013    
	hp = &hotrod[c->dev]; 
	dp = hp->addr; 
	if(c->offset >= sizeof(dp->mem)) 
		return 0; 
	if(c->offset+n > sizeof(dp->mem)) 
		n = sizeof(dp->mem) - c->offset; 
1990/1018    
                 
	/* 
	 *  avoid memcpy to ensure VME 32-bit reads 
	 */ 
1990/1013    
	qlock(hp); 
1990/1018    
	to = buf; 
	from = &dp->mem[c->offset/sizeof(ulong)]; 
	end = to + (n/sizeof(ulong)); 
1990/1020    
	while(to != end){ 
1990/1018    
		*to++ = *from++; 
1991/0212    
	switch(c->qid.path){ 
	case Qhotrod: 
		if(n > sizeof hp->buf) 
			error(Egreg); 
		if((((ulong)buf)&(KSEGM|3)) == KSEG0){ 
			/* 
			 *  use supplied buffer, no need to lock for reply 
			 */ 
			mp = &u->khot; 
			mp->param[2] = 0;	/* reply count */ 
			qlock(hp); 
			mp->cmd = READ; 
			mp->param[0] = MP2VME(buf); 
			mp->param[1] = n; 
			hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot); 
			qunlock(hp); 
			do 
				n = mp->param[2]; 
			while(n == 0); 
		}else{ 
			/* 
			 *  use hotrod buffer.  lock the buffer till the reply 
			 */ 
			mp = &u->uhot; 
			mp->param[2] = 0;	/* reply count */ 
			qlock(&hp->buflock); 
			qlock(hp); 
			mp->cmd = READ; 
			mp->param[0] = MP2VME(hp->buf); 
			mp->param[1] = n; 
			hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->uhot); 
			qunlock(hp); 
			do 
				n = mp->param[2]; 
			while(n == 0); 
			memcpy(buf, hp->buf, n); 
			qunlock(&hp->buflock); 
		} 
		return n; 
1990/1020    
	} 
1990/1013    
	qunlock(hp); 
	return n; 
1991/0212    
	error(Egreg); 
	return 0; 
1990/1013    
} 
 
/* 
1991/0209/sys/src/9/power/devhotrod.c:253,2891991/0212/sys/src/9/power/devhotrod.c:275,317
1990/1013    
hotrodwrite(Chan *c, void *buf, long n) 
{ 
	Hotrod *hp; 
	Device *dp; 
1990/1018    
	ulong *from; 
	ulong *to; 
	ulong *end; 
1991/0212    
	Hotmsg *mp; 
1990/1013    
 
1991/0209    
	if(c->qid.path != Qhotrod) 
		error(Egreg); 
1990/1018    
	/* 
	 *  allow full word access only 
	 */ 
	if((c->offset&(sizeof(ulong)-1)) || (n&(sizeof(ulong)-1))) 
1990/11211    
		error(Ebadarg); 
1990/1018    
                 
1990/1013    
	hp = &hotrod[c->dev]; 
	dp = hp->addr; 
	if(c->offset >= sizeof(dp->mem)) 
		return 0; 
	if(c->offset+n > sizeof(dp->mem)) 
		n = sizeof(dp->mem) - c->offset; 
1990/1018    
                 
	/* 
	 *  avoid memcpy to ensure VME 32-bit writes 
	 */ 
1990/1013    
	qlock(hp); 
1990/1018    
	from = buf; 
	to = &dp->mem[c->offset/sizeof(ulong)]; 
	end = to + (n/sizeof(ulong)); 
	while(to != end) 
		*to++ = *from++; 
1990/1013    
	qunlock(hp); 
	return n; 
1991/0212    
	switch(c->qid.path){ 
	case 1: 
		if(n > sizeof hp->buf) 
			error(Egreg); 
		if((((ulong)buf)&(KSEGM|3)) == KSEG0){ 
			/* 
			 *  use supplied buffer, no need to lock for reply 
			 */ 
			mp = &u->khot; 
			qlock(hp); 
			mp->cmd = WRITE; 
			mp->param[0] = MP2VME(buf); 
			mp->param[1] = n; 
			hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot); 
			qunlock(hp); 
		}else{ 
			/* 
			 *  use hotrod buffer.  lock the buffer till the reply 
			 */ 
			mp = &u->uhot; 
			qlock(&hp->buflock); 
			qlock(hp); 
			memcpy(hp->buf, buf, n); 
			mp->cmd = WRITE; 
			mp->param[0] = MP2VME(hp->buf); 
			mp->param[1] = n; 
			hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->uhot); 
			qunlock(hp); 
			qunlock(&hp->buflock); 
		} 
		return n; 
	} 
	error(Egreg); 
	return 0; 
1990/1013    
} 
 
void	  


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