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

📄 dgb.c

📁 freebsd v4.4内核源码
💻 C
📖 第 1 页 / 共 4 页
字号:
	DPRINT3(DB_CLOSE,"dgb%d: port%d: draining port\n",unit,pnum);        dgb_drain_or_flush(port);	s=spltty();	port->closing=1;	DPRINT3(DB_CLOSE,"dgb%d: port%d: closing line disc\n",unit,pnum);	linesw[tp->t_line].l_close(tp,flag);	disc_optim(tp,&tp->t_termios);	DPRINT3(DB_CLOSE,"dgb%d: port%d: hard closing\n",unit,pnum);	dgbhardclose(port);	DPRINT3(DB_CLOSE,"dgb%d: port%d: closing tty\n",unit,pnum);	ttyclose(tp);	port->closing=0;	wakeup(&port->closing);	port->used=0;	/* mark the card idle when all ports are closed */	for(i=0; i<sc->numports; i++)		if(sc->ports[i].used)			break;	splx(s);	DPRINT3(DB_CLOSE,"dgb%d: port%d: closed\n",unit,pnum);	wakeup(TSA_CARR_ON(tp));	wakeup(&port->active_out);	port->active_out=0;	DPRINT3(DB_CLOSE,"dgb%d: port%d: close exit\n",unit,pnum);	return 0;}static voiddgbhardclose(port)	struct dgb_p *port;{	struct dgb_softc *sc=&dgb_softc[port->unit];	volatile struct board_chan *bc=port->brdchan;	int cs;	cs=splclock();	port->do_timestamp = 0;	setwin(sc,0);	bc->idata=0; bc->iempty=0; bc->ilow=0;	if(port->tty->t_cflag & HUPCL) {		port->omodem &= ~(RTS|DTR);		fepcmd(port, SETMODEM, 0, DTR|RTS, 0, 1);	}	hidewin(sc);	splx(cs);	timeout(dgb_pause, &port->brdchan, hz/2);	tsleep(&port->brdchan, TTIPRI | PCATCH, "dgclo", 0);}static void dgb_pause(chan)	void *chan;{wakeup((caddr_t)chan);}static	intdgbread(dev, uio, flag)	dev_t		dev;	struct uio	*uio;	int		flag;{	int		mynor;	struct tty	*tp;	int error, unit, pnum;	mynor=minor(dev);	if (mynor & CONTROL_MASK)		return (ENODEV);	unit=MINOR_TO_UNIT(mynor);	pnum=MINOR_TO_PORT(mynor);	tp=&dgb_softc[unit].ttys[pnum];	error=linesw[tp->t_line].l_read(tp, uio, flag);	DPRINT4(DB_RD,"dgb%d: port%d: read() returns %d\n",unit,pnum,error);	return error;}static	intdgbwrite(dev, uio, flag)	dev_t		dev;	struct uio	*uio;	int		flag;{	int		mynor;	struct tty	*tp;	int error, unit, pnum;	mynor=minor(dev);	if (mynor & CONTROL_MASK)		return (ENODEV);	unit=MINOR_TO_UNIT(mynor);	pnum=MINOR_TO_PORT(mynor);	tp=&dgb_softc[unit].ttys[pnum];	error=linesw[tp->t_line].l_write(tp, uio, flag);	DPRINT4(DB_WR,"dgb%d: port%d: write() returns %d\n",unit,pnum,error);	return error;}static voiddgbpoll(unit_c)	void *unit_c;{	int unit=(int)unit_c;	int pnum;	struct dgb_p *port;	struct dgb_softc *sc=&dgb_softc[unit];	int head, tail;	u_char *eventbuf;	int event, mstat, lstat;	volatile struct board_chan *bc;	struct tty *tp;	int rhead, rtail;	int whead, wtail;	int size;	int c=0;	u_char *ptr;	int ocount;	int ibuf_full,obuf_full;	BoardMemWinState ws=bmws_get();	if(sc->status==DISABLED) {		printf("dgb%d: polling of disabled board stopped\n",unit);		return;	}		setwin(sc,0);	head=sc->mailbox->ein;	tail=sc->mailbox->eout;	while(head!=tail) {		if(head >= FEP_IMAX-FEP_ISTART 		|| tail >= FEP_IMAX-FEP_ISTART 		|| (head|tail) & 03 ) {			printf("dgb%d: event queue's head or tail is wrong! hd=%d,tl=%d\n", unit,head,tail);			break;		}		eventbuf=sc->vmem+tail+FEP_ISTART;		pnum=eventbuf[0];		event=eventbuf[1];		mstat=eventbuf[2];		lstat=eventbuf[3];		port=&sc->ports[pnum];		bc=port->brdchan;		tp=&sc->ttys[pnum];		if(pnum>=sc->numports || port->status==DISABLED) {			printf("dgb%d: port%d: got event on nonexisting port\n",unit,pnum);		} else if(port->used || port->wopeners>0 ) {			int wrapmask=port->rxbufsize-1;			if( !(event & ALL_IND) ) 				printf("dgb%d: port%d: ? event 0x%x mstat 0x%x lstat 0x%x\n",					unit, pnum, event, mstat, lstat);			if(event & DATA_IND) {				DPRINT3(DB_DATA,"dgb%d: port%d: DATA_IND\n",unit,pnum);				rhead=bc->rin & wrapmask; 				rtail=bc->rout & wrapmask;				if( !(tp->t_cflag & CREAD) || !port->used ) {					bc->rout=rhead;					goto end_of_data;				}				if(bc->orun) {					printf("dgb%d: port%d: overrun\n", unit, pnum);					bc->orun=0;				}				if(!(tp->t_state & TS_ISOPEN))					goto end_of_data;				for(ibuf_full=FALSE;rhead!=rtail && !ibuf_full;) {					DPRINT5(DB_RXDATA,"dgb%d: port%d: p rx head=%d tail=%d\n",						unit,pnum,rhead,rtail);					if(rhead>rtail)						size=rhead-rtail;					else						size=port->rxbufsize-rtail;					ptr=port->rxptr+rtail;/* Helg: */					if( tp->t_rawq.c_cc + size > DGB_IBUFSIZE ) {						size=DGB_IBUFSIZE-tp->t_rawq.c_cc;						DPRINT1(DB_RXDATA,"*");						ibuf_full=TRUE;					}					if(size) {						/*if (0) {*/						if (tp->t_state & TS_CAN_BYPASS_L_RINT) {							DPRINT1(DB_RXDATA,"!");							towin(sc,port->rxwin);							tk_nin += size;							tk_rawcc += size;							tp->t_rawcc += size;							b_to_q(ptr,size,&tp->t_rawq);							setwin(sc,0);						} else {							int i=size;							unsigned char chr;							do {								towin(sc,port->rxwin);								chr= *ptr++;								hidewin(sc);							       (*linesw[tp->t_line].l_rint)(chr, tp);							} while (--i > 0 );							setwin(sc,0);						}	 				}					rtail= (rtail + size) & wrapmask;					bc->rout=rtail;					rhead=bc->rin & wrapmask;					hidewin(sc);					ttwakeup(tp);					setwin(sc,0);				}			end_of_data:			}			if(event & MODEMCHG_IND) {				DPRINT3(DB_MODEM,"dgb%d: port%d: MODEMCHG_IND\n",unit,pnum);				port->imodem=mstat;				if(mstat & port->dcd) {					hidewin(sc);					linesw[tp->t_line].l_modem(tp,1);					setwin(sc,0);					wakeup(TSA_CARR_ON(tp));				} else {					hidewin(sc);					linesw[tp->t_line].l_modem(tp,0);					setwin(sc,0);					if( port->draining) {						port->draining=0;						wakeup(&port->draining);					}				}			}			if(event & BREAK_IND) {				if((tp->t_state & TS_ISOPEN) && (tp->t_iflag & IGNBRK))	{				        DPRINT3(DB_BREAK,"dgb%d: port%d: BREAK_IND\n",unit,pnum);				        hidewin(sc);				        linesw[tp->t_line].l_rint(TTY_BI, tp);				        setwin(sc,0);			        }			}/* Helg: with output flow control */			if(event & (LOWTX_IND | EMPTYTX_IND) ) {				DPRINT3(DB_TXDATA,"dgb%d: port%d: LOWTX_IND or EMPTYTX_IND\n",unit,pnum);				if( (event & EMPTYTX_IND ) && tp->t_outq.c_cc==0				&& port->draining) {					port->draining=0;					wakeup(&port->draining);					bc->ilow=0; bc->iempty=0;				} else {					int wrapmask=port->txbufsize-1;					for(obuf_full=FALSE; tp->t_outq.c_cc!=0 && !obuf_full; ) {						int s;						/* add "last-minute" data to write buffer */						if(!(tp->t_state & TS_BUSY)) {							hidewin(sc);#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					                setwin(sc,0);				                }						s=spltty();					whead=bc->tin & wrapmask;					wtail=bc->tout & wrapmask;					if(whead<wtail)						size=wtail-whead-1;					else {						size=port->txbufsize-whead;						if(wtail==0)							size--;					}					if(size==0) {						DPRINT5(DB_WR,"dgb: head=%d tail=%d size=%d full=%d\n",							whead,wtail,size,obuf_full);						bc->iempty=1; bc->ilow=1;						obuf_full=TRUE;						splx(s);						break;					}					towin(sc,port->txwin);					ocount=q_to_b(&tp->t_outq, port->txptr+whead, size);					whead+=ocount;					setwin(sc,0);					bc->tin=whead;					bc->tin=whead & wrapmask;					splx(s);				}				if(obuf_full) {					DPRINT1(DB_WR," +BUSY\n");					tp->t_state|=TS_BUSY;				} else {					DPRINT1(DB_WR," -BUSY\n");					hidewin(sc);#ifndef TS_ASLEEP	/* post 2.0.5 FreeBSD */					/* should clear TS_BUSY before ttwwakeup */					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				        setwin(sc,0);				        }			        }			end_of_buffer:			}			bc->idata=1;   /* require event on incoming data */ 		} else {			bc=port->brdchan;			DPRINT4(DB_EXCEPT,"dgb%d: port%d: got event 0x%x on closed port\n",				unit,pnum,event);			bc->rout=bc->rin;			bc->idata=bc->iempty=bc->ilow=0;		}		tail= (tail+4) & (FEP_IMAX-FEP_ISTART-4);	}	sc->mailbox->eout=tail;	bmws_set(ws);	timeout(dgbpoll, unit_c, hz/POLLSPERSEC);}#if 0static voiddgbintr(unit)	int	unit;{}#endifstatic	intdgbioctl(dev, cmd, data, flag, p)	dev_t		dev;	int		cmd;	caddr_t		data;	int		flag;	struct proc	*p;{	struct dgb_softc *sc;	int unit, pnum;	struct dgb_p *port;	int mynor;	struct tty *tp;	volatile struct board_chan *bc;	int error;	int s,cs;	int tiocm_xxx;#if defined(COMPAT_43) || defined(COMPAT_SUNOS)	int		oldcmd;	struct termios	term;#endif	BoardMemWinState ws=bmws_get();	mynor=minor(dev);	unit=MINOR_TO_UNIT(mynor);	pnum=MINOR_TO_PORT(mynor);	sc=&dgb_softc[unit];	port=&sc->ports[pnum];	tp=&sc->ttys[pnum];	bc=port->brdchan;	if (mynor & CONTROL_MASK) {		struct termios *ct;		switch (mynor & CONTROL_MASK) {		case CONTROL_INIT_STATE:			ct = mynor & CALLOUT_MASK ? &port->it_out : &port->it_in;			break;		case CONTROL_LOCK_STATE:			ct = mynor & CALLOUT_MASK ? &port->lt_out : &port->lt_in;			break;		default:			return (ENODEV);	/* /dev/nodev */		}		switch (cmd) {		case TIOCSETA:			error = suser(p->p_ucred, &p->p_acflag);			if (error != 0)				return (error);			*ct = *(struct termios *)data;			return (0);		case TIOCGETA:			*(struct termios *)data = *ct;			return (0);		case TIOCGETD:			*(int *)data = TTYDISC;			return (0);		case TIOCGWINSZ:			bzero(data, sizeof(struct winsize));			return (0);		default:			return (ENOTTY);		}	}#if defined(COMPAT_43) || defined(COMPAT_SUNOS)	term = tp->t_termios;	if (cmd == TIOCSETA || cmd == TIOCSETAW || cmd == TIOCSETAF) {	  DPRINT6(DB_PARAM,"dgb%d: port%d: dgbioctl-ISNOW c=0x%x i=0x%x l=0x%x\n",unit,pnum,term.c_cflag,term.c_iflag,term.c_lflag);	}	oldcmd = cmd;	error = ttsetcompat(tp, &cmd, data, &term);	if (error != 0)		return (error);	if (cmd != oldcmd)		data = (caddr_t)&term;#endif	if (cmd == TIOCSETA || cmd == TIOCSETAW || cmd == TIOCSETAF) {		int	cc;		struct termios *dt = (struct termios *)data;		struct termios *lt = mynor & CALLOUT_MASK				     ? &port->lt_out : &port->lt_in;		DPRINT6(DB_PARAM,"dgb%d: port%d: dgbioctl-TOSET c=0x%x i=0x%x l=0x%x\n",unit,pnum,dt->c_cflag,dt->c_iflag,dt->c_lflag);		dt->c_iflag = (tp->t_iflag & lt->c_iflag)			      | (dt->c_iflag & ~lt->c_iflag);		dt->c_oflag = (tp->t_oflag & lt->c_oflag)			      | (dt->c_oflag & ~lt->c_oflag);		dt->c_cflag = (tp->t_cflag & lt->c_cflag)			      | (dt->c_cflag & ~lt->c_cflag);		dt->c_lflag = (tp->t_lflag & lt->c_lflag)			      | (dt->c_lflag & ~lt->c_lflag);		for (cc = 0; cc < NCCS; ++cc)			if (lt->c_cc[cc] != 0)				dt->c_cc[cc] = tp->t_cc[cc];		if (lt->c_ispeed != 0)			dt->c_ispeed = tp->t_ispeed;		if (lt->c_ospeed != 0)			dt->c_ospeed = tp->t_ospeed;	}	if(cmd==TIOCSTOP) {		cs=splclock();		setwin(sc,0);		fepcmd(port, PAUSETX, 0, 0, 0, 0);		bmws_set(ws);		splx(cs);		return 0;	} else if(cmd==TIOCSTART) {		cs=splclock();		setwin(sc,0);		fepcmd(port, RESUMETX, 0, 0, 0, 0);		bmws_set(ws);		splx(cs);		return 0;	}	if(cmd==TIOCSETAW || cmd==TIOCSETAF)		port->mustdrain=1;	error = linesw[tp->t_line].l_ioctl(tp, cmd, data, flag, p);	if (error >= 0)		return error;	s = spltty();	error = ttioctl(tp, cmd, data, flag);	disc_optim(tp,&tp->t_termios);	port->mustdrain=0;	if (error >= 0) {		splx(s);		if (cmd == TIOCSETA || cmd == TIOCSETAW || cmd == TIOCSETAF) {			DPRINT6(DB_PARAM,"dgb%d: port%d: dgbioctl-RES c=0x%x i=0x%x l=0x%x\n",unit,pnum,tp->t_cflag,tp->t_iflag,tp->t_lflag);		}		return error;	}	switch (cmd) {	case TIOCSBRK:/* Helg: commented *//*		error=dgbdrain(port);*/		if(error!=0) {			splx(s);			return error;		}		cs=splclock();		setwin(sc,0);			/* now it sends 250 millisecond break because I don't know */		/* how to send an infinite break */		fepcmd(port, SENDBREAK, 250, 0, 10, 0);		hidewin(sc);		splx(cs);		break;	case TIOCCBRK:		/* now it's empty */		break;	case TIOCSDTR:		DPRINT3(DB_MODEM,"dgb%d: port%d: set DTR\n",unit,pnum);		port->omodem |= DTR;		cs=splclock();		setwin(sc,0);		fepcmd(port, SETMODEM, port->omodem, RTS, 0, 1);		if( !(bc->mstat & DTR) ) {			DPRINT3(DB_MODEM,"dgb%d: port%d: DTR is off\n",unit,pnum);		}		hidewin(sc);		splx(cs);		break;	case TIOCCDTR:		DPRINT3(DB_MODEM,"dgb%d: port%d: reset DTR\n",unit,pnum);		port->omodem &= ~DTR;		cs=splclock();		setwin(sc,0);		fepcmd(port, SETMODEM, port->omodem, RTS|DTR, 0, 1);		if( bc->mstat & DTR ) {			DPRINT3(DB_MODEM,"dgb%d: port%d: DTR is on\n",unit,pnum);		}		hidewin(sc);		splx(cs);		break;	case TIOCMSET:		if(*(int *)data & TIOCM_DTR)			port->omodem |=DTR;		else			port->omodem &=~DTR;

⌨️ 快捷键说明

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