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

📄 devi82365.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
		outb(x, 0x37 + (dev<<7));		/* make the id register show the Vadem id */		outb(x, 0x3A + (dev<<7));		c = inb(d);		outb(d, c|0xC0);		outb(x, Rid + (dev<<7));		c = inb(d);		if(c & 0x08)			cp->type = Tvg46x;		/* go back to Intel compatible id */		outb(x, 0x3A + (dev<<7));		c = inb(d);		outb(d, c & ~0xC0);	}	memset(&isa, 0, sizeof(ISAConf));	if(isaconfig("pcmcia", ncontroller, &isa) && isa.irq)		cp->irq = isa.irq;	else		cp->irq = IrqPCMCIA;	for(i = 0; i < isa.nopt; i++){		if(cistrncmp(isa.opt[i], "nslot=", 6))			continue;		nslot = strtol(&isa.opt[i][6], nil, 0);		if(nslot > 0 && nslot <= 2)			cp->nslot = nslot;	}	controller[ncontroller++] = cp;	return cp;}static voidi82365dump(PCMslot *pp){	int i;	for(i = 0; i < 0x40; i++){		if((i&0x0F) == 0)			print("\n%2.2uX:	", i);		print("%2.2uX ", rdreg(pp, i));		if(((i+1) & 0x0F) == 0x08)			print(" - ");	}	print("\n");}/* *  set up for slot cards */voiddevi82365link(void){	static int already;	int i, j;	I82365 *cp;	PCMslot *pp;	char buf[32], *p;	if(already)		return;	already = 1;	if((p=getconf("pcmcia0")) && strncmp(p, "disabled", 8)==0)		return;	if(_pcmspecial)		return;		/* look for controllers if the ports aren't already taken */	if(ioalloc(0x3E0, 2, 0, "i82365.0") >= 0){		i82365probe(0x3E0, 0x3E1, 0);		i82365probe(0x3E0, 0x3E1, 1);		if(ncontroller == 0)			iofree(0x3E0);	}	if(ioalloc(0x3E2, 2, 0, "i82365.1") >= 0){		i = ncontroller;		i82365probe(0x3E2, 0x3E3, 0);		i82365probe(0x3E2, 0x3E3, 1);		if(ncontroller == i)			iofree(0x3E2);	}	if(ncontroller == 0)		return;	_pcmspecial = pcmcia_pcmspecial;	_pcmspecialclose = pcmcia_pcmspecialclose;	for(i = 0; i < ncontroller; i++)		nslot += controller[i]->nslot;	slot = xalloc(nslot * sizeof(PCMslot));	lastslot = slot;	for(i = 0; i < ncontroller; i++){		cp = controller[i];		print("#y%d: %d slot %s: port 0x%uX irq %d\n",			i, cp->nslot, chipname[cp->type], cp->xreg, cp->irq);		for(j = 0; j < cp->nslot; j++){			pp = lastslot++;			pp->slotno = pp - slot;			pp->memlen = 64*MB;			pp->base = (cp->dev<<7) | (j<<6);			pp->cp = cp;			pp->msec = ~0;			pp->verstr[0] = 0;			slotdis(pp);			/* interrupt on status change */			wrreg(pp, Rcscic, (cp->irq<<4) | Fchangeena);			rdreg(pp, Rcsc);		}		/* for card management interrupts */		snprint(buf, sizeof buf, "i82365.%d", i);		intrenable(cp->irq, i82365intr, 0, BUSUNKNOWN, buf);	}}static Chan*i82365attach(char *spec){	return devattach('y', spec);}static Walkqid*i82365walk(Chan *c, Chan *nc, char **name, int nname){	return devwalk(c, nc, name, nname, 0, 0, pcmgen);}static inti82365stat(Chan *c, uchar *db, int n){	return devstat(c, db, n, 0, 0, pcmgen);}static Chan*i82365open(Chan *c, int omode){	if(c->qid.type & QTDIR){		if(omode != OREAD)			error(Eperm);	} else		increfp(slot + SLOTNO(c));	c->mode = openmode(omode);	c->flag |= COPEN;	c->offset = 0;	return c;}static voidi82365close(Chan *c){	if(c->flag & COPEN)		if((c->qid.type & QTDIR) == 0)			decrefp(slot+SLOTNO(c));}/* a memmove using only bytes */static voidmemmoveb(uchar *to, uchar *from, int n){	while(n-- > 0)		*to++ = *from++;}/* a memmove using only shorts & bytes */static voidmemmoves(uchar *to, uchar *from, int n){	ushort *t, *f;	if((((ulong)to) & 1) || (((ulong)from) & 1) || (n & 1)){		while(n-- > 0)			*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;	PCMslot *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("cannot 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, *buf, *e;	PCMslot *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:		buf = p = malloc(READSTR);		e = p + READSTR;		pp = slot + SLOTNO(c);		buf[0] = 0;		if(pp->occupied){			p = seprint(p, e, "occupied\n");			if(pp->verstr[0])				p = seprint(p, e, "version %s\n", pp->verstr);		}		if(pp->enabled)			p = seprint(p, e, "enabled\n");		if(pp->powered)			p = seprint(p, e, "powered\n");		if(pp->configed)			p = seprint(p, e, "configed\n");		if(pp->wrprot)			p = seprint(p, e, "write protected\n");		if(pp->busy)			p = seprint(p, e, "busy\n");		seprint(p, e, "battery lvl %d\n", pp->battery);		n = readstr(offset, a, n, buf);		free(buf);		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;	PCMslot *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("cannot 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){	PCMslot *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",	devreset,	devinit,	devshutdown,	i82365attach,	i82365walk,	i82365stat,	i82365open,	devcreate,	i82365close,	i82365read,	devbread,	i82365write,	devbwrite,	devremove,	devwstat,};/* *  configure the PCMslot 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;	PCMslot *pp;	PCMconftab *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	 * the 'top' register value includes the last valid address	 */	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 */	m = pcmmap(slotno, pp->cfg[0].caddr + Rconfig, 0x20, 1);	p = KADDR(m->isa + pp->cfg[0].caddr - m->ca);	if(pp->cfg[0].cpresent & (1<<Rconfig)){		/*  Reset adapter */		/*  set configuration and interrupt type.		 *  if level is possible on the card, use it.		 */		x = ct->index;		if(ct->irqtype & 0x20)			x |= Clevel;		/*  enable the device, enable address decode and		 *  irq enable.		 */		x |= Cfunc|Cdecode|Cirq;		p[0] = x;		//delay(5);		microdelay(40);	}	if(pp->cfg[0].cpresent & (1<<Riobase0)){		/* set up the iobase 0 */		p[Riobase0 << 1] = isa->port;		p[Riobase1 << 1] = isa->port >> 8;	}	if(pp->cfg[0].cpresent & (1<<Riosize))		p[Riosize << 1] = ct->io[0].len;	pcmunmap(slotno, m);	return 0;}

⌨️ 快捷键说明

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