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

📄 devpccard.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
	Cardbus *cb = &cbslots[slotno];	m = isamap(cb, 0, 0, attr);	if(m == 0)		return -1;	cis.cisbase = KADDR(m->isa);	cis.cispos = 0;	cis.cisskip = attr ? 2 : 1;	cis.cislen = m->len;	/* 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;		n = link;		if (link > 1 && subtuple != -1) {			if (readc(&cis, &c) != 1)				break;			subtype = c;			n--;		} else			subtype = -1;		if(type == tuple && subtype == subtuple) {			p = v;			for(l=0; l<nv && l<n; l++)				if(readc(&cis, p++) != 1)					break;			isaunmap(m);			return nv;		}		cis.cispos = this + (2+link);	}	isaunmap(m);	return -1;}static PCMmap *isamap(Cardbus *cb, ulong offset, int len, int attr){	uchar we, bit;	PCMmap *m, *nm;	Pcminfo *pi;	int i;	ulong e;	pi = &cb->linfo;	/* convert offset to granularity */	if(len <= 0)		len = 1;	e = ROUND(offset+len, Mgran);	offset &= Mmask;	len = e - offset;	/* look for a map that covers the right area */	we = rdreg(cb, Rwe);	bit = 1;	nm = 0;	for(m = pi->mmap; m < &pi->mmap[nelem(pi->mmap)]; m++){		if((we & bit))		if(m->attr == attr)		if(offset >= m->ca && e <= m->cea){			m->ref++;			return m;		}		bit <<= 1;		if(nm == 0 && m->ref == 0)			nm = m;	}	m = nm;	if(m == 0)		return 0;	/* if isa space isn't big enough, free it and get more */	if(m->len < len){		if(m->isa){			umbfree(m->isa, m->len);			m->len = 0;		}		m->isa = PADDR(umbmalloc(0, len, Mgran));		if(m->isa == 0){			print("isamap: out of isa space\n");			return 0;		}		m->len = len;	}	/* set up new map */	m->ca = offset;	m->cea = m->ca + m->len;	m->attr = attr;	i = m - pi->mmap;	bit = 1<<i;	wrreg(cb, Rwe, we & ~bit);		/* disable map before changing it */	wrreg(cb, MAP(i, Mbtmlo), m->isa>>Mshift);	wrreg(cb, MAP(i, Mbtmhi), (m->isa>>(Mshift+8)) | F16bit);	wrreg(cb, MAP(i, Mtoplo), (m->isa+m->len-1)>>Mshift);	wrreg(cb, MAP(i, Mtophi), ((m->isa+m->len-1)>>(Mshift+8)));	offset -= m->isa;	offset &= (1<<25)-1;	offset >>= Mshift;	wrreg(cb, MAP(i, Mofflo), offset);	wrreg(cb, MAP(i, Moffhi), (offset>>8) | (attr ? Fregactive : 0));	wrreg(cb, Rwe, we | bit);		/* enable map */	m->ref = 1;	return m;}static voidisaunmap(PCMmap* m){	m->ref--;}/* *  reading and writing card registers */static ucharrdreg(Cardbus *cb, int index){	outb(cb->lindex, cb->lbase + index);	return inb(cb->ldata);}static voidwrreg(Cardbus *cb, int index, uchar val){	outb(cb->lindex, cb->lbase + index);	outb(cb->ldata, val);}static intreadc(Cisdat *cis, uchar *x){	if(cis->cispos >= cis->cislen)		return 0;	*x = cis->cisbase[cis->cisskip*cis->cispos];	cis->cispos++;	return 1;}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(Cardbus *cb, Cisdat *cis, int ){	uchar size, rasize, rmsize;	uchar last;	Pcminfo *pi;	if(readc(cis, &size) != 1)		return;	rasize = (size&0x3) + 1;	rmsize = ((size>>2)&0xf) + 1;	if(readc(cis, &last) != 1)		return;	pi = &cb->linfo;	pi->conf_addr = getlong(cis, rasize);	pi->conf_present = getlong(cis, rmsize);}static voidtvers1(Cardbus *cb, Cisdat *cis, int ){	uchar c, major, minor, last;	int  i;	Pcminfo *pi;	pi = &cb->linfo;	if(readc(cis, &major) != 1)		return;	if(readc(cis, &minor) != 1)		return;	last = 0;	for(i = 0; i < sizeof(pi->verstr) - 1; i++){		if(readc(cis, &c) != 1)			return;		if(c == 0)			c = ';';		if(c == '\n')			c = ';';		if(c == 0xff)			break;		if(c == ';' && last == ';')			continue;		pi->verstr[i] = c;		last = c;	}	pi->verstr[i] = 0;}static ulongmicrovolt(Cisdat *cis){	uchar c;	ulong microvolts;	ulong exp;	if(readc(cis, &c) != 1)		return 0;	exp = exponent[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 = exponent[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 (feature 1) is important for config, * other features must read card to stay in sync. */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 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 * exponent[scale];	return nanosecs;}static voidtiming(Cisdat *cis, PCMconftab *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, PCMconftab *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;	/*	 * For each of the range descriptions read the	 * start address and the length (value is length-1).	 */	nio = (c&0xf)+1;	for(i = 0; i < nio; i++){		ct->io[i].start = getlong(cis, (c>>4)&0x3);		ct->io[i].len = getlong(cis, (c>>6)&0x3)+1;	}	ct->nio = nio;}static voidirq(Cisdat *cis, PCMconftab *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(Cardbus *cb, Cisdat *cis, int ){	uchar c, i, feature;	PCMconftab *ct;	Pcminfo *pi;	pi = &cb->linfo;	if(pi->nctab >= nelem(pi->ctab))		return;	if(readc(cis, &c) != 1)		return;	ct = &pi->ctab[pi->nctab++];	/* copy from last default config */	if(pi->defctab)		*ct = *pi->defctab;	ct->index = c & 0x3f;	/* is this the new default? */	if(c & 0x40)		pi->defctab = 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;	}}static voidi82365probe(Cardbus *cb, int lindex, int ldata){	uchar c, id;	int dev = 0;	/* According to the Ricoh spec 00->3F _and_ 80->BF seem				     to be the same socket A (ditto for B). */	outb(lindex, Rid + (dev<<7));	id = inb(ldata);	if((id & 0xf0) != 0x80)		return;		/* not a memory & I/O card */	if((id & 0x0f) == 0x00)		return;		/* no revision number, not possible */	cb->lindex = lindex;	cb->ldata = ldata;	cb->ltype = Ti82365;	cb->lbase = (int)(cb - cbslots) * 0x40;	switch(id){	case 0x82:	case 0x83:	case 0x84:		/* could be a cirrus */		outb(cb->lindex, Rchipinfo + (dev<<7));		outb(cb->ldata, 0);		c = inb(cb->ldata);		if((c & 0xc0) != 0xc0)			break;		c = inb(cb->ldata);		if((c & 0xc0) != 0x00)			break;		if(c & 0x20){			cb->ltype = Tpd6720;		} else {			cb->ltype = Tpd6710;		}		break;	}	/* if it's not a Cirrus, it could be a Vadem... */	if(cb->ltype == Ti82365){		/* unlock the Vadem extended regs */		outb(cb->lindex, 0x0E + (dev<<7));		outb(cb->lindex, 0x37 + (dev<<7));		/* make the id register show the Vadem id */		outb(cb->lindex, 0x3A + (dev<<7));		c = inb(cb->ldata);		outb(cb->ldata, c|0xC0);		outb(cb->lindex, Rid + (dev<<7));		c = inb(cb->ldata);		if(c & 0x08)			cb->ltype = Tvg46x;		/* go back to Intel compatible id */		outb(cb->lindex, 0x3A + (dev<<7));		c = inb(cb->ldata);		outb(cb->ldata, c & ~0xC0);	}}static intvcode(int volt){	switch(volt){	case 5:		return 1;	case 12:		return 2;	default:		return 0;	}}

⌨️ 快捷键说明

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