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

📄 dgb.c

📁 freebsd v4.4内核源码
💻 C
📖 第 1 页 / 共 4 页
字号:
		default:			printf("dgb%d: wrong IRQ mask 0x%x\n",dev->id_unit,dev->id_irq);			sc->status=DISABLED;			return 0;		}#endif		outb(sc->port+2,t & 0xFF);		outb(sc->port+3,t>>8);	} else if(sc->type==PCXE) {		t=(((u_long)sc->pmem>>8) & 0xFFE0) /* disable windowing */;		outb(sc->port+2,t & 0xFF);		outb(sc->port+3,t>>8);	}	if(sc->type==PCXI || sc->type==PCXE) {		outb(sc->port, FEPRST|FEPMEM); DELAY(1);		for(i=0; (inb(sc->port) & FEPMASK) != (FEPRST|FEPMEM) ; i++) {			if(i>10000) {				printf("dgb%d: 2nd reset failed\n",dev->id_unit);				sc->status=DISABLED;				hidewin(sc);				return 0;			}			DELAY(1);		}		DPRINT3(DB_INFO,"dgb%d: got memory after %d us\n",unit,i);	}	mem=sc->vmem;	/* very short memory test */	addr=setinitwin(sc,BOTWIN);	*(u_long *)(mem+addr) = 0xA55A3CC3;	if(*(u_long *)(mem+addr)!=0xA55A3CC3) {		printf("dgb%d: 1st memory test failed\n",dev->id_unit);		sc->status=DISABLED;		hidewin(sc);		return 0;	}			addr=setinitwin(sc,TOPWIN);	*(u_long *)(mem+addr) = 0x5AA5C33C;	if(*(u_long *)(mem+addr)!=0x5AA5C33C) {		printf("dgb%d: 2nd memory test failed\n",dev->id_unit);		sc->status=DISABLED;		hidewin(sc);		return 0;	}			addr=setinitwin(sc,BIOSCODE+((0xF000-sc->mem_seg)<<4));	*(u_long *)(mem+addr) = 0x5AA5C33C;	if(*(u_long *)(mem+addr)!=0x5AA5C33C) {		printf("dgb%d: 3rd (BIOS) memory test failed\n",dev->id_unit);	}			addr=setinitwin(sc,MISCGLOBAL);	for(i=0; i<16; i++) {		mem[addr+i]=0;	}	if(sc->type==PCXI || sc->type==PCXE) {		addr=BIOSCODE+((0xF000-sc->mem_seg)<<4);		DPRINT3(DB_INFO,"dgb%d: BIOS local address=0x%x\n",unit,addr);		ptr= mem+addr;		for(i=0; i<pcxx_nbios; i++, ptr++)			*ptr = pcxx_bios[i];		ptr= mem+addr;		nfails=0;		for(i=0; i<pcxx_nbios; i++, ptr++)			if( *ptr != pcxx_bios[i] ) {				DPRINT5(DB_EXCEPT,"dgb%d: wrong code in BIOS at addr 0x%x : \0x%x instead of 0x%x\n", unit, ptr-(mem+addr), *ptr, pcxx_bios[i] );				if(++nfails>=5) {					printf("dgb%d: 4th memory test (BIOS load) fails\n",unit);					break;					}				}		outb(sc->port,FEPMEM);		for(i=0; (inb(sc->port) & FEPMASK) != FEPMEM ; i++) {			if(i>10000) {				printf("dgb%d: BIOS start failed\n",dev->id_unit);				sc->status=DISABLED;				hidewin(sc);				return 0;			}			DELAY(1);		}		DPRINT3(DB_INFO,"dgb%d: reset dropped after %d us\n",unit,i);		for(i=0; i<200000; i++) {			if( *((ushort *)(mem+MISCGLOBAL)) == *((ushort *)"GD") )				goto load_fep;			DELAY(1);		}		printf("dgb%d: BIOS download failed\n",dev->id_unit);		DPRINT4(DB_EXCEPT,"dgb%d: code=0x%x must be 0x%x\n",			dev->id_unit,			*((ushort *)(mem+MISCGLOBAL)),			*((ushort *)"GD"));		sc->status=DISABLED;		hidewin(sc);		return 0;	}	if(sc->type==PCXEVE) {		/* set window 7 */		outb(sc->port+1,0xFF);		ptr= mem+(BIOSCODE & 0x1FFF);		for(i=0; i<pcxx_nbios; i++)			*ptr++ = pcxx_bios[i];		ptr= mem+(BIOSCODE & 0x1FFF);		nfails=0;		for(i=0; i<pcxx_nbios; i++, ptr++)			if( *ptr != pcxx_bios[i] ) {				DPRINT5(DB_EXCEPT,"dgb%d: wrong code in BIOS at addr 0x%x : \0x%x instead of 0x%x\n", unit, ptr-(mem+addr), *ptr, pcxx_bios[i] );				if(++nfails>=5) {					printf("dgb%d: 4th memory test (BIOS load) fails\n",unit);					break;					}				}		outb(sc->port,FEPCLR);		setwin(sc,0);		for(i=0; (inb(sc->port) & FEPMASK) != FEPCLR ; i++) {			if(i>10000) {				printf("dgb%d: BIOS start failed\n",dev->id_unit);				sc->status=DISABLED;				hidewin(sc);				return 0;			}			DELAY(1);		}		DPRINT3(DB_INFO,"dgb%d: reset dropped after %d us\n",unit,i);		addr=setwin(sc,MISCGLOBAL);		for(i=0; i<200000; i++) {			if(*(ushort *)(mem+addr)== *(ushort *)"GD")				goto load_fep;			DELAY(1);		}		printf("dgb%d: BIOS download failed\n",dev->id_unit);		DPRINT5(DB_EXCEPT,"dgb%d: Error#(0x%x,0x%x) code=0x%x\n",			dev->id_unit,			*(ushort *)(mem+0xC12),			*(ushort *)(mem+0xC14),			*(ushort *)(mem+MISCGLOBAL));		sc->status=DISABLED;		hidewin(sc);		return 0;	}load_fep:	DPRINT2(DB_INFO,"dgb%d: BIOS loaded\n",dev->id_unit);	addr=setwin(sc,FEPCODE);	ptr= mem+addr;	for(i=0; i<pcxx_ncook; i++)		*ptr++ = pcxx_cook[i];	addr=setwin(sc,MBOX);	*(ushort *)(mem+addr+ 0)=2;	*(ushort *)(mem+addr+ 2)=sc->mem_seg+FEPCODESEG;	*(ushort *)(mem+addr+ 4)=0;	*(ushort *)(mem+addr+ 6)=FEPCODESEG;	*(ushort *)(mem+addr+ 8)=0;	*(ushort *)(mem+addr+10)=pcxx_ncook;		outb(sc->port,FEPMEM|FEPINT); /* send interrupt to BIOS */	outb(sc->port,FEPMEM);	for(i=0; *(ushort *)(mem+addr)!=0; i++) {		if(i>200000) {			printf("dgb%d: FEP code download failed\n",unit);			DPRINT3(DB_EXCEPT,"dgb%d: code=0x%x must be 0\n", unit,				*(ushort *)(mem+addr));			sc->status=DISABLED;			hidewin(sc);			return 0;		}	}	DPRINT2(DB_INFO,"dgb%d: FEP code loaded\n",unit);	*(ushort *)(mem+setwin(sc,FEPSTAT))=0;	addr=setwin(sc,MBOX);	*(ushort *)(mem+addr+0)=1;	*(ushort *)(mem+addr+2)=FEPCODESEG;	*(ushort *)(mem+addr+4)=0x4;	outb(sc->port,FEPINT); /* send interrupt to BIOS */	outb(sc->port,FEPCLR);	addr=setwin(sc,FEPSTAT);	for(i=0; *(ushort *)(mem+addr)!= *(ushort *)"OS"; i++) {		if(i>200000) {			printf("dgb%d: FEP/OS start failed\n",dev->id_unit);			sc->status=DISABLED;			hidewin(sc);			return 0;		}	}	DPRINT2(DB_INFO,"dgb%d: FEP/OS started\n",dev->id_unit);	sc->numports= *(ushort *)(mem+setwin(sc,NPORT));	printf("dgb%d: %d ports\n",unit,sc->numports);	if(sc->numports > MAX_DGB_PORTS) {		printf("dgb%d: too many ports\n",unit);		sc->status=DISABLED;		hidewin(sc);		return 0;	}	if(nports+sc->numports>NDGBPORTS) {		printf("dgb%d: only %d ports are usable\n", unit, NDGBPORTS-nports);		sc->numports=NDGBPORTS-nports;	}	/* allocate port and tty structures */	sc->ports=&dgb_ports[nports];	sc->ttys=&dgb_tty[nports];	nports+=sc->numports;	addr=setwin(sc,PORTBASE);	pstat=(ushort *)(mem+addr);	for(i=0; i<sc->numports && pstat[i]; i++)		if(pstat[i])			sc->ports[i].status=ENABLED;		else {			sc->ports[i].status=DISABLED;			printf("dgb%d: port%d is broken\n", unit, i);		}	/* We should now init per-port structures */	bc=(volatile struct board_chan *)(mem + CHANSTRUCT);	sc->mailbox=(volatile struct global_data *)(mem + FEP_GLOBAL);	if(sc->numports<3)		shrinkmem=1;	else		shrinkmem=0;	for(i=0; i<sc->numports; i++, bc++) {		port= &sc->ports[i];		port->tty=&sc->ttys[i];		port->unit=unit;		port->brdchan=bc;		if(sc->altpin) {			port->dsr=CD;			port->dcd=DSR;		} else {			port->dcd=CD;			port->dsr=DSR;		}		port->pnum=i;		if(shrinkmem) {			DPRINT2(DB_INFO,"dgb%d: shrinking memory\n",unit);			fepcmd(port, SETBUFFER, 32, 0, 0, 0);			shrinkmem=0;			}		if(sc->type!=PCXEVE) {			port->txptr=mem+((bc->tseg-sc->mem_seg)<<4);			port->rxptr=mem+((bc->rseg-sc->mem_seg)<<4);			port->txwin=port->rxwin=0;		} else {			port->txptr=mem+( ((bc->tseg-sc->mem_seg)<<4) & 0x1FFF );			port->rxptr=mem+( ((bc->rseg-sc->mem_seg)<<4) & 0x1FFF );			port->txwin=FEPWIN | ((bc->tseg-sc->mem_seg)>>9);			port->rxwin=FEPWIN | ((bc->rseg-sc->mem_seg)>>9);		}		port->txbufhead=0;		port->rxbufhead=0;		port->txbufsize=bc->tmax+1;		port->rxbufsize=bc->rmax+1;		lowwater= (port->txbufsize>=2000) ? 1024 : (port->txbufsize/2);		setwin(sc,0);		fepcmd(port, STXLWATER, lowwater, 0, 10, 0);		fepcmd(port, SRXLWATER, port->rxbufsize/4, 0, 10, 0);		fepcmd(port, SRXHWATER, 3*port->rxbufsize/4, 0, 10, 0);		bc->edelay=100;		bc->idata=1;		port->startc=bc->startc;		port->startca=bc->startca;		port->stopc=bc->stopc;		port->stopca=bc->stopca;					/*port->close_delay=50;*/		port->close_delay=3 * hz;		port->do_timestamp=0;		port->do_dcd_timestamp=0;		/*		 * We don't use all the flags from <sys/ttydefaults.h> since they		 * are only relevant for logins.  It's important to have echo off		 * initially so that the line doesn't start blathering before the		 * echo flag can be turned off.		 */		port->it_in.c_iflag = TTYDEF_IFLAG;		port->it_in.c_oflag = TTYDEF_OFLAG;		port->it_in.c_cflag = TTYDEF_CFLAG;		port->it_in.c_lflag = TTYDEF_LFLAG;		termioschars(&port->it_in);		port->it_in.c_ispeed = port->it_in.c_ospeed = dgbdefaultrate;		port->it_out = port->it_in;#ifdef	DEVFS/*XXX*/ /* fix the minor numbers */		port->devfs_token.tty = 			devfs_add_devswf(&dgb_cdevsw,					 (unit*32)+i,/*mytical number*/					 DV_CHR, 0, 0, 0600, "dgb%d.%d", unit, 					 i);		port->devfs_token.tty = 			devfs_add_devswf(&dgb_cdevsw,					 (unit*32)+i+64,/*mytical number*/					 DV_CHR, 0, 0, 0600, "idgb%d.%d", unit, 					 i);		port->devfs_token.tty = 			devfs_add_devswf(&dgb_cdevsw,					 (unit*32)+i+128,/*mytical number*/					 DV_CHR, 0, 0, 0600, "ldgb%d.%d", unit,					 i);		port->devfs_token.tty = 			devfs_add_devswf(&dgb_cdevsw,					 (unit*32)+i+192,/*mytical number*/					 DV_CHR, 0, 0, 0600, "dgbcua%d.%d",					 unit, i);#endif	}	hidewin(sc);	/* register the polling function */	timeout(dgbpoll, (void *)unit, hz/POLLSPERSEC);	return 1;}/* ARGSUSED */static	intdgbopen(dev, flag, mode, p)	dev_t		dev;	int		flag;	int		mode;	struct proc	*p;{	struct dgb_softc *sc;	struct tty *tp;	int unit;	int mynor;	int pnum;	struct dgb_p *port;	int s,cs;	int error;	volatile struct board_chan *bc;	error=0;	mynor=minor(dev);	unit=MINOR_TO_UNIT(mynor);	pnum=MINOR_TO_PORT(mynor);	if(unit >= NDGB) {		DPRINT2(DB_EXCEPT,"dgb%d: try to open a nonexisting card\n",unit);		return ENXIO;	}	sc=&dgb_softc[unit];	if(sc->status!=ENABLED) {		DPRINT2(DB_EXCEPT,"dgb%d: try to open a disabled card\n",unit);		return ENXIO;	}	if(pnum>=sc->numports) {		DPRINT3(DB_EXCEPT,"dgb%d: try to open non-existing port %d\n",unit,pnum);		return ENXIO;	}	if(mynor & CONTROL_MASK)		return 0;	tp=&sc->ttys[pnum];	port=&sc->ports[pnum];	bc=port->brdchan;open_top:		s=spltty();	while(port->closing) {		error=tsleep(&port->closing, TTOPRI|PCATCH, "dgocl", 0);		if(error) {			DPRINT4(DB_OPEN,"dgb%d: port%d: tsleep(dgocl) error=%d\n",unit,pnum,error);			goto out;		}	}	if (tp->t_state & TS_ISOPEN) {		/*		 * The device is open, so everything has been initialized.		 * Handle conflicts.		 */		if (mynor & CALLOUT_MASK) {			if (!port->active_out) {				error = EBUSY;				DPRINT4(DB_OPEN,"dgb%d: port%d: BUSY error=%d\n",unit,pnum,error);				goto out;			}		} else {			if (port->active_out) {				if (flag & O_NONBLOCK) {					error = EBUSY;					DPRINT4(DB_OPEN,"dgb%d: port%d: BUSY error=%d\n",unit,pnum,error);					goto out;				}				error =	tsleep(&port->active_out,					       TTIPRI | PCATCH, "dgbi", 0);				if (error != 0) {					DPRINT4(DB_OPEN,"dgb%d: port%d: tsleep(dgbi) error=%d\n",						unit,pnum,error);					goto out;				}				splx(s);				goto open_top;			}		}		if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) {			error = EBUSY;			goto out;		}	} else {		/*		 * The device isn't open, so there are no conflicts.		 * Initialize it.  Initialization is done twice in many		 * cases: to preempt sleeping callin opens if we are		 * callout, and to complete a callin open after DCD rises.		 */		tp->t_oproc=dgbstart;		tp->t_param=dgbparam;		tp->t_dev=dev;		tp->t_termios= (mynor & CALLOUT_MASK) ?							port->it_out :							port->it_in;		cs=splclock();		setwin(sc,0);		port->imodem=bc->mstat;		bc->rout=bc->rin; /* clear input queue */		bc->idata=1;#ifdef PRINT_BUFSIZE		printf("dgb buffers tx=%x:%x rx=%x:%x\n",bc->tseg,bc->tmax,bc->rseg,bc->rmax);#endif		hidewin(sc);		splx(cs);		port->wopeners++;		error=dgbparam(tp, &tp->t_termios);		port->wopeners--;		if(error!=0) {			DPRINT4(DB_OPEN,"dgb%d: port%d: dgbparam error=%d\n",unit,pnum,error);			goto out;		}		ttsetwater(tp);		/* handle fake DCD for callout devices */		/* and initial DCD */		if( (port->imodem & port->dcd) || mynor & CALLOUT_MASK )			linesw[tp->t_line].l_modem(tp,1);	}	/*	 * Wait for DCD if necessary.	 */	if (!(tp->t_state & TS_CARR_ON) && !(mynor & CALLOUT_MASK)	    && !(tp->t_cflag & CLOCAL) && !(flag & O_NONBLOCK)) {		++port->wopeners;		error = tsleep(TSA_CARR_ON(tp), TTIPRI | PCATCH, "dgdcd", 0);		--port->wopeners;		if (error != 0) {			DPRINT4(DB_OPEN,"dgb%d: port%d: tsleep(dgdcd) error=%d\n",unit,pnum,error);			goto out;		}		splx(s);		goto open_top;	}	error =	linesw[tp->t_line].l_open(dev, tp);	disc_optim(tp,&tp->t_termios);	DPRINT4(DB_OPEN,"dgb%d: port%d: l_open error=%d\n",unit,pnum,error);	if (tp->t_state & TS_ISOPEN && mynor & CALLOUT_MASK)		port->active_out = TRUE;	port->used=1;	/* If any port is open (i.e. the open() call is completed for it) 	 * the device is busy	 */out:	disc_optim(tp,&tp->t_termios);	splx(s);	if( !(tp->t_state & TS_ISOPEN) && port->wopeners==0 )		dgbhardclose(port);	DPRINT4(DB_OPEN,"dgb%d: port%d: open() returns %d\n",unit,pnum,error);	return error;}/*ARGSUSED*/static	intdgbclose(dev, flag, mode, p)	dev_t		dev;	int		flag;	int		mode;	struct proc	*p;{	int		mynor;	struct tty	*tp;	int unit, pnum;	struct dgb_softc *sc;	struct dgb_p *port;	int s;	int i;	mynor=minor(dev);	if(mynor & CONTROL_MASK)		return 0;	unit=MINOR_TO_UNIT(mynor);	pnum=MINOR_TO_PORT(mynor);	sc=&dgb_softc[unit];	tp=&sc->ttys[pnum];	port=sc->ports+pnum;	DPRINT3(DB_CLOSE,"dgb%d: port%d: closing\n",unit,pnum);

⌨️ 快捷键说明

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