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

📄 dgb.c

📁 freebsd v4.4内核源码
💻 C
📖 第 1 页 / 共 4 页
字号:
		if(*(int *)data & TIOCM_RTS)			port->omodem |=RTS;		else			port->omodem &=~RTS;		cs=splclock();		setwin(sc,0);		fepcmd(port, SETMODEM, port->omodem, RTS|DTR, 0, 1);		hidewin(sc);		splx(cs);		break;	case TIOCMBIS:		if(*(int *)data & TIOCM_DTR)			port->omodem |=DTR;		if(*(int *)data & TIOCM_RTS)			port->omodem |=RTS;		cs=splclock();		setwin(sc,0);		fepcmd(port, SETMODEM, port->omodem, RTS|DTR, 0, 1);		hidewin(sc);		splx(cs);		break;	case TIOCMBIC:		if(*(int *)data & TIOCM_DTR)			port->omodem &=~DTR;		if(*(int *)data & TIOCM_RTS)			port->omodem &=~RTS;		cs=splclock();		setwin(sc,0);		fepcmd(port, SETMODEM, port->omodem, RTS|DTR, 0, 1);		hidewin(sc);		splx(cs);		break;	case TIOCMGET:		setwin(sc,0);		port->imodem=bc->mstat;		hidewin(sc);		tiocm_xxx = TIOCM_LE;	/* XXX - always enabled while open */		DPRINT3(DB_MODEM,"dgb%d: port%d: modem stat -- ",unit,pnum);		if (port->imodem & DTR) {			DPRINT1(DB_MODEM,"DTR ");			tiocm_xxx |= TIOCM_DTR;		}		if (port->imodem & RTS) {			DPRINT1(DB_MODEM,"RTS ");			tiocm_xxx |= TIOCM_RTS;		}		if (port->imodem & CTS) {			DPRINT1(DB_MODEM,"CTS ");			tiocm_xxx |= TIOCM_CTS;		}		if (port->imodem & port->dcd) {			DPRINT1(DB_MODEM,"DCD ");			tiocm_xxx |= TIOCM_CD;		}		if (port->imodem & port->dsr) {			DPRINT1(DB_MODEM,"DSR ");			tiocm_xxx |= TIOCM_DSR;		}		if (port->imodem & RI) {			DPRINT1(DB_MODEM,"RI ");			tiocm_xxx |= TIOCM_RI;		}		*(int *)data = tiocm_xxx;		DPRINT1(DB_MODEM,"--\n");		break;	case TIOCMSDTRWAIT:		/* must be root since the wait applies to following logins */		error = suser(p->p_ucred, &p->p_acflag);		if (error != 0) {			splx(s);			return (error);		}		port->close_delay = *(int *)data * hz / 100;		break;	case TIOCMGDTRWAIT:		*(int *)data = port->close_delay * 100 / hz;		break;	case TIOCTIMESTAMP:		port->do_timestamp = TRUE;		*(struct timeval *)data = port->timestamp;		break;	case TIOCDCDTIMESTAMP:		port->do_dcd_timestamp = TRUE;		*(struct timeval *)data = port->dcd_timestamp;		break;	default:		bmws_set(ws);		splx(s);		return ENOTTY;	}	bmws_set(ws);	splx(s);	return 0;}static void wakeflush(p)	void *p;{	struct dgb_p *port=p;	wakeup(&port->draining);}/* wait for the output to drain */static intdgbdrain(port)	struct dgb_p	*port;{	struct dgb_softc *sc=&dgb_softc[port->unit];	volatile struct board_chan *bc=port->brdchan;	int error;	int head, tail;	BoardMemWinState ws=bmws_get();	setwin(sc,0);	bc->iempty=1;	tail=bc->tout;	head=bc->tin;	while(tail!=head) {		DPRINT5(DB_WR,"dgb%d: port%d: drain: head=%d tail=%d\n",			port->unit, port->pnum, head, tail);		hidewin(sc);		port->draining=1;		timeout(wakeflush,port, hz);		error=tsleep(&port->draining, TTIPRI | PCATCH, "dgdrn", 0);		port->draining=0;		setwin(sc,0);		if (error != 0) {			DPRINT4(DB_WR,"dgb%d: port%d: tsleep(dgdrn) error=%d\n",				port->unit,port->pnum,error);			bc->iempty=0;			bmws_set(ws);			return error;		}		tail=bc->tout;		head=bc->tin;	}	DPRINT5(DB_WR,"dgb%d: port%d: drain: head=%d tail=%d\n",		port->unit, port->pnum, head, tail);	bmws_set(ws);	return 0;}/* wait for the output to drain *//* or simply clear the buffer it it's stopped */static voiddgb_drain_or_flush(port)	struct dgb_p	*port;{	struct tty *tp=port->tty;	struct dgb_softc *sc=&dgb_softc[port->unit];	volatile struct board_chan *bc=port->brdchan;	int error;	int lasttail;	int head, tail;	setwin(sc,0);	lasttail=-1;	bc->iempty=1;	tail=bc->tout;	head=bc->tin;	while(tail!=head /* && tail!=lasttail */ ) {		DPRINT5(DB_WR,"dgb%d: port%d: flush: head=%d tail=%d\n",			port->unit, port->pnum, head, tail);		/* if there is no carrier simply clean the buffer */		if( !(tp->t_state & TS_CARR_ON) ) {			bc->tout=bc->tin=0;			bc->iempty=0;			hidewin(sc);			return;		}		hidewin(sc);		port->draining=1;		timeout(wakeflush,port, hz);		error=tsleep(&port->draining, TTIPRI | PCATCH, "dgfls", 0);		port->draining=0;		setwin(sc,0);		if (error != 0) {			DPRINT4(DB_WR,"dgb%d: port%d: tsleep(dgfls) error=%d\n",				port->unit,port->pnum,error);			/* silently clean the buffer */			bc->tout=bc->tin=0;			bc->iempty=0;			hidewin(sc);			return;		}		lasttail=tail;		tail=bc->tout;		head=bc->tin;	}	hidewin(sc);	DPRINT5(DB_WR,"dgb%d: port%d: flush: head=%d tail=%d\n",			port->unit, port->pnum, head, tail);}static intdgbparam(tp, t)	struct tty	*tp;	struct termios	*t;{	int dev=tp->t_dev;	int mynor=minor(dev);	int unit=MINOR_TO_UNIT(dev);	int pnum=MINOR_TO_PORT(dev);	struct dgb_softc *sc=&dgb_softc[unit];	struct dgb_p *port=&sc->ports[pnum];	volatile struct board_chan *bc=port->brdchan;	int cflag;	int head;	int mval;	int iflag;	int hflow;	int s,cs;	BoardMemWinState ws=bmws_get();	DPRINT6(DB_PARAM,"dgb%d: port%d: dgbparm c=0x%x i=0x%x l=0x%x\n",unit,pnum,t->c_cflag,t->c_iflag,t->c_lflag);	if(port->mustdrain) {		DPRINT3(DB_PARAM,"dgb%d: port%d: must call dgbdrain()\n",unit,pnum);		dgbdrain(port);	}	cflag=ttspeedtab(t->c_ospeed, dgbspeedtab);	if (t->c_ispeed == 0)		t->c_ispeed = t->c_ospeed;	if (cflag < 0 /* || cflag > 0 && t->c_ispeed != t->c_ospeed */) {		DPRINT4(DB_PARAM,"dgb%d: port%d: invalid cflag=0%o\n",unit,pnum,cflag);		return (EINVAL);	}	cs=splclock();	setwin(sc,0);	if(cflag==0) { /* hangup */		DPRINT3(DB_PARAM,"dgb%d: port%d: hangup\n",unit,pnum);		head=bc->rin;		bc->rout=head;		head=bc->tin;		fepcmd(port, STOUT, (unsigned)head, 0, 0, 0);		mval= port->omodem & ~(DTR|RTS);	} else {		cflag |= dgbflags(dgb_cflags, t->c_cflag);		if(cflag!=port->fepcflag) {			port->fepcflag=cflag;			DPRINT6(DB_PARAM,"dgb%d: port%d: set cflag=0x%x c=0x%x\n",					unit,pnum,cflag&(FEP_CBAUD|FEP_FASTBAUD),cflag,					t->c_cflag&~CRTSCTS);			fepcmd(port, SETCTRLFLAGS, (unsigned)cflag, 0, 0, 0);		}		mval= port->omodem | (DTR|RTS);	}	iflag=dgbflags(dgb_iflags, t->c_iflag);	if(iflag!=port->fepiflag) {		port->fepiflag=iflag;		DPRINT5(DB_PARAM,"dgb%d: port%d: set iflag=0x%x c=0x%x\n",unit,pnum,iflag,t->c_iflag);		fepcmd(port, SETIFLAGS, (unsigned)iflag, 0, 0, 0);	}	bc->mint=port->dcd;	hflow=dgbflags(dgb_flow, t->c_cflag);	if(hflow!=port->hflow) {		port->hflow=hflow;		DPRINT5(DB_PARAM,"dgb%d: port%d: set hflow=0x%x f=0x%x\n",unit,pnum,hflow,t->c_cflag&CRTSCTS);		fepcmd(port, SETHFLOW, (unsigned)hflow, 0xff, 0, 1);	}		if(port->omodem != mval) {		DPRINT5(DB_PARAM,"dgb%d: port%d: setting modem parameters 0x%x was 0x%x\n",			unit,pnum,mval,port->omodem);		port->omodem=mval;		fepcmd(port, SETMODEM, (unsigned)mval, RTS|DTR, 0, 1);	}	if(port->fepstartc!=t->c_cc[VSTART] || port->fepstopc!=t->c_cc[VSTOP]) {		DPRINT5(DB_PARAM,"dgb%d: port%d: set startc=%d, stopc=%d\n",unit,pnum,t->c_cc[VSTART],t->c_cc[VSTOP]);		port->fepstartc=t->c_cc[VSTART];		port->fepstopc=t->c_cc[VSTOP];		fepcmd(port, SONOFFC, port->fepstartc, port->fepstopc, 0, 1);	}	bmws_set(ws);	splx(cs);	return 0;}static voiddgbstart(tp)	struct tty	*tp;{	int unit;	int pnum;	struct dgb_p *port;	struct dgb_softc *sc;	volatile struct board_chan *bc;	int head, tail;	int size, ocount;	int s;	int wmask;	BoardMemWinState ws=bmws_get();	unit=MINOR_TO_UNIT(minor(tp->t_dev));	pnum=MINOR_TO_PORT(minor(tp->t_dev));	sc=&dgb_softc[unit];	port=&sc->ports[pnum];	bc=port->brdchan;	wmask=port->txbufsize-1;	s=spltty();	while( tp->t_outq.c_cc!=0 ) {		int cs;#ifndef TS_ASLEEP	/* post 2.0.5 FreeBSD */		ttwwakeup(tp);#else		if(tp->t_outq.c_cc <= tp->t_lowat) {			if(tp->t_state & TS_ASLEEP) {				tp->t_state &= ~TS_ASLEEP;				wakeup(TSA_OLOWAT(tp));			}			/*selwakeup(&tp->t_wsel);*/		}#endif		cs=splclock();		setwin(sc,0);		head=bc->tin & wmask;		do { tail=bc->tout; } while (tail != bc->tout);		tail=bc->tout & wmask;		DPRINT5(DB_WR,"dgb%d: port%d: s tx head=%d tail=%d\n",unit,pnum,head,tail);#ifdef LEAVE_FREE_CHARS 		if(tail>head) {			size=tail-head-LEAVE_FREE_CHARS;			if (size <0)			        size==0;		        } else {			        size=port->txbufsize-head;			        if(tail+port->txbufsize < head)				        size==0;		        }		}#else		if(tail>head)			size=tail-head-1;		else {			size=port->txbufsize-head/*-1*/;			if(tail==0)				size--;		}#endif		if(size==0) {			bc->iempty=1; bc->ilow=1;			splx(cs);			bmws_set(ws);			tp->t_state|=TS_BUSY;			splx(s);			return;		}		towin(sc,port->txwin);		ocount=q_to_b(&tp->t_outq, port->txptr+head, size);		head+=ocount;		if(head>=port->txbufsize)			head-=port->txbufsize;		setwin(sc,0);		bc->tin=head;		DPRINT5(DB_WR,"dgb%d: port%d: tx avail=%d count=%d\n",unit,pnum,size,ocount);		hidewin(sc);		splx(cs);	}	bmws_set(ws);	splx(s);#ifndef TS_ASLEEP	/* post 2.0.5 FreeBSD */	if(tp->t_state & TS_BUSY) {			tp->t_state&=~TS_BUSY;		linesw[tp->t_line].l_start(tp);		ttwwakeup(tp);	}#else	if(tp->t_state & TS_ASLEEP) {		tp->t_state &= ~TS_ASLEEP;		wakeup(TSA_OLOWAT(tp));	}	tp->t_state&=~TS_BUSY;#endif}voiddgbstop(tp, rw)	struct tty	*tp;	int		rw;{	int unit;	int pnum;	struct dgb_p *port;	struct dgb_softc *sc;	volatile struct board_chan *bc;	int head;	int s;	BoardMemWinState ws=bmws_get();	DPRINT3(DB_WR,"dgb%d: port%d: stop\n",port->unit, port->pnum);	unit=MINOR_TO_UNIT(minor(tp->t_dev));	pnum=MINOR_TO_PORT(minor(tp->t_dev));	sc=&dgb_softc[unit];	port=&sc->ports[pnum];	bc=port->brdchan;	s = spltty();	setwin(sc,0);	if (rw & FWRITE) {		/* clear output queue */		bc->tout=bc->tin=0;		bc->ilow=0;bc->iempty=0;	}	if (rw & FREAD) {		/* clear input queue */		bc->rout=bc->rin;		bc->idata=1;	}	hidewin(sc);	bmws_set(ws);	splx(s);	dgbstart(tp);}struct tty *dgbdevtotty(dev)	dev_t	dev;{	int mynor, pnum, unit;	struct dgb_softc *sc;	mynor = minor(dev);	if (mynor & CONTROL_MASK)		return (NULL);	unit = MINOR_TO_UNIT(mynor);	if ((u_int) unit >= NDGB)		return (NULL);	pnum = MINOR_TO_PORT(mynor);	sc = &dgb_softc[unit];	if (pnum >= sc->numports)		return (NULL);	return (&sc->ttys[pnum]);}static void fepcmd(port, cmd, op1, op2, ncmds, bytecmd)	struct dgb_p *port;	unsigned cmd, op1, op2, ncmds, bytecmd;{	struct dgb_softc *sc=&dgb_softc[port->unit];	u_char *mem=sc->vmem;	unsigned tail, head;	int count, n;	if(port->status==DISABLED) {		printf("dgb%d: port%d: FEP command on disabled port\n", 			port->unit, port->pnum);		return;	}	/* setwin(sc,0); Require this to be set by caller */	head=sc->mailbox->cin;	if(head>=(FEP_CMAX-FEP_CSTART) || (head & 3)) {		printf("dgb%d: port%d: wrong pointer head of command queue : 0x%x\n",			port->unit, port->pnum, head);		return;	}	mem[head+FEP_CSTART+0]=cmd;	mem[head+FEP_CSTART+1]=port->pnum;	if(bytecmd) {		mem[head+FEP_CSTART+2]=op1;		mem[head+FEP_CSTART+3]=op2;	} else {		mem[head+FEP_CSTART+2]=op1&0xff;		mem[head+FEP_CSTART+3]=(op1>>8)&0xff;	}	DPRINT7(DB_FEP,"dgb%d: port%d: %s cmd=0x%x op1=0x%x op2=0x%x\n", port->unit, port->pnum,			(bytecmd)?"byte":"word", cmd, mem[head+FEP_CSTART+2], mem[head+FEP_CSTART+3]);	head=(head+4) & (FEP_CMAX-FEP_CSTART-4);	sc->mailbox->cin=head;	count=FEPTIMEOUT;	while (count-- != 0) {		head=sc->mailbox->cin;		tail=sc->mailbox->cout;		n = (head-tail) & (FEP_CMAX-FEP_CSTART-4);		if(n <= ncmds * (sizeof(ushort)*4))			return;	}	printf("dgb%d(%d): timeout on FEP cmd=0x%x\n", port->unit, port->pnum, cmd);}static void disc_optim(tp, t)	struct tty	*tp;	struct termios	*t;{	/*	 * XXX can skip a lot more cases if Smarts.  Maybe	 * (IGNCR | ISTRIP | IXON) in c_iflag.  But perhaps we	 * shouldn't skip if (TS_CNTTB | TS_LNCH) is set in t_state.	 */	if (!(t->c_iflag & (ICRNL | IGNCR | IMAXBEL | INLCR | ISTRIP | IXON))	    && (!(t->c_iflag & BRKINT) || (t->c_iflag & IGNBRK))	    && (!(t->c_iflag & PARMRK)		|| (t->c_iflag & (IGNPAR | IGNBRK)) == (IGNPAR | IGNBRK))	    && !(t->c_lflag & (ECHO | ICANON | IEXTEN | ISIG | PENDIN))	    && linesw[tp->t_line].l_rint == ttyinput)		tp->t_state |= TS_CAN_BYPASS_L_RINT;	else		tp->t_state &= ~TS_CAN_BYPASS_L_RINT;}static dgb_devsw_installed = 0;static void dgb_drvinit(void *unused){	dev_t dev;	if( ! dgb_devsw_installed ) {		dev = makedev(CDEV_MAJOR, 0);		cdevsw_add(&dev,&dgb_cdevsw, NULL);		dgb_devsw_installed = 1;    	}}SYSINIT(dgbdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,dgb_drvinit,NULL)#endif /* NDGB > 0 */

⌨️ 快捷键说明

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