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

📄 dmb.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Reset state of driver if BI reset was necessary. * Reset the csr and lpr registers on open lines, and * restart transmitters. */dmbreset(binum)	int binum;				/* bi adapter that reset */{	register int dmb, unit;	register struct tty *tp;	register struct uba_device *ui;	register struct dmb_device *addr;	register int i;	for (dmb = 0; dmb < nNDMB; dmb++)		{		ui = dmbinfo[dmb];		if (ui == 0 || ui->ui_alive == 0 || ui->ui_adpt != binum) 			continue;		printf(" dmb%d", dmb);		addr = (struct dmb_device *)ui->ui_addr;		/*		 * Enable external vector		 */		DMB_LOCK(dmb);		addr->dmb_biic.biic_int_ctrl |= BIIC_EXVEC;		addr->dmb_acsr2 = (dmb_timeout << 16);	/* 10 ms */		DMB_UNLOCK(dmb);		unit = dmb * NUMLINES;		for (i = 0; i < NUMLINES; i++)			{			tp = &dmb_tty[unit];			smp_lock(&tp->t_lk_tty,LK_RETRY);			if (tp->t_state & (TS_ISOPEN|TS_WOPEN))				{				DMB_LOCK(dmb);				dmbparam(unit); 	/* resets lpr reg */				DMB_UNLOCK(dmb);				tp->t_state &= ~TS_BUSY;				dmbstart(tp);				}			smp_unlock(&tp->t_lk_tty);			unit++; 		/* increment the line number */			}		}}/* * dmblopen -- open the line printer port on a dmb32 *//*ARGSUSED*/dmblopen(dev,flag)	dev_t dev;	int flag;{	register int dmb;	register struct dmbl_softc *sc;	register struct uba_device *ui;	register struct dmb_device *addr;	register int s;	dmb = minor(dev) & LINEMASK ;	if (dmb >= nNDMB)		return (ENXIO);	ui = dmbinfo[dmb];	sc = &dmbl_softc[dmb];	if ((sc->dmbl_state & OPEN) || (ui == 0) || (ui->ui_alive == 0) || (dmb_lines[ui->ui_unit] != DMB_8_LINES))		{		return(ENXIO);		}	addr = (struct dmb_device *)ui->ui_addr;#	ifdef DEBUG	if ((addr->dmb_pcsrhigh & DMB_PROFFLINE))		{		printd("dmb%d: line printer offline/jammed\n", dmb);		return(EIO);		}#	endif	if ((addr->dmb_pcsrhigh & DMB_PRCONNECT) == 0)		{		printf("dmb%d: line printer disconnected\n", dmb);		return(EIO);		}	/*	 * disable interrupts	 */	s = spltty();	DMB_LOCK(dmb);	addr->dmb_pcsrlow = 0;	sc->dmbl_state |= OPEN;	DMB_UNLOCK(dmb);	splx(s);	return(0);}/*ARGSUSED*/dmblclose(dev,flag)	dev_t dev;	int flag;{	register int dmb;	register struct dmbl_softc *sc;	register int s;	dmb = minor(dev) & LINEMASK;	sc = &dmbl_softc[dmb];	s = spltty();	DMB_LOCK(dmb);	/* If we're not waiting for something to complete, then           go ahead and print the form feed.  R. Craig Peterson */	if (!(sc->dmbl_state & ASLP))		dmblout(dev,"\f",1);	sc->dmbl_state = 0;	/*	 * disable interrupts	 */	((struct dmb_device *)(dmbinfo[dmb]->ui_addr))->dmb_pcsrlow = 0;	DMB_UNLOCK(dmb);	splx(s);	return(0);}dmblwrite(dev,uio)	dev_t dev;	struct uio *uio;{	register unsigned int n;	register int error;	register struct dmbl_softc *sc;	register int s, dmb;	dmb = minor(dev) & LINEMASK;	sc = &dmbl_softc[dmb];	if (sc->dmbl_state & ERROR)		return(EIO);	while(n = min(DMBL_BUFSIZE,(unsigned)uio->uio_resid))		{		if (error = uiomove(&sc->dmbl_buf[0],(int)n,UIO_WRITE,uio))			{			printf("uio move error\n");			return(error);			}		s = spltty();		DMB_LOCK(dmb);		error = dmblout(dev,&sc->dmbl_buf[0],n);		DMB_UNLOCK(dmb);		splx(s);		if (error)			return(error);		}	return(0);}/* * dmblout -- start io operation to dmb line printer *		cp is addr of buf of n chars to be sent. * *	-- dmb will NOT be put in formatted output mode, this will *		be selectable from an ioctl if the *		need ever arises. */dmblout(dev,cp,n)	dev_t dev;	char *cp;	int n;{	register struct dmbl_softc *sc;	register int dmb;	register struct uba_device *ui;	register struct dmb_device *addr;	dmb = minor(dev) & LINEMASK;	sc = &dmbl_softc[dmb];	if (sc->dmbl_state & ERROR)		return(EIO);	ui = dmbinfo[dmb];	addr = (struct dmb_device *)ui->ui_addr;	addr->dmb_pbufad = (long) svtophy(cp);	addr->dmb_pbufct = (n << DMB_PRCHARCT);	addr->dmb_psiz = (sc->dmbl_lines << DMB_PRPAGE) | (sc->dmbl_cols);	sc->dmbl_state |= ASLP;	addr->dmb_pcsrlow = DMB_PRIE;	addr->dmb_pctrl |= (DMB_PRSTART | DMB_PRPHYS);	while(sc->dmbl_state & ASLP)		{		sleep_unlock((caddr_t)&sc->dmbl_buf[0],(PZERO+8),&lk_dmb[dmb]);		spltty();		DMB_LOCK(dmb);		while(sc->dmbl_state&ERROR)			{			timeout(dmblint,dmb,10*hz);			sleep_unlock((caddr_t)&sc->dmbl_state,(PZERO+8),				&lk_dmb[dmb]);			spltty();			DMB_LOCK(dmb);			}		/*if (sc->dmbl_state&ERROR) return (EIO);*/		}	return(0);}/* * dmblint -- handle an interrupt from the line printer part of the dmb32 */dmblint(dmb)	register int dmb;{	register struct uba_device *ui;	register struct dmbl_softc *sc;	register struct dmb_device *addr;	register int s;	int post_wakeup = 0;	ui = dmbinfo[dmb];	sc = &dmbl_softc[dmb];	addr = (struct dmb_device *)ui->ui_addr;	s = spltty();	DMB_LOCK(dmb);	addr->dmb_pcsrlow = 0;		/* disable interrupts */	if (sc->dmbl_state & ERROR)		{#		ifdef DEBUG		printd("dmb%d: intr while in error state\n", dmb);#		endif		if ((addr->dmb_pcsrhigh & DMB_PROFFLINE) == 0)			sc->dmbl_state &= ~ERROR;		post_wakeup = WAKEUP_STATE;		goto dmbendlint;		}	if (addr->dmb_pctrl & DMB_PRERROR)		printf("dmb%d: Printer DMA Error %x\n", dmb,			((addr->dmb_pctrl & DMB_PRERROR)>>16));	if (addr->dmb_pcsrhigh & DMB_PROFFLINE)		{#		ifdef DEBUG		printd("dmb%d: printer offline\n", dmb);#		endif		sc->dmbl_state |= ERROR;		}#	ifdef DEBUG	if (addr->dmb_pctrl & DMB_PRSTART)		printd("DMB%d printer intr w/ DMA START still set\n", dmb);	else		{		printd("bytes= %d\n", addr->dmb_pcar & DMB_PRCHAR);		printd("lines= %d\n",addr->dmb_pcar & DMB_PRLINE);		}#	endif	sc->dmbl_state &= ~ASLP;	post_wakeup = WAKEUP_BUF;dmbendlint:	DMB_UNLOCK(dmb);	if (post_wakeup) {		if (post_wakeup & WAKEUP_STATE)			wakeup(&sc->dmbl_state);		else			wakeup(&sc->dmbl_buf[0]);	}	splx(s);}/* stub for synchronous device interrupt routine which is not supported */dmbsint() { printf("dmbsint\n"); }/* * Called from a timeout routine. */dmb_cd_drop(tp)	register struct tty *tp;{	register struct dmb_device *addr;	register int unit, dmb;	int post_wakeup;	unit = minor(tp->t_dev);	dmb = unit >> LINEBITS;	addr = (struct dmb_device *)tp->t_addr;	DMB_LOCK(dmb);	addr->dmb_acsr = DMB_IE | (unit&LINEMASK);	if ((tp->t_state&TS_CARR_ON) &&	   ((addr->dmb_lstatlow & DMB_DCD) == 0))		{#		ifdef DEBUG		printd("dmb_cd:  no CD, tp=0x%x\n", tp);#		endif		dmb_tty_drop(tp,&post_wakeup);		goto dmb_cd_end;		}	dmbmodem[unit] |= MODEM_CD;#	ifdef DEBUG	printd("dmb_cd:  CD is up, tp=0x%x\n", tp);#	endifdmb_cd_end:	DMB_UNLOCK(dmb);	if (post_wakeup)		wakeup((caddr_t)&tp->t_rawq);}/* * dmb_dsr_check_timeout * * Re-acquire locks on the tty line and multiplexer board before checking * to see if the modem signals are present.  If connection establishment * fails wakeup on the raw queue to allow another try. */dmb_dsr_check_timeout(tp) 	register struct tty *tp;{	register int s,dmb;	int post_wakeup = 0;	dmb = minor(tp->t_dev)>>LINEBITS;	DMB_TTY_LOCK(tp,s);	DMB_LOCK(dmb);	dmb_dsr_check(tp,&post_wakeup);	DMB_UNLOCK(dmb);	DMB_TTY_UNLOCK(tp,s);	if (post_wakeup)		wakeup((caddr_t)&tp->t_rawq);}/* * dmb_dsr_check * * When initiating a modem connection you must first leave the line idle for * 500ms.  If all the appropriate modem leads do not rise within 30 seconds * then throw in the towel. */dmb_dsr_check(tp,post_wakeup)	register struct tty *tp;	register int *post_wakeup;{	int unit;	register struct dmb_device *addr;	unit = minor(tp->t_dev);	addr = (struct dmb_device *)tp->t_addr;	/*	 * The line must remain dormant for the first 500ms.  Now that the	 * time period has expired, look to see if the appropriate modem	 * signals have been asserted to establish the connection.   	 */	if (dmbmodem[unit] & MODEM_DSR_START)		{		dmbmodem[unit] &= ~MODEM_DSR_START;		addr->dmb_acsr = DMB_IE | (unit&LINEMASK);	   	/* 	    	 * If dmbdsr is set look for DSR|CTS|CD, otherwise look 	    	 * for CD|CTS only.	    	 */		if (dmbdsr) {			if ((addr->dmb_lstatlow & DMB_XMIT) == DMB_XMIT)				dmb_start_tty(tp,post_wakeup);		}		else {			if ((addr->dmb_lstatlow & DMB_NODSR) == DMB_NODSR) 				dmb_start_tty(tp,post_wakeup);		}		return;		}	/*	 * CD has not come up within the 30 second interval.  Give up on	 * establishing this connection.	 */	if ((tp->t_state&TS_CARR_ON)==0)		{		dmb_tty_drop(tp,post_wakeup);#		ifdef DEBUG		printd("dmb_dsr: no carrier, tp=0x%x\n", tp);#		endif		}#	ifdef DEBUG	else		printd("dmb_dsr:  carrier is up, tp=0x%x\n", tp);#	endif}/* *  cd_down return 1 if carrier has been down for at least 2 secs. */dmb_cd_down(tp)	register struct tty *tp;{	register int msecs;	register int unit;	unit = minor(tp->t_dev);	msecs = 1000000 * (time.tv_sec - dmbtimestamp[unit].tv_sec) +		(time.tv_usec - dmbtimestamp[unit].tv_usec);	if (msecs > 2000000)		return(1);	else		return(0);}/* * dmb_tty_drop * * Close down a modem line by deasserting DTR.  Wakeup on rawq to allert * any processes which may be waiting for an open to succeed which has * timed out. */dmb_tty_drop(tp,post_wakeup)	register struct tty *tp;	register int *post_wakeup;{	register struct dmb_device *addr;	register int unit;	if (tp->t_flags&NOHANG)		return;	unit = minor(tp->t_dev);	dmbmodem[unit] = MODEM_BADCALL;	tp->t_state &= ~(TS_CARR_ON|TS_TTSTOP|TS_BUSY|TS_ISUSP);	*post_wakeup = WAKEUP_RAWQ;	gsignal(tp->t_pgrp, SIGHUP);	gsignal(tp->t_pgrp, SIGCONT);	addr = (struct dmb_device *)tp->t_addr;	addr->dmb_acsr = DMB_IE | ((minor(tp->t_dev)) & LINEMASK);	addr->dmb_lpr &= ~(DMB_DTR | DMB_RTS); /* turn off DTR & RTS */}/* * dmb_start_tty * * Mark line as usable after all modem control leads have been asserted. * Wakeup on rawq to allert processes which have been waiting for the open * to succeed. */dmb_start_tty(tp,post_wakeup)	register struct tty *tp;	register int *post_wakeup;{	register int unit = minor(tp->t_dev);	unit = minor(tp->t_dev);	tp->t_state &= ~TS_ONDELAY;	tp->t_state |= TS_CARR_ON;	if (dmbmodem[unit]&MODEM_DSR)		untimeout(dmb_dsr_check_timeout, tp);	dmbmodem[unit] |= MODEM_CD|MODEM_CTS|MODEM_DSR;	dmbtimestamp[unit] = dmbzerotime;	*post_wakeup = WAKEUP_RAWQ;}dmbbaudrate(speed)register int speed;{    if (dmb_valid_speeds & (1 << speed))	return(1);    else	return(0);}#endif

⌨️ 快捷键说明

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