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

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

1990/1013/sys/src/9/power/devhotrod.c:14,201990/1018/sys/src/9/power/devhotrod.c:14,20 (short | long)
1990/1013    
enum { 
	Vmevec=		0xd2,		/* vme vector for interrupts */ 
	Intlevel=	5,		/* level to interrupt on */ 
	Nhotrod=	1, 
1990/1018    
	Nhotrod=	2, 
1990/1013    
}; 
 
/* 
1990/1013/sys/src/9/power/devhotrod.c:24,321990/1018/sys/src/9/power/devhotrod.c:24,32
1990/1013    
 *  and	  0xB00000 to   0xBFFFFF  in	A24 space 
 */ 
struct Device { 
	uchar	mem[1*1024*1024]; 
1990/1018    
	ulong	mem[1024*1024/sizeof(ulong)]; 
1990/1013    
}; 
#define HOTROD		VMEA32SUP(Device, 0x30000000) 
1990/1018    
#define HOTROD		VMEA24SUP(Device, 0xB00000) 
1990/1013    
 
struct Hotrod { 
	QLock; 
1990/1013/sys/src/9/power/devhotrod.c:56,621990/1018/sys/src/9/power/devhotrod.c:56,62
1990/1013    
hotrodreset(void) 
{ 
	int i; 
	Hsvme *hp; 
1990/1018    
	Hotrod *hp; 
1990/1013    
 
	for(i=0; i<Nhotrod; i++){ 
		hotrod[i].addr = HOTROD+i; 
1990/1013/sys/src/9/power/devhotrod.c:116,1231990/1018/sys/src/9/power/devhotrod.c:116,122
1990/1013    
	if(c->qid == CHDIR){ 
		if(omode != OREAD) 
			error(0, Eperm); 
	}else 
		streamopen(c, &hotrodinfo); 
1990/1018    
	} 
1990/1013    
	c->mode = openmode(omode); 
	c->flag |= COPEN; 
	c->offset = 0; 
1990/1013/sys/src/9/power/devhotrod.c:143,1491990/1018/sys/src/9/power/devhotrod.c:142,160
1990/1013    
{ 
	Hotrod *hp; 
	Device *dp; 
1990/1018    
	ulong *from; 
	ulong *to; 
	ulong *end; 
1990/1013    
 
1990/1018    
	if(c->qid&CHDIR) 
		return devdirread(c, buf, n, 0, 0, hotrodgen); 
 
	/* 
	 *  allow full word access only 
	 */ 
	if((c->offset&(sizeof(ulong)-1)) || (n&(sizeof(ulong)-1))) 
		error(0, Ebadarg); 
 
1990/1013    
	hp = &hotrod[c->dev]; 
	dp = hp->addr; 
	if(c->offset >= sizeof(dp->mem)) 
1990/1013/sys/src/9/power/devhotrod.c:150,1571990/1018/sys/src/9/power/devhotrod.c:161,176
1990/1013    
		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); 
	memcpy(buf, &dp->mem[c->offset], n); 
1990/1018    
	to = buf; 
	from = &dp->mem[c->offset/sizeof(ulong)]; 
	end = to + (n/sizeof(ulong)); 
	while(to != end) 
		*to++ = *from++; 
1990/1013    
	qunlock(hp); 
	return n; 
} 
1990/1013/sys/src/9/power/devhotrod.c:164,1701990/1018/sys/src/9/power/devhotrod.c:183,198
1990/1013    
{ 
	Hotrod *hp; 
	Device *dp; 
1990/1018    
	ulong *from; 
	ulong *to; 
	ulong *end; 
1990/1013    
 
1990/1018    
	/* 
	 *  allow full word access only 
	 */ 
	if((c->offset&(sizeof(ulong)-1)) || (n&(sizeof(ulong)-1))) 
		error(0, Ebadarg); 
 
1990/1013    
	hp = &hotrod[c->dev]; 
	dp = hp->addr; 
	if(c->offset >= sizeof(dp->mem)) 
1990/1013/sys/src/9/power/devhotrod.c:171,1781990/1018/sys/src/9/power/devhotrod.c:199,214
1990/1013    
		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); 
	memcpy(&dp->mem[c->offset], buf, n); 
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; 
} 
1990/1013/sys/src/9/power/devhotrod.c:201,2061990/1018/sys/src/9/power/devhotrod.c:237,243
1990/1013    
	rooterrstr(e, buf); 
} 
 
1990/1018    
static void 
1990/1013    
hotrodintr(int vec) 
{ 
	Hotrod *hp; 
1990/1018/sys/src/9/power/devhotrod.c:169,1761990/1020/sys/src/9/power/devhotrod.c:169,177 (short | long)
1990/1018    
	to = buf; 
	from = &dp->mem[c->offset/sizeof(ulong)]; 
	end = to + (n/sizeof(ulong)); 
	while(to != end) 
1990/1020    
	while(to != end){ 
1990/1018    
		*to++ = *from++; 
1990/1020    
	} 
1990/1013    
	qunlock(hp); 
	return n; 
} 
1990/1020/sys/src/9/power/devhotrod.c:10,151990/1106/sys/src/9/power/devhotrod.c:10,16 (short | long)
1990/1013    
 
typedef struct Hotrod	Hotrod; 
typedef struct Device	Device; 
1990/1106    
typedef struct Printbuf	Printbuf; 
1990/1013    
 
enum { 
	Vmevec=		0xd2,		/* vme vector for interrupts */ 
1990/1020/sys/src/9/power/devhotrod.c:18,231990/1106/sys/src/9/power/devhotrod.c:19,34
1990/1013    
}; 
 
/* 
1990/1106    
 *  circular 2 pointer queue for hotrod prnt's 
 */ 
struct Printbuf { 
	char	*rptr; 
	char	*wptr; 
	char	*lim; 
	char	buf[4*1024]; 
}; 
 
/* 
1990/1013    
 *  the hotrod fiber interface responds to 1MB 
 *  of either user or supervisor accesses at: 
 *  	0x30000000 to 0x300FFFFF  in	A32 space 
1990/1020/sys/src/9/power/devhotrod.c:31,441990/1106/sys/src/9/power/devhotrod.c:42,59
1990/1013    
struct Hotrod { 
	QLock; 
 
	Device	*addr; 
	int	vec; 
	char	name[NAMELEN]; 
1990/1106    
	Device		*addr;		/* address of the device */ 
	int		vec;		/* vme interrupt vector */ 
	char		name[NAMELEN];	/* hot rod name */ 
	Printbuf	pbuf;		/* circular queue for hotrod print's */ 
	int		kprocstarted; 
	Rendez		r; 
1990/1013    
}; 
 
Hotrod hotrod[Nhotrod]; 
 
static void hotrodintr(int); 
1990/1106    
void	hotrodintr(int); 
void	hotrodkproc(void *a); 
1990/1013    
 
int 
hotrodgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp) 
1990/1020/sys/src/9/power/devhotrod.c:79,841990/1106/sys/src/9/power/devhotrod.c:94,100
1990/1013    
Chan* 
hotrodattach(char *spec) 
{ 
1990/1106    
	Hotrod *hp; 
1990/1013    
	int i; 
	Chan *c; 
 
1990/1020/sys/src/9/power/devhotrod.c:86,911990/1106/sys/src/9/power/devhotrod.c:102,111
1990/1013    
	if(i >= Nhotrod) 
		error(0, Ebadarg); 
 
1990/1106    
	hp = &hotrod[i]; 
	if(hp->kprocstarted == 0) 
		kproc(hp->name, hotrodkproc, hp); 
 
1990/1013    
	c = devattach('H', spec); 
	c->dev = i; 
	c->qid = CHDIR; 
1990/1020/sys/src/9/power/devhotrod.c:113,1181990/1106/sys/src/9/power/devhotrod.c:133,149
1990/1013    
Chan* 
hotrodopen(Chan *c, int omode) 
{ 
1990/1106    
	Device *dp; 
	Hotrod *hp; 
 
	/* 
	 *  Remind hotrod where the print buffer is.  The address we store 
	 *  is the address of the printbuf in VME A32 space. 
	 */ 
	hp = &hotrod[c->dev]; 
	dp = hp->addr; 
	dp->mem[256*1024/sizeof(ulong)] = (((ulong)&hp->pbuf) - KZERO) | (SLAVE<<28); 
 
1990/1013    
	if(c->qid == CHDIR){ 
		if(omode != OREAD) 
			error(0, Eperm); 
1990/1020/sys/src/9/power/devhotrod.c:238,2441990/1106/sys/src/9/power/devhotrod.c:269,275
1990/1013    
	rooterrstr(e, buf); 
} 
 
1990/1018    
static void 
1990/1106    
void 
1990/1013    
hotrodintr(int vec) 
{ 
	Hotrod *hp; 
1990/1020/sys/src/9/power/devhotrod.c:248,2521990/1106/sys/src/9/power/devhotrod.c:279,311
1990/1013    
	if(hp < hotrod || hp > &hotrod[Nhotrod]){ 
		print("bad hotrod vec\n"); 
		return; 
1990/1106    
	} 
} 
 
/* 
 *  print hotrod processor messages on the console 
 */ 
void 
hotrodkproc(void *a) 
{ 
	Hotrod	*hp = a; 
	char	*p; 
 
	hp->kprocstarted = 1; 
	hp->pbuf.rptr = hp->pbuf.wptr = hp->pbuf.buf; 
	hp->pbuf.lim = &hp->pbuf.buf[sizeof(hp->pbuf.buf)]; 
 
	for(;;){ 
		p = hp->pbuf.wptr; 
		if(p != hp->pbuf.rptr){ 
			if(p > hp->pbuf.rptr){ 
				putstrn(hp->pbuf.rptr, p - hp->pbuf.rptr); 
			} else { 
				putstrn(hp->pbuf.rptr, hp->pbuf.lim - hp->pbuf.rptr); 
				putstrn(hp->pbuf.buf, hp->pbuf.wptr - hp->pbuf.buf); 
			} 
			hp->pbuf.rptr = p; 
		} 
		tsleep(&(hp->r), return0, 0, 1000); 
1990/1013    
	} 
} 
1990/1106/sys/src/9/power/devhotrod.c:136,1411990/1110/sys/src/9/power/devhotrod.c:136,142 (short | long)
1990/1106    
	Device *dp; 
	Hotrod *hp; 
 
1990/1110    
#ifdef asdf 
1990/1106    
	/* 
	 *  Remind hotrod where the print buffer is.  The address we store 
	 *  is the address of the printbuf in VME A32 space. 
1990/1106/sys/src/9/power/devhotrod.c:143,1481990/1110/sys/src/9/power/devhotrod.c:144,150
1990/1106    
	hp = &hotrod[c->dev]; 
	dp = hp->addr; 
	dp->mem[256*1024/sizeof(ulong)] = (((ulong)&hp->pbuf) - KZERO) | (SLAVE<<28); 
1990/1110    
#endif 
1990/1106    
 
1990/1013    
	if(c->qid == CHDIR){ 
		if(omode != OREAD) 
1990/1110/sys/src/9/power/devhotrod.c:60,661990/11211/sys/src/9/power/devhotrod.c:60,66 (short | long)
1990/1013    
{ 
	if(i || c->dev>=Nhotrod) 
		return -1; 
	devdir(c, 0, hotrod[c->dev].name, sizeof(Device), 0666, dp); 
1990/11211    
	devdir(c, (Qid){0,0}, hotrod[c->dev].name, sizeof(Device), 0666, dp); 
1990/1013    
	return 1; 
} 
 
1990/1110/sys/src/9/power/devhotrod.c:100,1061990/11211/sys/src/9/power/devhotrod.c:100,106
1990/1013    
 
	i = strtoul(spec, 0, 0); 
	if(i >= Nhotrod) 
		error(0, Ebadarg); 
1990/11211    
		error(Ebadarg); 
1990/1013    
 
1990/1106    
	hp = &hotrod[i]; 
	if(hp->kprocstarted == 0) 
1990/1110/sys/src/9/power/devhotrod.c:108,1141990/11211/sys/src/9/power/devhotrod.c:108,115
1990/1106    
 
1990/1013    
	c = devattach('H', spec); 
	c->dev = i; 
	c->qid = CHDIR; 
1990/11211    
	c->qid.path = CHDIR; 
	c->qid.vers = 0; 
1990/1013    
	return c; 
} 
 
1990/1110/sys/src/9/power/devhotrod.c:146,1541990/11211/sys/src/9/power/devhotrod.c:147,155
1990/1106    
	dp->mem[256*1024/sizeof(ulong)] = (((ulong)&hp->pbuf) - KZERO) | (SLAVE<<28); 
1990/1110    
#endif 
1990/1106    
 
1990/1013    
	if(c->qid == CHDIR){ 
1990/11211    
	if(c->qid.path == CHDIR){ 
1990/1013    
		if(omode != OREAD) 
			error(0, Eperm); 
1990/11211    
			error(Eperm); 
1990/1018    
	} 
1990/1013    
	c->mode = openmode(omode); 
	c->flag |= COPEN; 
1990/1110/sys/src/9/power/devhotrod.c:159,1651990/11211/sys/src/9/power/devhotrod.c:160,166
1990/1013    
void	  
hotrodcreate(Chan *c, char *name, int omode, ulong perm) 
{ 
	error(0, Eperm); 
1990/11211    
	error(Eperm); 
1990/1013    
} 
 
void	  
1990/1110/sys/src/9/power/devhotrod.c:179,1851990/11211/sys/src/9/power/devhotrod.c:180,186
1990/1018    
	ulong *to; 
	ulong *end; 
1990/1013    
 
1990/1018    
	if(c->qid&CHDIR) 
1990/11211    
	if(c->qid.path & CHDIR) 
1990/1018    
		return devdirread(c, buf, n, 0, 0, hotrodgen); 
 
	/* 
1990/1110/sys/src/9/power/devhotrod.c:186,1921990/11211/sys/src/9/power/devhotrod.c:187,193
1990/1018    
	 *  allow full word access only 
	 */ 
	if((c->offset&(sizeof(ulong)-1)) || (n&(sizeof(ulong)-1))) 
		error(0, Ebadarg); 
1990/11211    
		error(Ebadarg); 
1990/1018    
 
1990/1013    
	hp = &hotrod[c->dev]; 
	dp = hp->addr; 
1990/1110/sys/src/9/power/devhotrod.c:225,2311990/11211/sys/src/9/power/devhotrod.c:226,232
1990/1018    
	 *  allow full word access only 
	 */ 
	if((c->offset&(sizeof(ulong)-1)) || (n&(sizeof(ulong)-1))) 
		error(0, Ebadarg); 
1990/11211    
		error(Ebadarg); 
1990/1018    
 
1990/1013    
	hp = &hotrod[c->dev]; 
	dp = hp->addr; 
1990/1110/sys/src/9/power/devhotrod.c:250,2741990/11211/sys/src/9/power/devhotrod.c:251,263
1990/1013    
void	  
hotrodremove(Chan *c) 
{ 
	error(0, Eperm); 
1990/11211    
	error(Eperm); 
1990/1013    
} 
 
void	  
hotrodwstat(Chan *c, char *dp) 
{ 
	error(0, Eperm); 
} 
                 
void 
hotroduserstr(Error *e, char *buf) 
{ 
	consuserstr(e, buf); 
} 
                 
void	  
hotroderrstr(Error *e, char *buf) 
{ 
	rooterrstr(e, buf); 
1990/11211    
	error(Eperm); 
1990/1013    
} 
 
1990/1106    
void 
1990/11211/sys/src/9/power/devhotrod.c:9,521991/0209/sys/src/9/power/devhotrod.c:9,54 (short | long)
1990/1013    
#include	"io.h" 
 
typedef struct Hotrod	Hotrod; 
1991/0209    
typedef struct HotQ	HotQ; 
1990/1013    
typedef struct Device	Device; 
1990/1106    
typedef struct Printbuf	Printbuf; 
1990/1013    
 
enum { 
	Vmevec=		0xd2,		/* vme vector for interrupts */ 
	Intlevel=	5,		/* level to interrupt on */ 
1990/1018    
	Nhotrod=	2, 
1991/0209    
	Qdir=		0,		/* Qid's */ 
	Qhotrod=	1, 
	NhotQ=		10,		/* size of communication queues */ 
	Nhotrod=	1, 
1990/1013    
}; 
 
/* 
1990/1106    
 *  circular 2 pointer queue for hotrod prnt's 
 */ 
struct Printbuf { 
	char	*rptr; 
	char	*wptr; 
	char	*lim; 
	char	buf[4*1024]; 
}; 
                 
/* 
1990/1013    
 *  the hotrod fiber interface responds to 1MB 
1991/0209    
 *  The hotrod fiber interface responds to 1MB 
1990/1013    
 *  of either user or supervisor accesses at: 
 *  	0x30000000 to 0x300FFFFF  in	A32 space 
 *  and	  0xB00000 to   0xBFFFFF  in	A24 space 
1991/0209    
 *  and	  0xB00000 to   0xBFFFFF  in	A24 space. 
 *  The second 0x40000 of this space is on-board SRAM. 
1990/1013    
 */ 
struct Device { 
1990/1018    
	ulong	mem[1024*1024/sizeof(ulong)]; 
1991/0209    
	ulong	mem[0x100000/sizeof(ulong)]; 
1990/1013    
}; 
1990/1018    
#define HOTROD		VMEA24SUP(Device, 0xB00000) 
1990/1013    
 
struct Hotrod { 
	QLock; 
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; 
	Lock		busy; 
1990/1106    
	Device		*addr;		/* address of the device */ 
	int		vec;		/* vme interrupt vector */ 
	char		name[NAMELEN];	/* hot rod name */ 
	Printbuf	pbuf;		/* circular queue for hotrod print's */ 
	int		kprocstarted; 
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 */ 
	int		ri;		/* where to read next response */ 
1990/1106    
	Rendez		r; 
1990/1013    
}; 
 
1990/11211/sys/src/9/power/devhotrod.c:53,671991/0209/sys/src/9/power/devhotrod.c:55,80
1990/1013    
Hotrod hotrod[Nhotrod]; 
 
1990/1106    
void	hotrodintr(int); 
void	hotrodkproc(void *a); 
1990/1013    
 
int 
hotrodgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp) 
1991/0209    
/* 
 * Commands 
 */ 
enum{ 
	RESET=	0,	/* params: Q address, length of queue */ 
	REBOOT=	1,	/* params: none */ 
}; 
 
void 
hotsend(Hotrod *h, Hotmsg *m) 
1990/1013    
{ 
	if(i || c->dev>=Nhotrod) 
		return -1; 
1990/11211    
	devdir(c, (Qid){0,0}, hotrod[c->dev].name, sizeof(Device), 0666, dp); 
1990/1013    
	return 1; 
1991/0209    
print("hotsend send %d %lux %lux\n", m->cmd, m, m->param[0]); 
	h->wq->msg[h->wi] = m; 
	while(h->wq->msg[h->wi]) 
		; 
print("hotsend done\n"); 
	h->wi++; 
	if(h->wi >= NhotQ) 
		h->wi = 0; 
1990/1013    
} 
 
/* 
1990/11211/sys/src/9/power/devhotrod.c:73,831991/0209/sys/src/9/power/devhotrod.c:86,99
1990/1013    
	int i; 
1990/1018    
	Hotrod *hp; 
1990/1013    
 
	for(i=0; i<Nhotrod; i++){ 
		hotrod[i].addr = HOTROD+i; 
		hotrod[i].vec = Vmevec+i; 
		sprint(hotrod[i].name, "hotrod%d", i); 
		setvmevec(hotrod[i].vec, hotrodintr); 
1991/0209    
	for(hp=hotrod,i=0; i<Nhotrod; i++,hp++){ 
		hp->addr = HOTROD+i; 
		/* 
		 * Write queue is at end of hotrod memory 
		 */ 
		hp->wq = (HotQ*)((ulong)hp->addr+2*0x40000-sizeof(HotQ)); 
		hp->vec = Vmevec+i; 
		setvmevec(hp->vec, hotrodintr); 
1990/1013    
	}	 
	wbflush(); 
	delay(20); 
1990/11211/sys/src/9/power/devhotrod.c:102,1111991/0209/sys/src/9/power/devhotrod.c:118,123
1990/1013    
	if(i >= Nhotrod) 
1990/11211    
		error(Ebadarg); 
1990/1013    
 
1990/1106    
	hp = &hotrod[i]; 
	if(hp->kprocstarted == 0) 
		kproc(hp->name, hotrodkproc, hp); 
                 
1990/1013    
	c = devattach('H', spec); 
	c->dev = i; 
1990/11211    
	c->qid.path = CHDIR; 
1990/11211/sys/src/9/power/devhotrod.c:122,1341991/0209/sys/src/9/power/devhotrod.c:134,153
1990/1013    
int	  
hotrodwalk(Chan *c, char *name) 
{ 
	return devwalk(c, name, 0, 0, hotrodgen); 
1991/0209    
	if(c->qid.path != CHDIR) 
		return 0; 
	if(strncmp(name, "hotrod", 6) == 0){ 
		c->qid.path = Qhotrod; 
		return 1; 
	} 
	return 0; 
1990/1013    
} 
 
void	  
hotrodstat(Chan *c, char *dp) 
{ 
	devstat(c, dp, 0, 0, hotrodgen); 
1991/0209    
	print("hotrodstat\n"); 
	error(Egreg); 
1990/1013    
} 
 
Chan* 
1990/11211/sys/src/9/power/devhotrod.c:137,1551991/0209/sys/src/9/power/devhotrod.c:156,183
1990/1106    
	Device *dp; 
	Hotrod *hp; 
 
1990/1110    
#ifdef asdf 
1990/1106    
	/* 
	 *  Remind hotrod where the print buffer is.  The address we store 
	 *  is the address of the printbuf in VME A32 space. 
	 */ 
	hp = &hotrod[c->dev]; 
	dp = hp->addr; 
	dp->mem[256*1024/sizeof(ulong)] = (((ulong)&hp->pbuf) - KZERO) | (SLAVE<<28); 
1990/1110    
#endif 
1990/1106    
                 
1990/11211    
	if(c->qid.path == CHDIR){ 
1990/1013    
		if(omode != OREAD) 
1990/11211    
			error(Eperm); 
1991/0209    
	}else if(c->qid.path == Qhotrod){ 
		hp = &hotrod[c->dev]; 
		if(!canlock(&hp->busy)) 
			error(Einuse); 
		/* 
		 * Clear communications region 
		 */ 
		memset(hp->wq->msg, 0, sizeof(hp->wq->msg)); 
		hp->wq->i = 0; 
 
		/* 
		 * Issue reset 
		 */ 
		hp->wi = 0; 
		hp->ri = 0; 
		u->khot.cmd = RESET; 
		u->khot.param[0] = (ulong)&hp->rq; 
		u->khot.param[1] = NhotQ; 
		hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot); 
1990/1018    
	} 
1990/1013    
	c->mode = openmode(omode); 
	c->flag |= COPEN; 
1990/11211/sys/src/9/power/devhotrod.c:166,1711991/0209/sys/src/9/power/devhotrod.c:194,207
1990/1013    
void	  
hotrodclose(Chan *c) 
{ 
1991/0209    
	Hotrod *hp; 
 
	hp = &hotrod[c->dev]; 
	if(c->qid.path != CHDIR){ 
		u->khot.cmd = REBOOT; 
		hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot); 
		unlock(&hp->busy); 
	} 
1990/1013    
} 
 
/* 
1990/11211/sys/src/9/power/devhotrod.c:180,1871991/0209/sys/src/9/power/devhotrod.c:216,223
1990/1018    
	ulong *to; 
	ulong *end; 
1990/1013    
 
1990/11211    
	if(c->qid.path & CHDIR) 
1990/1018    
		return devdirread(c, buf, n, 0, 0, hotrodgen); 
1991/0209    
	if(c->qid.path != Qhotrod) 
		error(Egreg); 
1990/1018    
 
	/* 
	 *  allow full word access only 
1990/11211/sys/src/9/power/devhotrod.c:222,2271991/0209/sys/src/9/power/devhotrod.c:258,265
1990/1018    
	ulong *to; 
	ulong *end; 
1990/1013    
 
1991/0209    
	if(c->qid.path != Qhotrod) 
		error(Egreg); 
1990/1018    
	/* 
	 *  allow full word access only 
	 */ 
1990/11211/sys/src/9/power/devhotrod.c:270,3021991/0209/sys/src/9/power/devhotrod.c:308,312
1990/1013    
	if(hp < hotrod || hp > &hotrod[Nhotrod]){ 
		print("bad hotrod vec\n"); 
		return; 
1990/1106    
	} 
} 
                 
/* 
 *  print hotrod processor messages on the console 
 */ 
void 
hotrodkproc(void *a) 
{ 
	Hotrod	*hp = a; 
	char	*p; 
                 
	hp->kprocstarted = 1; 
	hp->pbuf.rptr = hp->pbuf.wptr = hp->pbuf.buf; 
	hp->pbuf.lim = &hp->pbuf.buf[sizeof(hp->pbuf.buf)]; 
                 
	for(;;){ 
		p = hp->pbuf.wptr; 
		if(p != hp->pbuf.rptr){ 
			if(p > hp->pbuf.rptr){ 
				putstrn(hp->pbuf.rptr, p - hp->pbuf.rptr); 
			} else { 
				putstrn(hp->pbuf.rptr, hp->pbuf.lim - hp->pbuf.rptr); 
				putstrn(hp->pbuf.buf, hp->pbuf.wptr - hp->pbuf.buf); 
			} 
			hp->pbuf.rptr = p; 
		} 
		tsleep(&(hp->r), return0, 0, 1000); 
1990/1013    
	} 
} 
1991/0209/sys/src/9/power/devhotrod.c:5,101991/0212/sys/src/9/power/devhotrod.c:5,11 (short | long)
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	  
1991/0212/sys/src/9/power/devhotrod.c:67,721991/0214/sys/src/9/power/devhotrod.c:67,73 (short | long)
1991/0209    
	REBOOT=	1,	/* params: none */ 
1991/0212    
	READ=	2,	/* params: buffer, count, returned count */ 
	WRITE=	3,	/* params: buffer, count */ 
1991/0214    
	TEST=	7,	/* params: none */ 
1991/0209    
}; 
 
void 
1991/0212/sys/src/9/power/devhotrod.c:185,1901991/0214/sys/src/9/power/devhotrod.c:186,201
1991/0212    
		mp->param[0] = MP2VME(&hp->rq); 
		mp->param[1] = NhotQ; 
1991/0209    
		hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot); 
1991/0214    
		delay(1000); 
		print("reset\n"); 
		/* 
		 * Issue reset 
		 */ 
		mp->cmd = TEST; 
		hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot); 
		print("ok1\n"); 
		delay(1000); 
		print("ok2\n"); 
1990/1018    
	} 
1990/1013    
	c->mode = openmode(omode); 
	c->flag |= COPEN; 
1991/0214/sys/src/9/power/devhotrod.c:8,171991/0215/sys/src/9/power/devhotrod.c:8,17 (short | long)
1991/0212    
#include	"fcall.h" 
1990/1013    
 
#include	"io.h" 
1991/0215    
#include	"hrod.h" 
1990/1013    
 
typedef struct Hotrod	Hotrod; 
1991/0209    
typedef struct HotQ	HotQ; 
1990/1013    
typedef struct Device	Device; 
 
enum { 
	Vmevec=		0xd2,		/* vme vector for interrupts */ 
1991/0214/sys/src/9/power/devhotrod.c:18,391991/0215/sys/src/9/power/devhotrod.c:18,27
1990/1013    
	Intlevel=	5,		/* level to interrupt on */ 
1991/0209    
	Qdir=		0,		/* Qid's */ 
	Qhotrod=	1, 
	NhotQ=		10,		/* size of communication queues */ 
1991/0215    
	NhotQ=		NRQ,		/* size of communication queues */ 
1991/0209    
	Nhotrod=	1, 
1990/1013    
}; 
 
/* 
1991/0209    
 *  The hotrod fiber interface responds to 1MB 
1990/1013    
 *  of either user or supervisor accesses at: 
 *  	0x30000000 to 0x300FFFFF  in	A32 space 
1991/0209    
 *  and	  0xB00000 to   0xBFFFFF  in	A24 space. 
 *  The second 0x40000 of this space is on-board SRAM. 
1990/1013    
 */ 
struct Device { 
1991/0209    
	ulong	mem[0x100000/sizeof(ulong)]; 
1990/1013    
}; 
1990/1018    
#define HOTROD		VMEA24SUP(Device, 0xB00000) 
1990/1013    
                 
1991/0209    
struct HotQ{ 
	ulong	i;			/* index into queue */ 
	Hotmsg	*msg[NhotQ];		/* pointer to command buffer */ 
1991/0214/sys/src/9/power/devhotrod.c:45,511991/0215/sys/src/9/power/devhotrod.c:33,39
1991/0209    
	QLock; 
1991/0212    
	QLock		buflock; 
1991/0209    
	Lock		busy; 
1990/1106    
	Device		*addr;		/* address of the device */ 
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 */ 
1991/0214/sys/src/9/power/devhotrod.c:59,641991/0215/sys/src/9/power/devhotrod.c:47,54
1990/1013    
 
1990/1106    
void	hotrodintr(int); 
1990/1013    
 
1991/0215    
#define	HOTROD	VMEA24SUP(Hot, 0xB00000); 
 
1991/0209    
/* 
 * Commands 
 */ 
1991/0214/sys/src/9/power/devhotrod.c:75,821991/0215/sys/src/9/power/devhotrod.c:65,73
1990/1013    
{ 
1991/0209    
print("hotsend send %d %lux %lux\n", m->cmd, m, m->param[0]); 
1991/0212    
	h->wq->msg[h->wi] = (Hotmsg*)MP2VME(m); 
1991/0209    
	while(h->wq->msg[h->wi]) 
		; 
1991/0215    
	do 
		delay(1); 
	while(h->wq->msg[h->wi]); 
1991/0209    
print("hotsend done\n"); 
	h->wi++; 
	if(h->wi >= NhotQ) 
1991/0214/sys/src/9/power/devhotrod.c:97,1051991/0215/sys/src/9/power/devhotrod.c:88,97
1991/0209    
		/* 
		 * Write queue is at end of hotrod memory 
		 */ 
		hp->wq = (HotQ*)((ulong)hp->addr+2*0x40000-sizeof(HotQ)); 
1991/0215    
		hp->wq = (HotQ*)(&hp->addr->hostrp); 
1991/0209    
		hp->vec = Vmevec+i; 
		setvmevec(hp->vec, hotrodintr); 
1991/0215    
setvmevec(0xFF, hotrodintr); 
1990/1013    
	}	 
	wbflush(); 
	delay(20); 
1991/0214/sys/src/9/power/devhotrod.c:159,1651991/0215/sys/src/9/power/devhotrod.c:151,156
1990/1013    
Chan* 
hotrodopen(Chan *c, int omode) 
{ 
1990/1106    
	Device *dp; 
	Hotrod *hp; 
1991/0212    
	Hotmsg *mp; 
1990/1106    
 
1991/0214/sys/src/9/power/devhotrod.c:186,2011991/0215/sys/src/9/power/devhotrod.c:177,184
1991/0212    
		mp->param[0] = MP2VME(&hp->rq); 
		mp->param[1] = NhotQ; 
1991/0209    
		hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot); 
1991/0214    
		delay(1000); 
1991/0215    
		delay(100); 
1991/0214    
		print("reset\n"); 
		/* 
		 * Issue reset 
		 */ 
		mp->cmd = TEST; 
		hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot); 
		print("ok1\n"); 
		delay(1000); 
		print("ok2\n"); 
1990/1018    
	} 
1990/1013    
	c->mode = openmode(omode); 
	c->flag |= COPEN; 
1991/0214/sys/src/9/power/devhotrod.c:233,2381991/0215/sys/src/9/power/devhotrod.c:216,222
1990/1013    
{ 
	Hotrod *hp; 
1991/0212    
	Hotmsg *mp; 
1991/0215    
	ulong l; 
1990/1013    
 
	hp = &hotrod[c->dev]; 
1991/0212    
	switch(c->qid.path){ 
1991/0214/sys/src/9/power/devhotrod.c:251,2621991/0215/sys/src/9/power/devhotrod.c:235,251
1991/0212    
			mp->param[1] = n; 
			hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot); 
			qunlock(hp); 
1991/0215    
			l = 100*1000*000; 
1991/0212    
			do 
				n = mp->param[2]; 
			while(n == 0); 
1991/0215    
			while(n==0 && --l>0); 
			if(n == 0){ 
				print("devhotrod: give up\n"); 
				error(Egreg); 
			} 
1991/0212    
		}else{ 
			/* 
			 *  use hotrod buffer.  lock the buffer till the reply 
1991/0215    
			 *  use hotrod buffer.  lock the buffer until the reply 
1991/0212    
			 */ 
			mp = &u->uhot; 
			mp->param[2] = 0;	/* reply count */ 
1991/0214/sys/src/9/power/devhotrod.c:267,2771991/0215/sys/src/9/power/devhotrod.c:256,271
1991/0212    
			mp->param[1] = n; 
			hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->uhot); 
			qunlock(hp); 
1991/0215    
			l = 100*1000*1000; 
1991/0212    
			do 
				n = mp->param[2]; 
			while(n == 0); 
1991/0215    
			while(n==0 && --l>0); 
1991/0212    
			memcpy(buf, hp->buf, n); 
			qunlock(&hp->buflock); 
1991/0215    
			if(n == 0){ 
				print("devhotrod: give up\n"); 
				error(Egreg); 
			} 
1991/0212    
		} 
		return n; 
1990/1020    
	} 
1991/0214/sys/src/9/power/devhotrod.c:344,3511991/0215/sys/src/9/power/devhotrod.c:338,347
1990/1013    
 
	print("hotrod%d interrupt\n", vec - Vmevec); 
	hp = &hotrod[vec - Vmevec]; 
1991/0215    
hp=&hotrod[0]; 
1990/1013    
	if(hp < hotrod || hp > &hotrod[Nhotrod]){ 
		print("bad hotrod vec\n"); 
		return; 
	} 
1991/0215    
	hp->addr->csr3 &= ~INT_VME; 
1990/1013    
} 
1991/0215/sys/src/9/power/devhotrod.c:91,971991/0219/sys/src/9/power/devhotrod.c:91,96 (short | long)
1991/0215    
		hp->wq = (HotQ*)(&hp->addr->hostrp); 
1991/0209    
		hp->vec = Vmevec+i; 
		setvmevec(hp->vec, hotrodintr); 
1991/0215    
setvmevec(0xFF, hotrodintr); 
1990/1013    
	}	 
	wbflush(); 
	delay(20); 
1991/0215/sys/src/9/power/devhotrod.c:179,1841991/0219/sys/src/9/power/devhotrod.c:178,192
1991/0209    
		hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot); 
1991/0215    
		delay(100); 
1991/0214    
		print("reset\n"); 
1991/0219    
 
		/* 
		 * Issue test 
		 */ 
		mp = &u->khot; 
		mp->cmd = TEST; 
		hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot); 
		delay(100); 
		print("tested\n"); 
1990/1018    
	} 
1990/1013    
	c->mode = openmode(omode); 
	c->flag |= COPEN; 
1991/0215/sys/src/9/power/devhotrod.c:338,3471991/0219/sys/src/9/power/devhotrod.c:346,354
1990/1013    
 
	print("hotrod%d interrupt\n", vec - Vmevec); 
	hp = &hotrod[vec - Vmevec]; 
1991/0215    
hp=&hotrod[0]; 
1990/1013    
	if(hp < hotrod || hp > &hotrod[Nhotrod]){ 
		print("bad hotrod vec\n"); 
		return; 
	} 
1991/0215    
	hp->addr->csr3 &= ~INT_VME; 
1991/0219    
	hp->addr->lcsr3 &= ~INT_VME; 
1990/1013    
} 
1991/0219/sys/src/9/power/devhotrod.c:40,461991/0220/sys/src/9/power/devhotrod.c:40,46 (short | long)
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]; 
1991/0220    
	uchar		buf[MAXFDATA+MAXMSG]; 
1990/1013    
}; 
 
Hotrod hotrod[Nhotrod]; 
1991/0219/sys/src/9/power/devhotrod.c:63,741991/0220/sys/src/9/power/devhotrod.c:63,74
1991/0209    
void 
hotsend(Hotrod *h, Hotmsg *m) 
1990/1013    
{ 
1991/0209    
print("hotsend send %d %lux %lux\n", m->cmd, m, m->param[0]); 
1991/0220    
/* print("hotsend send %d %d %lux %lux\n", h->wi, m->cmd, m, m->param[0]); /**/ 
1991/0212    
	h->wq->msg[h->wi] = (Hotmsg*)MP2VME(m); 
1991/0215    
	do 
		delay(1); 
	while(h->wq->msg[h->wi]); 
1991/0209    
print("hotsend done\n"); 
1991/0220    
/* print("hotsend done\n"); /**/ 
1991/0209    
	h->wi++; 
	if(h->wi >= NhotQ) 
		h->wi = 0; 
1991/0219/sys/src/9/power/devhotrod.c:179,1841991/0220/sys/src/9/power/devhotrod.c:179,185
1991/0215    
		delay(100); 
1991/0214    
		print("reset\n"); 
1991/0219    
 
1991/0220    
#ifdef asdf 
1991/0219    
		/* 
		 * Issue test 
		 */ 
1991/0219/sys/src/9/power/devhotrod.c:187,1921991/0220/sys/src/9/power/devhotrod.c:188,194
1991/0219    
		hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot); 
		delay(100); 
		print("tested\n"); 
1991/0220    
#endif 
1990/1018    
	} 
1990/1013    
	c->mode = openmode(omode); 
	c->flag |= COPEN; 
1991/0219/sys/src/9/power/devhotrod.c:229,2361991/0220/sys/src/9/power/devhotrod.c:231,240
1990/1013    
	hp = &hotrod[c->dev]; 
1991/0212    
	switch(c->qid.path){ 
	case Qhotrod: 
		if(n > sizeof hp->buf) 
1991/0220    
		if(n > sizeof hp->buf){ 
			print("hotrod bufsize\n"); 
1991/0212    
			error(Egreg); 
1991/0220    
		} 
1991/0212    
		if((((ulong)buf)&(KSEGM|3)) == KSEG0){ 
			/* 
			 *  use supplied buffer, no need to lock for reply 
1991/0219/sys/src/9/power/devhotrod.c:243,2491991/0220/sys/src/9/power/devhotrod.c:247,253
1991/0212    
			mp->param[1] = n; 
			hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot); 
			qunlock(hp); 
1991/0215    
			l = 100*1000*000; 
1991/0220    
			l = 100*1000*1000; 
1991/0212    
			do 
				n = mp->param[2]; 
1991/0215    
			while(n==0 && --l>0); 
1991/0219/sys/src/9/power/devhotrod.c:277,2821991/0220/sys/src/9/power/devhotrod.c:281,287
1991/0212    
		} 
		return n; 
1990/1020    
	} 
1991/0220    
	print("hotrod read unk\n"); 
1991/0212    
	error(Egreg); 
	return 0; 
1990/1013    
} 
1991/0219/sys/src/9/power/devhotrod.c:293,3001991/0220/sys/src/9/power/devhotrod.c:298,307
1990/1013    
	hp = &hotrod[c->dev]; 
1991/0212    
	switch(c->qid.path){ 
	case 1: 
		if(n > sizeof hp->buf) 
1991/0220    
		if(n > sizeof hp->buf){ 
			print("hotrod write bufsize\n"); 
1991/0212    
			error(Egreg); 
1991/0220    
		} 
1991/0212    
		if((((ulong)buf)&(KSEGM|3)) == KSEG0){ 
			/* 
			 *  use supplied buffer, no need to lock for reply 
1991/0219/sys/src/9/power/devhotrod.c:323,3281991/0220/sys/src/9/power/devhotrod.c:330,336
1991/0212    
		} 
		return n; 
	} 
1991/0220    
	print("hotrod write unk\n"); 
1991/0212    
	error(Egreg); 
	return 0; 
1990/1013    
} 
1991/0219/sys/src/9/power/devhotrod.c:344,3501991/0220/sys/src/9/power/devhotrod.c:352,358
1990/1013    
{ 
	Hotrod *hp; 
 
	print("hotrod%d interrupt\n", vec - Vmevec); 
1991/0220    
/*	print("hotrod%d interrupt\n", vec - Vmevec); /**/ 
1990/1013    
	hp = &hotrod[vec - Vmevec]; 
	if(hp < hotrod || hp > &hotrod[Nhotrod]){ 
		print("bad hotrod vec\n"); 
1991/0220/sys/src/9/power/devhotrod.c:179,1851991/0222/sys/src/9/power/devhotrod.c:179,184 (short | long)
1991/0215    
		delay(100); 
1991/0214    
		print("reset\n"); 
1991/0219    
 
1991/0220    
#ifdef asdf 
1991/0219    
		/* 
		 * Issue test 
		 */ 
1991/0220/sys/src/9/power/devhotrod.c:188,1941991/0222/sys/src/9/power/devhotrod.c:187,192
1991/0219    
		hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot); 
		delay(100); 
		print("tested\n"); 
1991/0220    
#endif 
1990/1018    
	} 
1990/1013    
	c->mode = openmode(omode); 
	c->flag |= COPEN; 
1991/0222/sys/src/9/power/devhotrod.c:147,1521991/0227/sys/src/9/power/devhotrod.c:147,155 (short | long)
1991/0209    
	error(Egreg); 
1990/1013    
} 
 
1991/0227    
#define	NTESTBUF	256 
ulong	testbuf[NTESTBUF]; 
 
1990/1013    
Chan* 
hotrodopen(Chan *c, int omode) 
{ 
1991/0222/sys/src/9/power/devhotrod.c:184,1891991/0227/sys/src/9/power/devhotrod.c:187,194
1991/0219    
		 */ 
		mp = &u->khot; 
		mp->cmd = TEST; 
1991/0227    
		mp->param[0] = MP2VME(testbuf); 
		mp->param[1] = NTESTBUF; 
1991/0219    
		hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot); 
		delay(100); 
		print("tested\n"); 
1991/0227/sys/src/9/power/devhotrod.c:182,1871991/0302/sys/src/9/power/devhotrod.c:182,188 (short | long)
1991/0215    
		delay(100); 
1991/0214    
		print("reset\n"); 
1991/0219    
 
1991/0302    
#ifdef asdf 
1991/0219    
		/* 
		 * Issue test 
		 */ 
1991/0227/sys/src/9/power/devhotrod.c:192,1971991/0302/sys/src/9/power/devhotrod.c:193,199
1991/0219    
		hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot); 
		delay(100); 
		print("tested\n"); 
1991/0302    
#endif 
1990/1018    
	} 
1990/1013    
	c->mode = openmode(omode); 
	c->flag |= COPEN; 
1991/0302/sys/src/9/power/devhotrod.c:10,151991/0303/sys/src/9/power/devhotrod.c:10,22 (short | long)
1990/1013    
#include	"io.h" 
1991/0215    
#include	"hrod.h" 
1990/1013    
 
1991/0303    
void	mem(Hot*, ulong*, ulong); 
 
/* 
 * If set, causes data transfers to have checksums 
 */ 
#define	ENABCKSUM	1 
 
1990/1013    
typedef struct Hotrod	Hotrod; 
1991/0209    
typedef struct HotQ	HotQ; 
1990/1013    
 
1991/0302/sys/src/9/power/devhotrod.c:55,621991/0303/sys/src/9/power/devhotrod.c:62,69
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/0303    
	READ=	2,	/* params: buffer, count, sum, returned count */ 
	WRITE=	3,	/* params: buffer, count, sum */ 
1991/0214    
	TEST=	7,	/* params: none */ 
1991/0209    
}; 
 
1991/0302/sys/src/9/power/devhotrod.c:192,1981991/0303/sys/src/9/power/devhotrod.c:199,209
1991/0227    
		mp->param[1] = NTESTBUF; 
1991/0219    
		hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot); 
		delay(100); 
		print("tested\n"); 
1991/0303    
		print("testing addr %lux size %ld\n", mp->param[0], mp->param[1]); 
		for(;;){ 
			print("-"); 
			mem(hp->addr, &hp->addr->ram[(mp->param[0]-0x40000)/sizeof(ulong)], mp->param[1]); 
		} 
1991/0302    
#endif 
1990/1018    
	} 
1990/1013    
	c->mode = openmode(omode); 
1991/0302/sys/src/9/power/devhotrod.c:220,2251991/0303/sys/src/9/power/devhotrod.c:231,250
1991/0209    
	} 
1990/1013    
} 
 
1991/0303    
ulong 
hotsum(ulong *p, int n, ulong doit) 
{ 
	ulong sum; 
 
	if(!doit) 
		return 0; 
	sum = 0; 
	n = (n+sizeof(ulong)-1)/sizeof(ulong); 
	while(--n >= 0) 
		sum += *p++; 
	return sum; 
} 
 
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/0302/sys/src/9/power/devhotrod.c:231,2371991/0303/sys/src/9/power/devhotrod.c:256,262
1990/1013    
{ 
	Hotrod *hp; 
1991/0212    
	Hotmsg *mp; 
1991/0215    
	ulong l; 
1991/0303    
	ulong l, m; 
1990/1013    
 
	hp = &hotrod[c->dev]; 
1991/0212    
	switch(c->qid.path){ 
1991/0302/sys/src/9/power/devhotrod.c:245,2511991/0303/sys/src/9/power/devhotrod.c:270,277
1991/0212    
			 *  use supplied buffer, no need to lock for reply 
			 */ 
			mp = &u->khot; 
			mp->param[2] = 0;	/* reply count */ 
1991/0303    
			mp->param[2] = 0;	/* checksum */ 
			mp->param[3] = 0;	/* reply count */ 
1991/0212    
			qlock(hp); 
			mp->cmd = READ; 
			mp->param[0] = MP2VME(buf); 
1991/0302/sys/src/9/power/devhotrod.c:254,2711991/0303/sys/src/9/power/devhotrod.c:280,303
1991/0212    
			qunlock(hp); 
1991/0220    
			l = 100*1000*1000; 
1991/0212    
			do 
				n = mp->param[2]; 
1991/0215    
			while(n==0 && --l>0); 
			if(n == 0){ 
				print("devhotrod: give up\n"); 
1991/0303    
				m = mp->param[3]; 
			while(m==0 && --l>0); 
			if(m==0 || m>n){ 
				print("devhotrod: count %ld %ld\n", m, n); 
1991/0215    
				error(Egreg); 
			} 
1991/0303    
			if(mp->param[2] != hotsum(buf, m, mp->param[2])){ 
				print("hotrod cksum err is %lux sb %lux\n", 
					hotsum(buf, n, 1), mp->param[2]); 
				error(Eio); 
			} 
1991/0212    
		}else{ 
			/* 
1991/0215    
			 *  use hotrod buffer.  lock the buffer until the reply 
1991/0212    
			 */ 
			mp = &u->uhot; 
			mp->param[2] = 0;	/* reply count */ 
1991/0303    
			mp->param[2] = 0;	/* checksum */ 
			mp->param[3] = 0;	/* reply count */ 
1991/0212    
			qlock(&hp->buflock); 
			qlock(hp); 
			mp->cmd = READ; 
1991/0302/sys/src/9/power/devhotrod.c:275,2901991/0303/sys/src/9/power/devhotrod.c:307,329
1991/0212    
			qunlock(hp); 
1991/0215    
			l = 100*1000*1000; 
1991/0212    
			do 
				n = mp->param[2]; 
1991/0215    
			while(n==0 && --l>0); 
1991/0212    
			memcpy(buf, hp->buf, n); 
			qunlock(&hp->buflock); 
1991/0215    
			if(n == 0){ 
				print("devhotrod: give up\n"); 
1991/0303    
				m = mp->param[3]; 
			while(m==0 && --l>0); 
			if(m==0 || m>n){ 
				print("devhotrod: count %ld %ld\n", m, n); 
				qunlock(&hp->buflock); 
1991/0215    
				error(Egreg); 
			} 
1991/0303    
			if(mp->param[2] != hotsum((ulong*)hp->buf, m, mp->param[2])){ 
				print("hotrod cksum err is %lux sb %lux\n", 
					hotsum((ulong*)hp->buf, n, 1), mp->param[2]); 
				qunlock(&hp->buflock); 
				error(Eio); 
			} 
			memcpy(buf, hp->buf, m); 
			qunlock(&hp->buflock); 
1991/0212    
		} 
		return n; 
1991/0303    
		return m; 
1990/1020    
	} 
1991/0220    
	print("hotrod read unk\n"); 
1991/0212    
	error(Egreg); 
1991/0302/sys/src/9/power/devhotrod.c:316,3211991/0303/sys/src/9/power/devhotrod.c:355,361
1991/0212    
			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); 
			qunlock(hp); 
		}else{ 
1991/0302/sys/src/9/power/devhotrod.c:329,3341991/0303/sys/src/9/power/devhotrod.c:369,375
1991/0212    
			mp->cmd = WRITE; 
			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); 
			qunlock(hp); 
			qunlock(&hp->buflock); 
1991/0302/sys/src/9/power/devhotrod.c:364,3671991/0303/sys/src/9/power/devhotrod.c:405,498
1990/1013    
		return; 
	} 
1991/0219    
	hp->addr->lcsr3 &= ~INT_VME; 
1991/0303    
} 
 
void 
mem(Hot *hot, ulong *buf, ulong size) 
{ 
	long i, j, k, l; 
	ulong *p, bit, u; 
	int q; 
 
goto part4; 
	/* one bit */ 
	bit = 0; 
	p = buf; 
	for(i=0; i<size; i++,p++) { 
		if(bit == 0) 
			bit = 1; 
		*p = bit; 
		bit <<= 1; 
	} 
	bit = 0; 
	p = buf; 
	for(i=0; i<size; i++,p++) { 
		if(bit == 0) 
			bit = 1; 
		if(*p != bit) { 
			print("A: %lux is %lux sb %lux\n", p, *p, bit); 
			hot->error++; 
			delay(500); 
		} 
		bit <<= 1; 
	} 
	/* all but one bit */ 
	bit = 0; 
	p = buf; 
	for(i=0; i<size; i++,p++) { 
		if(bit == 0) 
			bit = 1; 
		*p = ~bit; 
		bit <<= 1; 
	} 
	bit = 0; 
	p = buf; 
	for(i=0; i<size; i++,p++) { 
		if(bit == 0) 
			bit = 1; 
		if(*p != ~bit) { 
			print("B: %lux is %lux sb %lux\n", p, *p, ~bit); 
			hot->error++; 
			delay(500); 
		} 
		bit <<= 1; 
	} 
	/* rand bit */ 
	bit = 0; 
	p = buf; 
	for(i=0; i<size; i++,p++) { 
		if(bit == 0) 
			bit = 1; 
		*p = bit; 
		bit += PRIME; 
	} 
	bit = 0; 
	p = buf; 
	for(i=0; i<size; i++,p++) { 
		if(bit == 0) 
			bit = 1; 
		if(*p != bit) { 
			print("C: %lux is %lux sb %lux\n", p, *p, bit); 
			hot->error++; 
			delay(500); 
		} 
		bit += PRIME; 
	} 
part4: 
	/* address */ 
	p = buf; 
	for(i=0; i<size; i++,p++) 
		*p = i; 
	for(j=0; j<200; j++) { 
		p = buf; 
		for(i=0; i<size; i++,p++) { 
			u = *p; 
			if(u != i+j) { 
				print("D: %lux is %lux sb %lux (%lux)\n", p, u, i+j, *p); 
			hot->error++; 
				delay(500); 
			} 
			*p = i+j+1; 
		} 
	} 
1990/1013    
} 
1991/0303/sys/src/9/power/devhotrod.c:15,211991/0304/sys/src/9/power/devhotrod.c:15,21 (short | long)
1991/0303    
/* 
 * If set, causes data transfers to have checksums 
 */ 
#define	ENABCKSUM	1 
1991/0304    
#define	ENABCKSUM	0 
1991/0303    
 
1990/1013    
typedef struct Hotrod	Hotrod; 
1991/0209    
typedef struct HotQ	HotQ; 
1991/0303/sys/src/9/power/devhotrod.c:70,841991/0304/sys/src/9/power/devhotrod.c:70,92
1991/0209    
void 
hotsend(Hotrod *h, Hotmsg *m) 
1990/1013    
{ 
1991/0304    
	Hotmsg **mp; 
	long l; 
 
1991/0220    
/* print("hotsend send %d %d %lux %lux\n", h->wi, m->cmd, m, m->param[0]); /**/ 
1991/0212    
	h->wq->msg[h->wi] = (Hotmsg*)MP2VME(m); 
1991/0215    
	do 
		delay(1); 
	while(h->wq->msg[h->wi]); 
1991/0220    
/* print("hotsend done\n"); /**/ 
1991/0304    
	mp = &h->wq->msg[h->wi]; 
	*mp = (Hotmsg*)MP2VME(m); 
1991/0209    
	h->wi++; 
	if(h->wi >= NhotQ) 
		h->wi = 0; 
1991/0304    
	l = 0; 
	while(*mp){ 
		delay(0);	/* just a subroutine call; stay off VME */ 
		if(++l > 1000*1000){ 
			l = 0; 
			print("hotsend blocked\n"); 
		} 
	} 
1990/1013    
} 
 
/* 
1991/0303/sys/src/9/power/devhotrod.c:360,3661991/0304/sys/src/9/power/devhotrod.c:368,374
1991/0212    
			qunlock(hp); 
		}else{ 
			/* 
			 *  use hotrod buffer.  lock the buffer till the reply 
1991/0304    
			 *  use hotrod buffer.  lock the buffer until the reply 
1991/0212    
			 */ 
			mp = &u->uhot; 
			qlock(&hp->buflock); 
1991/0304/sys/src/9/power/devhotrod.c:10,411991/0306/sys/src/9/power/devhotrod.c:10,37 (short | long)
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 
1991/0306/sys/src/9/power/devhotrod.c:11,241991/0307/sys/src/9/power/devhotrod.c:11,26 (short | long)
1991/0215    
#include	"hrod.h" 
1990/1013    
 
1991/0306    
/* 
 * If defined, causes memory test to be run at device open 
1991/0307    
 * If defined, ENABMEMTEST causes memory test to be run at device open 
1991/0306    
 */ 
#ifdef	ENABMEMTEST 
1991/0303    
void	mem(Hot*, ulong*, ulong); 
1991/0307    
#define	NTESTBUF	256 
ulong	testbuf[NTESTBUF]; 
1991/0306    
#endif 
1991/0303    
 
/* 
 * If set, causes data transfers to have checksums 
1991/0307    
 * If 1, ENABCKSUM causes data transfers to have checksums 
1991/0303    
 */ 
1991/0306    
#define	ENABCKSUM	1 
1991/0303    
 
1991/0306/sys/src/9/power/devhotrod.c:32,371991/0307/sys/src/9/power/devhotrod.c:34,45
1991/0209    
	Nhotrod=	1, 
1990/1013    
}; 
 
1991/0307    
Dirtab hotroddir[]={ 
	"hotrod",	{Qhotrod},	0,	0600, 
}; 
 
#define	NHOTRODDIR	(sizeof hotroddir/sizeof(Dirtab)) 
 
1991/0209    
struct Hotrod{ 
	QLock; 
1991/0212    
	QLock		buflock; 
1991/0306/sys/src/9/power/devhotrod.c:53,661991/0307/sys/src/9/power/devhotrod.c:61,66
1991/0209    
/* 
 * Commands 
 */ 
enum{ 
	RESET=	0,	/* params: Q address, length of queue */ 
	REBOOT=	1,	/* params: none */ 
1991/0303    
	READ=	2,	/* params: buffer, count, sum, returned count */ 
	WRITE=	3,	/* params: buffer, count, sum */ 
1991/0214    
	TEST=	7,	/* params: none */ 
1991/0209    
}; 
                 
void 
hotsend(Hotrod *h, Hotmsg *m) 
1990/1013    
{ 
1991/0306/sys/src/9/power/devhotrod.c:100,1071991/0307/sys/src/9/power/devhotrod.c:100,105
1991/0209    
		hp->vec = Vmevec+i; 
		setvmevec(hp->vec, hotrodintr); 
1990/1013    
	}	 
	wbflush(); 
	delay(20); 
} 
 
void 
1991/0306/sys/src/9/power/devhotrod.c:139,1631991/0307/sys/src/9/power/devhotrod.c:137,151
1990/1013    
int	  
hotrodwalk(Chan *c, char *name) 
{ 
1991/0209    
	if(c->qid.path != CHDIR) 
		return 0; 
	if(strncmp(name, "hotrod", 6) == 0){ 
		c->qid.path = Qhotrod; 
		return 1; 
	} 
	return 0; 
1991/0307    
	return devwalk(c, name, hotroddir, NHOTRODDIR, devgen); 
1990/1013    
} 
 
void	  
hotrodstat(Chan *c, char *dp) 
{ 
1991/0209    
	print("hotrodstat\n"); 
	error(Egreg); 
1991/0307    
	devstat(c, dp, hotroddir, NHOTRODDIR, devgen); 
1990/1013    
} 
 
1991/0227    
#define	NTESTBUF	256 
ulong	testbuf[NTESTBUF]; 
                 
1990/1013    
Chan* 
hotrodopen(Chan *c, int omode) 
{ 
1991/0306/sys/src/9/power/devhotrod.c:183,1891991/0307/sys/src/9/power/devhotrod.c:171,177
1991/0209    
		hp->wi = 0; 
		hp->ri = 0; 
1991/0212    
		mp = &u->khot; 
		mp->cmd = RESET; 
1991/0307    
		mp->cmd = Ureset; 
1991/0306    
		mp->param[0] = MP2VME(hp->rq); 
		mp->param[1] = NRQ; 
1991/0209    
		hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot); 
1991/0306/sys/src/9/power/devhotrod.c:195,2011991/0307/sys/src/9/power/devhotrod.c:183,189
1991/0219    
		 * Issue test 
		 */ 
		mp = &u->khot; 
		mp->cmd = TEST; 
1991/0307    
		mp->cmd = Utest; 
1991/0227    
		mp->param[0] = MP2VME(testbuf); 
		mp->param[1] = NTESTBUF; 
1991/0219    
		hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot); 
1991/0306/sys/src/9/power/devhotrod.c:226,2321991/0307/sys/src/9/power/devhotrod.c:214,220
1991/0209    
 
	hp = &hotrod[c->dev]; 
	if(c->qid.path != CHDIR){ 
		u->khot.cmd = REBOOT; 
1991/0307    
		u->khot.cmd = Ureboot; 
1991/0209    
		hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot); 
		unlock(&hp->busy); 
	} 
1991/0306/sys/src/9/power/devhotrod.c:266,2721991/0307/sys/src/9/power/devhotrod.c:254,263
1991/0306    
	ulong l, m, isflush; 
1990/1013    
 
	hp = &hotrod[c->dev]; 
1991/0212    
	switch(c->qid.path){ 
1991/0307    
	switch(c->qid.path & ~CHDIR){ 
	case Qdir: 
		return devdirread(c, buf, n, hotroddir, NHOTRODDIR, devgen); 
 
1991/0212    
	case Qhotrod: 
1991/0220    
		if(n > sizeof hp->buf){ 
			print("hotrod bufsize\n"); 
1991/0306/sys/src/9/power/devhotrod.c:282,2911991/0307/sys/src/9/power/devhotrod.c:273,282
1991/0306    
				mp = &((User*)(u->p->upage->pa|KZERO))->fhot; 
				isflush = 1; 
			} 
1991/0303    
			mp->param[2] = 0;	/* checksum */ 
1991/0307    
			mp->param[2] = 0;	/* reply checksum */ 
1991/0303    
			mp->param[3] = 0;	/* reply count */ 
1991/0212    
			qlock(hp); 
			mp->cmd = READ; 
1991/0307    
			mp->cmd = Uread; 
1991/0212    
			mp->param[0] = MP2VME(buf); 
			mp->param[1] = n; 
1991/0306    
			mp->abort = isflush; 
1991/0306/sys/src/9/power/devhotrod.c:310,3171991/0307/sys/src/9/power/devhotrod.c:301,310
1991/0215    
				error(Egreg); 
			} 
1991/0303    
			if(mp->param[2] != hotsum(buf, m, mp->param[2])){ 
1991/0307    
				hp->addr->error++; 
1991/0303    
				print("hotrod cksum err is %lux sb %lux\n", 
					hotsum(buf, n, 1), mp->param[2]); 
1991/0307    
{int i; for(i=0; i<8; i++) print("%lux\n", ((ulong*)buf)[i]); } 
1991/0303    
				error(Eio); 
			} 
1991/0306    
			if(!isflush) 
1991/0306/sys/src/9/power/devhotrod.c:321,3311991/0307/sys/src/9/power/devhotrod.c:314,324
1991/0306    
			 * use hotrod buffer. lock the buffer until the reply 
1991/0212    
			 */ 
1991/0306    
			mp = &((User*)(u->p->upage->pa|KZERO))->uhot; 
1991/0303    
			mp->param[2] = 0;	/* checksum */ 
1991/0307    
			mp->param[2] = 0;	/* reply checksum */ 
1991/0303    
			mp->param[3] = 0;	/* reply count */ 
1991/0212    
			qlock(&hp->buflock); 
			qlock(hp); 
			mp->cmd = READ; 
1991/0307    
			mp->cmd = Uread; 
1991/0212    
			mp->param[0] = MP2VME(hp->buf); 
			mp->param[1] = n; 
1991/0306    
			mp->abort = 1; 
1991/0306/sys/src/9/power/devhotrod.c:342,3501991/0307/sys/src/9/power/devhotrod.c:335,345
1991/0215    
				error(Egreg); 
			} 
1991/0303    
			if(mp->param[2] != hotsum((ulong*)hp->buf, m, mp->param[2])){ 
1991/0307    
				hp->addr->error++; 
1991/0303    
				print("hotrod cksum err is %lux sb %lux\n", 
					hotsum((ulong*)hp->buf, n, 1), mp->param[2]); 
				qunlock(&hp->buflock); 
1991/0307    
{int i; for(i=0; i<8; i++) print("%lux\n", ((ulong*)buf)[i]); } 
1991/0303    
				error(Eio); 
			} 
			memcpy(buf, hp->buf, m); 
1991/0306/sys/src/9/power/devhotrod.c:364,3711991/0307/sys/src/9/power/devhotrod.c:359,369
1991/0212    
	Hotmsg *mp; 
1990/1013    
 
	hp = &hotrod[c->dev]; 
1991/0212    
	switch(c->qid.path){ 
	case 1: 
1991/0307    
	switch(c->qid.path & ~CHDIR){ 
	case Qdir: 
		return devdirread(c, buf, n, hotroddir, NHOTRODDIR, devgen); 
 
	case Qhotrod: 
1991/0220    
		if(n > sizeof hp->buf){ 
			print("hotrod write bufsize\n"); 
1991/0212    
			error(Egreg); 
1991/0306/sys/src/9/power/devhotrod.c:378,3841991/0307/sys/src/9/power/devhotrod.c:376,382
1991/0306    
			if(mp->abort)	/* use reserved flush msg */ 
				mp = &((User*)(u->p->upage->pa|KZERO))->fhot; 
1991/0212    
			qlock(hp); 
			mp->cmd = WRITE; 
1991/0307    
			mp->cmd = Uwrite; 
1991/0212    
			mp->param[0] = MP2VME(buf); 
			mp->param[1] = n; 
1991/0303    
			mp->param[2] = hotsum(buf, n, ENABCKSUM); 
1991/0306/sys/src/9/power/devhotrod.c:392,3981991/0307/sys/src/9/power/devhotrod.c:390,396
1991/0212    
			qlock(&hp->buflock); 
			qlock(hp); 
			memcpy(hp->buf, buf, n); 
			mp->cmd = WRITE; 
1991/0307    
			mp->cmd = Uwrite; 
1991/0212    
			mp->param[0] = MP2VME(hp->buf); 
			mp->param[1] = n; 
1991/0303    
			mp->param[2] = hotsum((ulong*)hp->buf, n, ENABCKSUM); 
1991/0307/sys/src/9/power/devhotrod.c:13,181991/0316/sys/src/9/power/devhotrod.c:13,19 (short | long)
1991/0306    
/* 
1991/0307    
 * If defined, ENABMEMTEST causes memory test to be run at device open 
1991/0306    
 */ 
1991/0316    
#define	ENABMEMTEST 
1991/0306    
#ifdef	ENABMEMTEST 
1991/0303    
void	mem(Hot*, ulong*, ulong); 
1991/0307    
#define	NTESTBUF	256 
1991/0316/sys/src/9/power/devhotrod.c:13,191991/0317/sys/src/9/power/devhotrod.c:13,18 (short | long)
1991/0306    
/* 
1991/0307    
 * If defined, ENABMEMTEST causes memory test to be run at device open 
1991/0306    
 */ 
1991/0316    
#define	ENABMEMTEST 
1991/0306    
#ifdef	ENABMEMTEST 
1991/0303    
void	mem(Hot*, ulong*, ulong); 
1991/0307    
#define	NTESTBUF	256 
1991/0317/sys/src/9/power/devhotrod.c:342,3481991/0318/sys/src/9/power/devhotrod.c:342,348 (short | long)
1991/0307    
{int i; for(i=0; i<8; i++) print("%lux\n", ((ulong*)buf)[i]); } 
1991/0303    
				error(Eio); 
			} 
			memcpy(buf, hp->buf, m); 
1991/0318    
			memmove(buf, hp->buf, m); 
1991/0303    
			qunlock(&hp->buflock); 
1991/0212    
		} 
1991/0303    
		return m; 
1991/0317/sys/src/9/power/devhotrod.c:389,3951991/0318/sys/src/9/power/devhotrod.c:389,395
1991/0306    
			mp = &((User*)(u->p->upage->pa|KZERO))->uhot; 
1991/0212    
			qlock(&hp->buflock); 
			qlock(hp); 
			memcpy(hp->buf, buf, n); 
1991/0318    
			memmove(hp->buf, buf, n); 
1991/0307    
			mp->cmd = Uwrite; 
1991/0212    
			mp->param[0] = MP2VME(hp->buf); 
			mp->param[1] = n; 
1991/0318/sys/src/9/power/devhotrod.c:422,4431991/0326/sys/src/9/power/devhotrod.c:422,447 (short | long)
1990/1013    
{ 
1991/0306    
	Hotrod *h; 
	Hotmsg *hm; 
1991/0326    
	ulong l; 
1990/1013    
 
1991/0306    
	h = &hotrod[vec - Vmevec]; 
	if(h < hotrod || h > &hotrod[Nhotrod]){ 
1991/0326    
	if(h<hotrod || h>&hotrod[Nhotrod]){ 
1990/1013    
		print("bad hotrod vec\n"); 
		return; 
	} 
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/0326    
	while(l = h->rq[h->ri]){	/* assign = */ 
		hm = (Hotmsg*)(VME2MP(l)); 
		h->rq[h->ri] = 0; 
		h->ri++; 
		if(h->ri >= NRQ) 
			h->ri = 0; 
		hm->intr = 1; 
		if(hm->abort) 
			print("abort wakeup\n"); 
		else 
			wakeup(&hm->r); 
	} 
1991/0303    
} 
 
1991/0306    
#ifdef	ENABMEMTEST 
1991/0326/sys/src/9/power/devhotrod.c:18,231991/0328/sys/src/9/power/devhotrod.c:18,27 (short | long)
1991/0307    
#define	NTESTBUF	256 
ulong	testbuf[NTESTBUF]; 
1991/0306    
#endif 
1991/0328    
/* 
 * If defined, ENABBUSTEST causes bus error diagnostic to be run at device open 
 */ 
#define	ENABBUSTEST 
1991/0303    
 
/* 
1991/0307    
 * If 1, ENABCKSUM causes data transfers to have checksums 
1991/0326/sys/src/9/power/devhotrod.c:193,1981991/0328/sys/src/9/power/devhotrod.c:197,210
1991/0303    
			print("-"); 
			mem(hp->addr, &hp->addr->ram[(mp->param[0]-0x40000)/sizeof(ulong)], mp->param[1]); 
		} 
1991/0328    
#endif 
#ifdef ENABBUSTEST 
		/* 
		 * Issue test 
		 */ 
		mp = &u->khot; 
		mp->cmd = Ubus; 
		hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot); 
1991/0302    
#endif 
1990/1018    
	} 
1990/1013    
	c->mode = openmode(omode); 
1991/0328/sys/src/9/power/devhotrod.c:13,181991/0329/sys/src/9/power/devhotrod.c:13,19 (short | long)
1991/0306    
/* 
1991/0307    
 * If defined, ENABMEMTEST causes memory test to be run at device open 
1991/0306    
 */ 
1991/0329    
#define	ENABMEMTEST 
1991/0306    
#ifdef	ENABMEMTEST 
1991/0303    
void	mem(Hot*, ulong*, ulong); 
1991/0307    
#define	NTESTBUF	256 
1991/0328/sys/src/9/power/devhotrod.c:21,271991/0329/sys/src/9/power/devhotrod.c:22,27
1991/0328    
/* 
 * If defined, ENABBUSTEST causes bus error diagnostic to be run at device open 
 */ 
#define	ENABBUSTEST 
1991/0303    
 
/* 
1991/0307    
 * If 1, ENABCKSUM causes data transfers to have checksums 
1991/0329/sys/src/9/power/devhotrod.c:13,191991/0331/sys/src/9/power/devhotrod.c:13,18 (short | long)
1991/0306    
/* 
1991/0307    
 * If defined, ENABMEMTEST causes memory test to be run at device open 
1991/0306    
 */ 
1991/0329    
#define	ENABMEMTEST 
1991/0306    
#ifdef	ENABMEMTEST 
1991/0303    
void	mem(Hot*, ulong*, ulong); 
1991/0307    
#define	NTESTBUF	256 
1991/0329/sys/src/9/power/devhotrod.c:26,321991/0331/sys/src/9/power/devhotrod.c:25,31
1991/0303    
/* 
1991/0307    
 * If 1, ENABCKSUM causes data transfers to have checksums 
1991/0303    
 */ 
1991/0306    
#define	ENABCKSUM	1 
1991/0331    
#define	ENABCKSUM	0 
1991/0303    
 
1990/1013    
typedef struct Hotrod	Hotrod; 
 
Too many diffs (26 > 25). Stopping.


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