⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 devi82365.c

📁 著名操作系统Plan 9的第三版的部分核心源代码。现在很难找到了。Plan 9是bell实验室开发的Unix后继者。
💻 C
📖 第 1 页 / 共 2 页
字号:
			*to++ = *from++;	} else {		n = n/2;		t = (ushort*)to;		f = (ushort*)from;		while(n-- > 0)			*t++ = *f++;	}}static longpcmread(int slotno, int attr, void *a, long n, vlong off){	int i, len;	PCMmap *m;	uchar *ac;	Slot *pp;	ulong offset = off;	pp = slot + slotno;	if(pp->memlen < offset)		return 0;	if(pp->memlen < offset + n)		n = pp->memlen - offset;	m = 0;	if(waserror()){		if(m)			pcmunmap(pp->slotno, m);		nexterror();	}	ac = a;	for(len = n; len > 0; len -= i){		m = pcmmap(pp->slotno, offset, 0, attr);		if(m == 0)			error("can't map PCMCIA card");		if(offset + len > m->cea)			i = m->cea - offset;		else			i = len;		memmoveb(ac, KADDR(m->isa + offset - m->ca), i);		pcmunmap(pp->slotno, m);		offset += i;		ac += i;	}	poperror();	return n;}static longi82365read(Chan *c, void *a, long n, vlong off){	char *p;	int len;	Slot *pp;	ulong offset = off;	switch(TYPE(c)){	case Qdir:		return devdirread(c, a, n, 0, 0, pcmgen);	case Qmem:	case Qattr:		return pcmread(SLOTNO(c), TYPE(c) == Qattr, a, n, off);	case Qctl:		p = malloc(READSTR);		len = 0;		pp = slot + SLOTNO(c);		if(pp->occupied)			len += snprint(p+len, READSTR-len, "occupied\n");		if(pp->enabled)			len += snprint(p+len, READSTR-len, "enabled\n");		if(pp->powered)			len += snprint(p+len, READSTR-len, "powered\n");		if(pp->configed)			len += snprint(p+len, READSTR-len, "configed\n");		if(pp->wrprot)			len += snprint(p+len, READSTR-len, "write protected\n");		if(pp->busy)			len += snprint(p+len, READSTR-len, "busy\n");		snprint(p+len, READSTR-len, "battery lvl %d\n", pp->battery);		n = readstr(offset, a, n, p);		free(p);		return n;	}	error(Ebadarg);	return -1;	/* not reached */}static longpcmwrite(int dev, int attr, void *a, long n, vlong off){	int i, len;	PCMmap *m;	uchar *ac;	Slot *pp;	ulong offset = off;	pp = slot + dev;	if(pp->memlen < offset)		return 0;	if(pp->memlen < offset + n)		n = pp->memlen - offset;	m = 0;	if(waserror()){		if(m)			pcmunmap(pp->slotno, m);		nexterror();	}	ac = a;	for(len = n; len > 0; len -= i){		m = pcmmap(pp->slotno, offset, 0, attr);		if(m == 0)			error("can't map PCMCIA card");		if(offset + len > m->cea)			i = m->cea - offset;		else			i = len;		memmoveb(KADDR(m->isa + offset - m->ca), ac, i);		pcmunmap(pp->slotno, m);		offset += i;		ac += i;	}	poperror();	return n;}static longi82365write(Chan *c, void *a, long n, vlong off){	Slot *pp;	char buf[32];	switch(TYPE(c)){	case Qctl:		if(n >= sizeof(buf))			n = sizeof(buf) - 1;		strncpy(buf, a, n);		buf[n] = 0;		pp = slot + SLOTNO(c);		if(!pp->occupied)			error(Eio);		/* set vpp on card */		if(strncmp(buf, "vpp", 3) == 0)			wrreg(pp, Rpc, vcode(atoi(buf+3))|Fautopower|Foutena|Fcardena);		return n;	case Qmem:	case Qattr:		pp = slot + SLOTNO(c);		if(pp->occupied == 0 || pp->enabled == 0)			error(Eio);		n = pcmwrite(pp->slotno, TYPE(c) == Qattr, a, n, off);		if(n < 0)			error(Eio);		return n;	}	error(Ebadarg);	return -1;	/* not reached */}Dev i82365devtab = {	'y',	"i82365",	i82365reset,	devinit,	i82365attach,	devclone,	i82365walk,	i82365stat,	i82365open,	devcreate,	i82365close,	i82365read,	devbread,	i82365write,	devbwrite,	devremove,	devwstat,};/* *  configure the Slot for IO.  We assume very heavily that we can read *  configuration info from the CIS.  If not, we won't set up correctly. */static intpcmio(int slotno, ISAConf *isa){	uchar we, x, *p;	Slot *pp;	Conftab *ct, *et, *t;	PCMmap *m;	int i, index, irq;	char *cp;	irq = isa->irq;	if(irq == 2)		irq = 9;	if(slotno > nslot)		return -1;	pp = slot + slotno;	if(!pp->occupied)		return -1;	et = &pp->ctab[pp->nctab];	ct = 0;	for(i = 0; i < isa->nopt; i++){		if(strncmp(isa->opt[i], "index=", 6))			continue;		index = strtol(&isa->opt[i][6], &cp, 0);		if(cp == &isa->opt[i][6] || index >= pp->nctab)			return -1;		ct = &pp->ctab[index];	}	if(ct == 0){			/* assume default is right */		if(pp->def)			ct = pp->def;		else			ct = pp->ctab;			/* try for best match */		if(ct->nio == 0		|| ct->io[0].start != isa->port || ((1<<irq) & ct->irqs) == 0){			for(t = pp->ctab; t < et; t++)				if(t->nio				&& t->io[0].start == isa->port				&& ((1<<irq) & t->irqs)){					ct = t;					break;				}		}		if(ct->nio == 0 || ((1<<irq) & ct->irqs) == 0){			for(t = pp->ctab; t < et; t++)				if(t->nio && ((1<<irq) & t->irqs)){					ct = t;					break;				}		}		if(ct->nio == 0){			for(t = pp->ctab; t < et; t++)				if(t->nio){					ct = t;					break;				}		}	}	if(ct == et || ct->nio == 0)		return -1;	if(isa->port == 0 && ct->io[0].start == 0)		return -1;	/* route interrupts */	isa->irq = irq;	wrreg(pp, Rigc, irq | Fnotreset | Fiocard);		/* set power and enable device */	x = vcode(ct->vpp1);	wrreg(pp, Rpc, x|Fautopower|Foutena|Fcardena);	/* 16-bit data path */	if(ct->bit16)		x = Ftiming|Fiocs16|Fwidth16;	else		x = Ftiming;	if(ct->nio == 2 && ct->io[1].start)		x |= x<<4;	wrreg(pp, Rio, x);	/* enable io port map 0 */	if(isa->port == 0)		isa->port = ct->io[0].start;	we = rdreg(pp, Rwe);	wrreg(pp, Riobtm0lo, isa->port);	wrreg(pp, Riobtm0hi, isa->port>>8);	i = isa->port+ct->io[0].len-1;	wrreg(pp, Riotop0lo, i);	wrreg(pp, Riotop0hi, i>>8);	we |= 1<<6;	if(ct->nio == 2 && ct->io[1].start){		wrreg(pp, Riobtm1lo, ct->io[1].start);		wrreg(pp, Riobtm1hi, ct->io[1].start>>8);		i = ct->io[1].start+ct->io[1].len-1;		wrreg(pp, Riotop1lo, i);		wrreg(pp, Riotop1hi, i>>8);		we |= 1<<7;	}	wrreg(pp, Rwe, we);	/* only touch Rconfig if it is present */	if(pp->cpresent & (1<<Rconfig)){		/*  Reset adapter */		m = pcmmap(slotno, pp->caddr + Rconfig, 1, 1);		p = KADDR(m->isa + pp->caddr + Rconfig - m->ca);		/* set configuration and interrupt type */		x = ct->index;		if((ct->irqtype & 0x20) && ((ct->irqtype & 0x40)==0 || isa->irq>7))			x |= Clevel;		*p = x;		delay(5);		pcmunmap(slotno, m);	}	return 0;}/* *  read and crack the card information structure enough to set *  important parameters like power */static void	tcfig(Slot*, Cisdat*, int);static void	tentry(Slot*, Cisdat*, int);static void	tvers1(Slot*, Cisdat*, int);struct {	int n;	void (*parse)(Slot*, Cisdat*, int);} cistab[] = {	0x15, tvers1,	0x1A, tcfig,	0x1B, tentry,};static intreadc(Cisdat *pp, uchar *x){	if(pp->cispos >= pp->cislen)		return 0;	*x = pp->cisbase[pp->cisskip*pp->cispos];	pp->cispos++;	return 1;}static intxcistuple(int slotno, int tuple, void *v, int nv, int attr){	PCMmap *m;	Cisdat cis;	int i, l;	uchar *p;	uchar type, link;	int this;	m = pcmmap(slotno, 0, 0, attr);	if(m == 0)		return -1;	cis.cisbase = KADDR(m->isa);	cis.cispos = 0;	cis.cisskip = attr ? 2 : 1;	cis.cislen = Mchunk;	/* loop through all the tuples */	for(i = 0; i < 1000; i++){		this = cis.cispos;		if(readc(&cis, &type) != 1)			break;		if(type == 0xFF)			break;		if(readc(&cis, &link) != 1)			break;		if(link == 0xFF)			break;		if(type == tuple) {			p = v;			for(l=0; l<nv && l<link; l++)				if(readc(&cis, p++) != 1)					break;			pcmunmap(slotno, m);			return nv;		}		cis.cispos = this + (2+link);	}	pcmunmap(slotno, m);	return -1;}intpcmcistuple(int slotno, int tuple, void *v, int nv){	int n;	/* try attribute space, then memory */	if((n = xcistuple(slotno, tuple, v, nv, 1)) >= 0)		return n;	return xcistuple(slotno, tuple, v, nv, 0);}static voidcisread(Slot *pp){	uchar v[256];	int i, nv;	Cisdat cis;	memset(pp->ctab, 0, sizeof(pp->ctab));	pp->caddr = 0;	pp->cpresent = 0;	pp->configed = 0;	pp->nctab = 0;	for(i = 0; i < nelem(cistab); i++) {		if((nv = pcmcistuple(pp->slotno, cistab[i].n, v, sizeof(v))) >= 0) {			cis.cisbase = v;			cis.cispos = 0;			cis.cisskip = 1;			cis.cislen = nv;						(*cistab[i].parse)(pp, &cis, cistab[i].n);		}	}}static ulonggetlong(Cisdat *cis, int size){	uchar c;	int i;	ulong x;	x = 0;	for(i = 0; i < size; i++){		if(readc(cis, &c) != 1)			break;		x |= c<<(i*8);	}	return x;}static voidtcfig(Slot *pp, Cisdat *cis, int ){	uchar size, rasize, rmsize;	uchar last;	if(readc(cis, &size) != 1)		return;	rasize = (size&0x3) + 1;	rmsize = ((size>>2)&0xf) + 1;	if(readc(cis, &last) != 1)		return;	pp->caddr = getlong(cis, rasize);	pp->cpresent = getlong(cis, rmsize);}static ulong vexp[8] ={	1, 10, 100, 1000, 10000, 100000, 1000000, 10000000};static ulong vmant[16] ={	10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80, 90,};static ulongmicrovolt(Cisdat *cis){	uchar c;	ulong microvolts;	ulong exp;	if(readc(cis, &c) != 1)		return 0;	exp = vexp[c&0x7];	microvolts = vmant[(c>>3)&0xf]*exp;	while(c & 0x80){		if(readc(cis, &c) != 1)			return 0;		switch(c){		case 0x7d:			break;		/* high impedence when sleeping */		case 0x7e:		case 0x7f:			microvolts = 0;	/* no connection */			break;		default:			exp /= 10;			microvolts += exp*(c&0x7f);		}	}	return microvolts;}static ulongnanoamps(Cisdat *cis){	uchar c;	ulong nanoamps;	if(readc(cis, &c) != 1)		return 0;	nanoamps = vexp[c&0x7]*vmant[(c>>3)&0xf];	while(c & 0x80){		if(readc(cis, &c) != 1)			return 0;		if(c == 0x7d || c == 0x7e || c == 0x7f)			nanoamps = 0;	}	return nanoamps;}/* *  only nominal voltage is important for config */static ulongpower(Cisdat *cis){	uchar feature;	ulong mv;	mv = 0;	if(readc(cis, &feature) != 1)		return 0;	if(feature & 1)		mv = microvolt(cis);	if(feature & 2)		microvolt(cis);	if(feature & 4)		microvolt(cis);	if(feature & 8)		nanoamps(cis);	if(feature & 0x10)		nanoamps(cis);	if(feature & 0x20)		nanoamps(cis);	if(feature & 0x40)		nanoamps(cis);	return mv/1000000;}static ulong mantissa[16] ={ 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80, };static ulong exponent[8] ={ 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, };static ulongttiming(Cisdat *cis, int scale){	uchar unscaled;	ulong nanosecs;	if(readc(cis, &unscaled) != 1)		return 0;	nanosecs = (mantissa[(unscaled>>3)&0xf]*exponent[unscaled&7])/10;	nanosecs = nanosecs * vexp[scale];	return nanosecs;}static voidtiming(Cisdat *cis, Conftab *ct){	uchar c, i;	if(readc(cis, &c) != 1)		return;	i = c&0x3;	if(i != 3)		ct->maxwait = ttiming(cis, i);		/* max wait */	i = (c>>2)&0x7;	if(i != 7)		ct->readywait = ttiming(cis, i);		/* max ready/busy wait */	i = (c>>5)&0x7;	if(i != 7)		ct->otherwait = ttiming(cis, i);		/* reserved wait */}static voidiospaces(Cisdat *cis, Conftab *ct){	uchar c;	int i, nio;	ct->nio = 0;	if(readc(cis, &c) != 1)		return;	ct->bit16 = ((c>>5)&3) >= 2;	if(!(c & 0x80)){		ct->io[0].start = 0;		ct->io[0].len = 1<<(c&0x1f);		ct->nio = 1;		return;	}	if(readc(cis, &c) != 1)		return;	nio = (c&0xf)+1;	for(i = 0; i < nio; i++){		ct->io[i].start = getlong(cis, (c>>4)&0x3);		ct->io[0].len = getlong(cis, (c>>6)&0x3);	}	ct->nio = nio;}static voidirq(Cisdat *cis, Conftab *ct){	uchar c;	if(readc(cis, &c) != 1)		return;	ct->irqtype = c & 0xe0;	if(c & 0x10)		ct->irqs = getlong(cis, 2);	else		ct->irqs = 1<<(c&0xf);	ct->irqs &= 0xDEB8;		/* levels available to card */}static voidmemspace(Cisdat *cis, int asize, int lsize, int host){	ulong haddress, address, len;	len = getlong(cis, lsize)*256;	address = getlong(cis, asize)*256;	USED(len, address);	if(host){		haddress = getlong(cis, asize)*256;		USED(haddress);	}}static voidtentry(Slot *pp, Cisdat *cis, int ){	uchar c, i, feature;	Conftab *ct;	if(pp->nctab >= Maxctab)		return;	if(readc(cis, &c) != 1)		return;	ct = &pp->ctab[pp->nctab++];	/* copy from last default config */	if(pp->def)		*ct = *pp->def;	ct->index = c & 0x3f;	/* is this the new default? */	if(c & 0x40)		pp->def = ct;	/* memory wait specified? */	if(c & 0x80){		if(readc(cis, &i) != 1)			return;		if(i&0x80)			ct->memwait = 1;	}	if(readc(cis, &feature) != 1)		return;	switch(feature&0x3){	case 1:		ct->vpp1 = ct->vpp2 = power(cis);		break;	case 2:		power(cis);		ct->vpp1 = ct->vpp2 = power(cis);		break;	case 3:		power(cis);		ct->vpp1 = power(cis);		ct->vpp2 = power(cis);		break;	default:		break;	}	if(feature&0x4)		timing(cis, ct);	if(feature&0x8)		iospaces(cis, ct);	if(feature&0x10)		irq(cis, ct);	switch((feature>>5)&0x3){	case 1:		memspace(cis, 0, 2, 0);		break;	case 2:		memspace(cis, 2, 2, 0);		break;	case 3:		if(readc(cis, &c) != 1)			return;		for(i = 0; i <= (c&0x7); i++)			memspace(cis, (c>>5)&0x3, (c>>3)&0x3, c&0x80);		break;	}	pp->configed++;}static voidtvers1(Slot *pp, Cisdat *cis, int ){	uchar c, major, minor;	int  i;	if(readc(cis, &major) != 1)		return;	if(readc(cis, &minor) != 1)		return;	for(i = 0; i < sizeof(pp->verstr)-1; i++){		if(readc(cis, &c) != 1)			return;		if(c == 0)			c = '\n';		if(c == 0xff)			break;		pp->verstr[i] = c;	}	pp->verstr[i] = 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -