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

1991/0318/power/devbit3.c (diff list | history)

1991/0318/sys/src/9/power/devbit3.c:1,2181991/0411/sys/src/9/power/devbit3.c:1,218 (short | long | prev | next)
1990/0324    
#include	"u.h" 
#include	"lib.h" 
#include	"mem.h" 
#include	"dat.h" 
#include	"fns.h" 
#include	"errno.h" 
#include	"devtab.h" 
 
#include	"io.h" 
 
static struct 
{ 
	QLock; 
1990/06061    
	QLock	buflock; 
1990/0324    
	int	open; 
	char	buf[10*1024]; 
}bit3; 
 
#define	BIT3ADDR	((Bit3msg**)(KZERO+0x7C)) 
#define	BIT3HOLD	((ulong*)(KZERO+0x78)) 
#define	BIT3INTR	((char*)(UNCACHED|0x17c12001)) 
 
enum 
{ 
	RESET, 
	READ, 
	WRITE, 
}; 
 
void 
bit3send(Bit3msg *bp, ulong cmd, void *addr, ulong count) 
{ 
	do; while(*BIT3ADDR); 
	bp->cmd = cmd; 
	bp->addr = (ulong)addr; 
	bp->count = count; 
	*BIT3ADDR = bp; 
	wbflush(); 
	do; while(*BIT3HOLD); 
	*BIT3INTR = 0x20; 
} 
 
void 
bit3reset(void) 
{ 
	*BIT3HOLD = 0; 
	*BIT3ADDR = 0; 
	qlock(&bit3); 
	qunlock(&bit3); 
} 
 
void 
bit3init(void) 
{ 
} 
 
Chan* 
bit3attach(char *spec) 
{ 
	return devattach('3', spec); 
} 
 
Chan* 
bit3clone(Chan *c, Chan *nc) 
{ 
	return devclone(c, nc); 
} 
 
int	  
bit3walk(Chan *c, char *name) 
{ 
1990/11211    
	if(c->qid.path != CHDIR) 
1990/0324    
		return 0; 
	if(strcmp(name, "bit3") == 0){ 
1990/11211    
		c->qid.path = 1; 
1990/0324    
		return 1; 
	} 
	return 0; 
} 
 
void	  
bit3stat(Chan *c, char *dp) 
{ 
	print("bit3stat\n"); 
1990/11211    
	error(Egreg); 
1990/0324    
} 
 
Chan* 
bit3open(Chan *c, int omode) 
{ 
	Bit3msg *bp; 
 
1990/0608    
	bp = &((User*)(u->p->upage->pa|KZERO))->kbit3; 
1990/11211    
	if(c->qid.path!=1 || omode!=ORDWR) 
		error(Eperm); 
1990/0324    
	qlock(&bit3); 
	if(bit3.open){ 
		qunlock(&bit3); 
1990/11211    
		error(Einuse); 
1990/0324    
	} 
	bit3send(bp, RESET, 0, 0); 
	bit3.open = 1; 
	qunlock(&bit3); 
	c->mode = openmode(omode); 
	c->flag |= COPEN; 
	c->offset = 0; 
	return c; 
} 
 
void	  
bit3create(Chan *c, char *name, int omode, ulong perm) 
{ 
1990/11211    
	error(Eperm); 
1990/0324    
} 
 
void	  
bit3close(Chan *c) 
{ 
	qlock(&bit3); 
	bit3.open = 0; 
	qunlock(&bit3); 
} 
 
/* 
 * 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.  The only killer is that 
 * DMA counts from the bit3 device are mod 256, so devmnt must use oversize 
 * buffers. 
 */ 
 
long	  
bit3read(Chan *c, void *buf, long n) 
1991/0411    
bit3read(Chan *c, void *buf, long n, ulong offset) 
1990/0324    
{ 
	Bit3msg *bp; 
	int docpy; 
 
1990/11211    
	switch(c->qid.path){ 
1990/0324    
	case 1: 
		if(n > sizeof bit3.buf) 
1990/11211    
			error(Egreg); 
1990/06061    
		if((((ulong)buf)&(KSEGM|3)) == KSEG0){ 
			/* 
			 *  use supplied buffer, no need to lock for reply 
			 */ 
1990/0608    
			bp = &((User*)(u->p->upage->pa|KZERO))->kbit3; 
			bp->rcount = 0; 
1990/06061    
			qlock(&bit3); 
1990/0324    
			bit3send(bp, READ, buf, n); 
1990/06061    
			qunlock(&bit3); 
			do 
				n = bp->rcount; 
			while(n == 0); 
		}else{ 
			/* 
			 *  use bit3 buffer.  lock the buffer till the reply 
			 */ 
1990/0608    
			bp = &((User*)(u->p->upage->pa|KZERO))->ubit3; 
			bp->rcount = 0; 
1990/06061    
			qlock(&bit3.buflock); 
			qlock(&bit3); 
1990/0324    
			bit3send(bp, READ, bit3.buf, n); 
1990/06061    
			qunlock(&bit3); 
			do 
				n = bp->rcount; 
			while(n == 0); 
1991/0318    
			memmove(buf, bit3.buf, n); 
1990/06061    
			qunlock(&bit3.buflock); 
		} 
1990/0324    
		return n; 
	} 
1990/11211    
	error(Egreg); 
1990/0324    
	return 0; 
} 
 
long	  
bit3write(Chan *c, void *buf, long n) 
1991/0411    
bit3write(Chan *c, void *buf, long n, ulong offset) 
1990/0324    
{ 
	Bit3msg *bp; 
 
1990/11211    
	switch(c->qid.path){ 
1990/0324    
	case 1: 
		if(n > sizeof bit3.buf) 
1990/11211    
			error(Egreg); 
1990/06061    
		if((((ulong)buf)&(KSEGM|3)) == KSEG0){ 
1990/0608    
			bp = &((User*)(u->p->upage->pa|KZERO))->kbit3; 
1990/06061    
			qlock(&bit3); 
1990/0324    
			bit3send(bp, WRITE, buf, n); 
1990/06061    
			qunlock(&bit3); 
		}else{ 
1990/0608    
			bp = &((User*)(u->p->upage->pa|KZERO))->ubit3; 
1990/06061    
			qlock(&bit3.buflock); 
1990/0608    
 
1990/06061    
			qlock(&bit3); 
1991/0318    
			memmove(bit3.buf, buf, n); 
1990/0324    
			bit3send(bp, WRITE, bit3.buf, n); 
1990/0608    
			do; while(*BIT3ADDR); 
1990/06061    
			qunlock(&bit3); 
1990/0608    
 
1990/06061    
			qunlock(&bit3.buflock); 
1990/0324    
		} 
		return n; 
	} 
1990/11211    
	error(Egreg); 
1990/0324    
	return 0; 
} 
 
void	  
bit3remove(Chan *c) 
{ 
1990/11211    
	error(Eperm); 
1990/0324    
} 
 
void	  
bit3wstat(Chan *c, char *dp) 
{ 
1990/11211    
	error(Eperm); 
1990/0324    
} 


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