xref: /original-bsd/sys/vax/uba/dmf.c (revision b9d18e58)
1 /*
2  * Copyright (c) 1982 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  *
6  *	@(#)dmf.c	6.19 (Berkeley) 04/12/86
7  */
8 
9 #include "dmf.h"
10 #if NDMF > 0
11 /*
12  * DMF32 driver
13  *
14  *
15  * TODO:
16  *	test with modem
17  *	load as much as possible into silo
18  *	use auto XON/XOFF
19  *	test reset code
20  ****************************
21  * DMF32 line printer driver
22  *
23  * the line printer on dmfx is indicated by a minor device code of 128+x
24  *
25  * the flags field of the config file is interpreted like so:
26  * bits		meaning
27  * ----		-------
28  * 0-7		soft carrier bits for ttys part of dmf32
29  * 8-15		number of cols/line on the line printer
30  *			if 0, 132 will be used.
31  * 16-23	number of lines/page on the line printer
32  *			if 0, 66 will be used.
33  * 24		if 1 DO NOT use the auto format mode of the
34  *			line printer parallel port
35  */
36 #include "../machine/pte.h"
37 
38 #include "bk.h"
39 #include "uba.h"
40 #include "param.h"
41 #include "conf.h"
42 #include "dir.h"
43 #include "user.h"
44 #include "proc.h"
45 #include "ioctl.h"
46 #include "tty.h"
47 #include "map.h"
48 #include "buf.h"
49 #include "vm.h"
50 #include "bkmac.h"
51 #include "clist.h"
52 #include "file.h"
53 #include "uio.h"
54 #include "kernel.h"
55 #include "syslog.h"
56 
57 #include "ubareg.h"
58 #include "ubavar.h"
59 #include "dmfreg.h"
60 
61 /*
62  * Definition of the driver for the auto-configuration program.
63  */
64 int	dmfprobe(), dmfattach(), dmfrint(), dmfxint();
65 int	dmflint();
66 struct	uba_device *dmfinfo[NDMF];
67 u_short	dmfstd[] = { 0 };
68 struct	uba_driver dmfdriver =
69 	{ dmfprobe, 0, dmfattach, 0, dmfstd, "dmf", dmfinfo };
70 
71 int	dmf_timeout = 10;		/* silo timeout, in ms */
72 int	dmf_mindma = 4;			/* don't dma below this point */
73 
74 /*
75  * Local variables for the driver
76  */
77 char	dmf_speeds[] =
78 	{ 0, 0, 1, 2, 3, 4, 0, 5, 6, 7, 010, 012, 014, 016, 017, 0 };
79 
80 #ifndef	PORTSELECTOR
81 #define	ISPEED	B9600
82 #define	IFLAGS	(EVENP|ODDP|ECHO)
83 #else
84 #define	ISPEED	B4800
85 #define	IFLAGS	(EVENP|ODDP)
86 #endif
87 
88 struct	tty dmf_tty[NDMF*8];
89 char	dmfsoftCAR[NDMF];
90 
91 struct dmfl_softc {
92 	u_int	dmfl_state; 		/* soft state bits */
93 	int	dmfl_info;		/* uba info */
94 	u_short	dmfl_lines;		/* lines per page (66 def.) */
95 	u_short	dmfl_cols; 		/* cols per line (132 def.) */
96 	u_short	dmfl_format;		/* fflag for auto form feed */
97 	char	dmfl_buf[DMFL_BUFSIZ];
98 } dmfl_softc[NDMF];
99 
100 /*
101  * convert device number into DMF line printer unit number
102  */
103 #define	DMFL_UNIT(d)	(minor(d)&0xF)	/* up to 16 DMFs */
104 
105 #define ASLP 1		/* waiting for interrupt from dmf */
106 #define OPEN 2		/* line printer is open */
107 #define ERROR 4		/* error while printing, driver
108 			 refuses to do anything till closed */
109 #define MOREIO 8	/* more data for printer */
110 
111 #ifndef lint
112 int	ndmf = NDMF*8;			/* used by iostat */
113 #endif
114 int	dmfact;				/* mask of active dmf's */
115 int	dmfstart(), ttrstrt();
116 
117 /*
118  * The clist space is mapped by the driver onto each UNIBUS.
119  * The UBACVT macro converts a clist space address for unibus uban
120  * into an i/o space address for the DMA routine.
121  */
122 int	dmf_ubinfo[NUBA];		/* info about allocated unibus map */
123 int	cbase[NUBA];			/* base address in unibus map */
124 #define	UBACVT(x, uban)		(cbase[uban] + ((x)-(char *)cfree))
125 char	dmf_dma[NDMF*8];
126 
127 /*
128  * Routine for configuration to set dmf interrupt.
129  */
130 /*ARGSUSED*/
131 dmfprobe(reg, ctlr)
132 	caddr_t reg;
133 	struct uba_device *ctlr;
134 {
135 	register int br, cvec;		/* these are ``value-result'' */
136 	register struct dmfdevice *dmfaddr = (struct dmfdevice *)reg;
137 	register int i;
138 	register unsigned int a;
139 	static char *dmfdevs[]=
140 		{"parallel","printer","synch","asynch"};
141 	unsigned int dmfoptions;
142 	static int (*intrv[3])() = { (int (*)())0, (int (*)())0, (int (*)())0 };
143 
144 #ifdef lint
145 	br = 0; cvec = br; br = cvec;
146 	dmfxint(0); dmfrint(0);
147 	dmfsrint(); dmfsxint(); dmfdaint(); dmfdbint(); dmflint(0);
148 #endif
149 	/*
150 	 * Pick the usual size DMF vector here (don't decrement it here).
151 	 * grab configuration; note that the DMF32
152 	 * doesn't seem to put the right bits in this
153 	 * register until AFTER the interrupt vector is set.
154 	 */
155 	br = 0x15;
156 	cvec = (uba_hd[numuba].uh_lastiv - 4*8);
157 	dmfaddr->dmfccsr0 = (cvec >> 2);
158 	dmfoptions = dmfaddr->dmfccsr0 & DMFC_CONFMASK;
159 
160 	/* catch a couple of special cases:  Able vmz/32n and vmz/lp	*/
161 	if (dmfoptions == DMFC_ASYNC) {
162 		/* Async portion only */
163 
164 		cvec = (uba_hd[numuba].uh_lastiv -= 8);
165 		dmfaddr->dmfccsr0 = (cvec - 2*8) >> 2;
166 		intrv[0] = ctlr->ui_intr[4];
167 		intrv[1] = ctlr->ui_intr[5];
168 		ctlr->ui_intr = intrv;
169 	} else if (dmfoptions == DMFC_LP) {
170 		/* LP portion only */
171 
172 		cvec = (uba_hd[numuba].uh_lastiv -= 8);
173 		ctlr->ui_intr = &ctlr->ui_intr[6];
174 	} else if (dmfoptions == (DMFC_LP|DMFC_ASYNC)) {
175 		/* LP ans Async portions only */
176 
177 		cvec = (uba_hd[numuba].uh_lastiv -= 2*8);
178 		ctlr->ui_intr = &ctlr->ui_intr[4];
179 	} else {
180 		/* All other configurations get everything */
181 
182 		cvec = (uba_hd[numuba].uh_lastiv -= 4*8);
183 	}
184 	a = (dmfoptions >> 12) & 0xf;
185 	printf("dmf%d:", ctlr->ui_unit);
186 	for (i = 0; a != 0; ++i, a >>= 1) {
187 		if (a & 1)
188 			printf(" %s",dmfdevs[i]);
189 	}
190 	printf(".\n");
191 
192 	if (dmfoptions & DMFC_LP)
193 		dmfaddr->dmfl_ctrl = DMFL_RESET;
194 	return (sizeof (struct dmfdevice));
195 }
196 
197 /*
198  * Routine called to attach a dmf.
199  */
200 dmfattach(ui)
201 	struct uba_device *ui;
202 {
203 	register int cols = (ui->ui_flags>>8) & 0xff;
204 	register int lines = (ui->ui_flags>>16) & 0xff;
205 
206 	dmfsoftCAR[ui->ui_unit] = ui->ui_flags & 0xff;
207 	dmfl_softc[ui->ui_unit].dmfl_cols = cols == 0 ? DMFL_DEFCOLS : cols;
208 	dmfl_softc[ui->ui_unit].dmfl_lines = lines == 0 ? DMFL_DEFLINES : lines;
209  	if ((ui->ui_flags >> 24) & 0x1)
210  		dmfl_softc[ui->ui_unit].dmfl_format = (2 << 8);
211  	else
212  		dmfl_softc[ui->ui_unit].dmfl_format = (2 << 8) | DMFL_FORMAT;
213 	cbase[ui->ui_ubanum] = -1;
214 }
215 
216 
217 /*
218  * Open a DMF32 line, mapping the clist onto the uba if this
219  * is the first dmf on this uba.  Turn on this dmf if this is
220  * the first use of it.
221  */
222 /*ARGSUSED*/
223 dmfopen(dev, flag)
224 	dev_t dev;
225 {
226 	register struct tty *tp;
227 	register int unit, dmf;
228 	register struct dmfdevice *addr;
229 	register struct uba_device *ui;
230 	int s;
231 
232 	unit = minor(dev);
233 	if (unit & 0200)
234 		return (dmflopen(dev,flag));
235 	dmf = unit >> 3;
236 	if (unit >= NDMF*8 || (ui = dmfinfo[dmf])== 0 || ui->ui_alive == 0)
237 		return (ENXIO);
238 	tp = &dmf_tty[unit];
239 	if (tp->t_state&TS_XCLUDE && u.u_uid!=0)
240 		return (EBUSY);
241 	addr = (struct dmfdevice *)ui->ui_addr;
242 	tp->t_addr = (caddr_t)addr;
243 	tp->t_oproc = dmfstart;
244 	tp->t_state |= TS_WOPEN;
245 	/*
246 	 * While setting up state for this uba and this dmf,
247 	 * block uba resets which can clear the state.
248 	 */
249 	s = spltty();
250 	if (cbase[ui->ui_ubanum] == -1) {
251 		dmf_ubinfo[ui->ui_ubanum] =
252 		    uballoc(ui->ui_ubanum, (caddr_t)cfree,
253 			nclist*sizeof(struct cblock), 0);
254 		cbase[ui->ui_ubanum] = UBAI_ADDR(dmf_ubinfo[ui->ui_ubanum]);
255 	}
256 	if ((dmfact&(1<<dmf)) == 0) {
257 		addr->dmfcsr |= DMF_IE;
258 		dmfact |= (1<<dmf);
259 		addr->dmfrsp = dmf_timeout;
260 	}
261 	splx(s);
262 	/*
263 	 * If this is first open, initialize tty state to default.
264 	 */
265 	if ((tp->t_state&TS_ISOPEN) == 0) {
266 		ttychars(tp);
267 #ifndef PORTSELECTOR
268 		if (tp->t_ispeed == 0) {
269 #else
270 			tp->t_state |= TS_HUPCLS;
271 #endif PORTSELECTOR
272 			tp->t_ispeed = ISPEED;
273 			tp->t_ospeed = ISPEED;
274 			tp->t_flags = IFLAGS;
275 #ifndef PORTSELECTOR
276 		}
277 #endif PORTSELECTOR
278 		dmfparam(unit);
279 	}
280 	/*
281 	 * Wait for carrier, then process line discipline specific open.
282 	 */
283 	s = spltty();
284 	for (;;) {
285 		if ((dmfmctl(dev, DMF_ON, DMSET) & (DMF_CAR<<8)) ||
286 		    (dmfsoftCAR[dmf] & (1<<(unit&07))))
287 			tp->t_state |= TS_CARR_ON;
288 		if (tp->t_state & TS_CARR_ON)
289 			break;
290 		tp->t_state |= TS_WOPEN;
291 		sleep((caddr_t)&tp->t_rawq, TTIPRI);
292 	}
293 	splx(s);
294 	return ((*linesw[tp->t_line].l_open)(dev, tp));
295 }
296 
297 /*
298  * Close a DMF32 line.
299  */
300 /*ARGSUSED*/
301 dmfclose(dev, flag)
302 	dev_t dev;
303 	int flag;
304 {
305 	register struct tty *tp;
306 	register unit;
307 
308 	unit = minor(dev);
309 	if (unit & 0200) {
310 		dmflclose(dev,flag);
311 		return;
312 	}
313 
314 	tp = &dmf_tty[unit];
315 	(*linesw[tp->t_line].l_close)(tp);
316 	(void) dmfmctl(unit, DMF_BRK, DMBIC);
317 	if (tp->t_state&TS_HUPCLS || (tp->t_state&TS_ISOPEN)==0)
318 		(void) dmfmctl(unit, DMF_OFF, DMSET);
319 	ttyclose(tp);
320 }
321 
322 dmfread(dev, uio)
323 	dev_t dev;
324 	struct uio *uio;
325 {
326 	register struct tty *tp;
327 
328 	if (minor(dev) & 0200)
329 		return(ENXIO);
330 	tp = &dmf_tty[minor(dev)];
331 	return ((*linesw[tp->t_line].l_read)(tp, uio));
332 }
333 
334 dmfwrite(dev, uio)
335 	dev_t dev;
336 	struct uio *uio;
337 {
338 	register struct tty *tp;
339 
340 	if (minor(dev) & 0200)
341 		return (dmflwrite(dev,uio));
342 	tp = &dmf_tty[minor(dev)];
343 	return ((*linesw[tp->t_line].l_write)(tp, uio));
344 }
345 
346 /*
347  * DMF32 receiver interrupt.
348  */
349 dmfrint(dmf)
350 	int dmf;
351 {
352 	register c;
353 	register struct tty *tp;
354 	register struct dmfdevice *addr;
355 	register struct tty *tp0;
356 	int unit;
357 	int overrun = 0;
358 	register struct uba_device *ui;
359 
360 	ui = dmfinfo[dmf];
361 	if (ui == 0 || ui->ui_alive == 0)
362 		return;
363 	addr = (struct dmfdevice *)ui->ui_addr;
364 	tp0 = &dmf_tty[dmf * 8];
365 	/*
366 	 * Loop fetching characters from the silo for this
367 	 * dmf until there are no more in the silo.
368 	 */
369 	while ((c = addr->dmfrbuf) < 0) {
370 
371 		unit = (c >> 8) & 07;
372 		tp = tp0 + unit;
373 		if (c & DMF_DSC) {
374 			addr->dmfcsr = DMF_IE | DMFIR_TBUF | unit;
375 			if (addr->dmfrms & DMF_CAR)
376 				(void)(*linesw[tp->t_line].l_modem)(tp, 1);
377 			else if ((dmfsoftCAR[dmf] & (1 << unit)) == 0 &&
378 			    (*linesw[tp->t_line].l_modem)(tp, 0) == 0) {
379 				addr->dmfcsr = DMF_IE | DMFIR_LCR | unit;
380 				addr->dmflctms = DMFLCR_ENA;
381 			}
382 			continue;
383 		}
384 		if ((tp->t_state&TS_ISOPEN) == 0) {
385 			wakeup((caddr_t)&tp->t_rawq);
386 #ifdef PORTSELECTOR
387 			if ((tp->t_state & TS_WOPEN) == 0)
388 #endif
389 				continue;
390 		}
391 		if (c & (DMF_PE|DMF_DO|DMF_FE)) {
392 			if (c & DMF_PE)
393 				if ((tp->t_flags & (EVENP|ODDP)) == EVENP
394 			 	|| (tp->t_flags & (EVENP|ODDP)) == ODDP)
395 					continue;
396 			if ((c & DMF_DO) && overrun == 0) {
397 				log(LOG_WARNING, "dmf%d: silo overflow\n", dmf);
398 				overrun = 1;
399 			}
400 			if (c & DMF_FE)
401 				/*
402 			 	* At framing error (break) generate
403 			 	* a null (in raw mode, for getty), or a
404 			 	* interrupt (in cooked/cbreak mode).
405 			 	*/
406 				if (tp->t_flags & RAW)
407 					c = 0;
408 				else
409 					c = tp->t_intrc;
410 		}
411 #if NBK > 0
412 		if (tp->t_line == NETLDISC) {
413 			c &= 0177;
414 			BKINPUT(c, tp);
415 		} else
416 #endif
417 			(*linesw[tp->t_line].l_rint)(c, tp);
418 	}
419 }
420 
421 /*
422  * Ioctl for DMF32.
423  */
424 /*ARGSUSED*/
425 dmfioctl(dev, cmd, data, flag)
426 	dev_t dev;
427 	caddr_t data;
428 {
429 	register struct tty *tp;
430 	register int unit = minor(dev);
431 	int error;
432 
433 	if (unit & 0200)
434 		return (ENOTTY);
435 	tp = &dmf_tty[unit];
436 	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
437 	if (error >= 0)
438 		return (error);
439 	error = ttioctl(tp, cmd, data, flag);
440 	if (error >= 0) {
441 		if (cmd == TIOCSETP || cmd == TIOCSETN || cmd == TIOCLBIS ||
442 		    cmd == TIOCLBIC || cmd == TIOCLSET)
443 			dmfparam(unit);
444 		return (error);
445 	}
446 	switch (cmd) {
447 
448 	case TIOCSBRK:
449 		(void) dmfmctl(dev, DMF_BRK, DMBIS);
450 		break;
451 
452 	case TIOCCBRK:
453 		(void) dmfmctl(dev, DMF_BRK, DMBIC);
454 		break;
455 
456 	case TIOCSDTR:
457 		(void) dmfmctl(dev, DMF_DTR|DMF_RTS, DMBIS);
458 		break;
459 
460 	case TIOCCDTR:
461 		(void) dmfmctl(dev, DMF_DTR|DMF_RTS, DMBIC);
462 		break;
463 
464 	case TIOCMSET:
465 		(void) dmfmctl(dev, dmtodmf(*(int *)data), DMSET);
466 		break;
467 
468 	case TIOCMBIS:
469 		(void) dmfmctl(dev, dmtodmf(*(int *)data), DMBIS);
470 		break;
471 
472 	case TIOCMBIC:
473 		(void) dmfmctl(dev, dmtodmf(*(int *)data), DMBIC);
474 		break;
475 
476 	case TIOCMGET:
477 		*(int *)data = dmftodm(dmfmctl(dev, 0, DMGET));
478 		break;
479 
480 	default:
481 		return (ENOTTY);
482 	}
483 	return (0);
484 }
485 
486 dmtodmf(bits)
487 	register int bits;
488 {
489 	register int b;
490 
491 	b = bits & 012;
492 	if (bits & DML_ST) b |= DMF_RATE;
493 	if (bits & DML_RTS) b |= DMF_RTS;
494 	if (bits & DML_USR) b |= DMF_USRW;
495 	return(b);
496 }
497 
498 dmftodm(bits)
499 	register int bits;
500 {
501 	register int b;
502 
503 	b = (bits & 012) | ((bits >> 7) & 0760) | DML_LE;
504 	if (bits & DMF_USRR) b |= DML_USR;
505 	if (bits & DMF_RTS) b |= DML_RTS;
506 	return(b);
507 }
508 
509 
510 /*
511  * Set parameters from open or stty into the DMF hardware
512  * registers.
513  */
514 dmfparam(unit)
515 	register int unit;
516 {
517 	register struct tty *tp;
518 	register struct dmfdevice *addr;
519 	register int lpar, lcr;
520 	int s;
521 
522 	tp = &dmf_tty[unit];
523 	addr = (struct dmfdevice *)tp->t_addr;
524 	/*
525 	 * Block interrupts so parameters will be set
526 	 * before the line interrupts.
527 	 */
528 	s = spltty();
529 	addr->dmfcsr = (unit&07) | DMFIR_LCR | DMF_IE;
530 	if ((tp->t_ispeed)==0) {
531 		tp->t_state |= TS_HUPCLS;
532 		(void) dmfmctl(unit, DMF_OFF, DMSET);
533 		splx(s);
534 		return;
535 	}
536 	lpar = (dmf_speeds[tp->t_ospeed]<<12) | (dmf_speeds[tp->t_ispeed]<<8);
537 	lcr = DMFLCR_ENA;
538 	if ((tp->t_ispeed) == B134)
539 		lpar |= BITS6|PENABLE;
540 	else if (tp->t_flags & (RAW|LITOUT|PASS8))
541 		lpar |= BITS8;
542 	else {
543 		lpar |= BITS7|PENABLE;
544 		/* CHECK FOR XON/XOFF AND SET lcr |= DMF_AUTOX; */
545 	}
546 	if (tp->t_flags&EVENP)
547 		lpar |= EPAR;
548 	if ((tp->t_ospeed) == B110)
549 		lpar |= TWOSB;
550 	lpar |= (unit&07);
551 	addr->dmflpr = lpar;
552 	addr->dmflctms = (addr->dmflctms &~ 0xff) | lcr;
553 	splx(s);
554 }
555 
556 /*
557  * DMF32 transmitter interrupt.
558  * Restart the idle line.
559  */
560 dmfxint(dmf)
561 	int dmf;
562 {
563 	int unit0 = dmf * 8;
564 	struct tty *tp0 = &dmf_tty[unit0];
565 	register struct tty *tp;
566 	register struct dmfdevice *addr;
567 	register struct uba_device *ui;
568 	register int t;
569 	short cntr;
570 
571 	ui = dmfinfo[dmf];
572 	addr = (struct dmfdevice *)ui->ui_addr;
573 	while ((t = addr->dmfcsr) & DMF_TI) {
574 		if (t & DMF_NXM)
575 			/* SHOULD RESTART OR SOMETHING... */
576 			printf("dmf%d: NXM line %d\n", dmf, t >> 8 & 7);
577 		t = t >> 8 & 7;
578 		tp = tp0 + t;
579 		tp->t_state &= ~TS_BUSY;
580 		if (tp->t_state&TS_FLUSH)
581 			tp->t_state &= ~TS_FLUSH;
582 		else if (dmf_dma[unit0 + t]) {
583 			/*
584 			 * Do arithmetic in a short to make up
585 			 * for lost 16&17 bits.
586 			 */
587 			addr->dmfcsr = DMFIR_TBA | DMF_IE | t;
588 			cntr = addr->dmftba -
589 			    UBACVT(tp->t_outq.c_cf, ui->ui_ubanum);
590 			ndflush(&tp->t_outq, (int)cntr);
591 		}
592 		if (tp->t_line)
593 			(*linesw[tp->t_line].l_start)(tp);
594 		else
595 			dmfstart(tp);
596 	}
597 }
598 
599 /*
600  * Start (restart) transmission on the given DMF32 line.
601  */
602 dmfstart(tp)
603 	register struct tty *tp;
604 {
605 	register struct dmfdevice *addr;
606 	register int unit, nch;
607 	int s;
608 	register int dmf;
609 
610 	unit = minor(tp->t_dev);
611 	dmf = unit >> 3;
612 	unit &= 07;
613 	addr = (struct dmfdevice *)tp->t_addr;
614 
615 	/*
616 	 * Must hold interrupts in following code to prevent
617 	 * state of the tp from changing.
618 	 */
619 	s = spltty();
620 	/*
621 	 * If it's currently active, or delaying, no need to do anything.
622 	 */
623 	if (tp->t_state&(TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
624 		goto out;
625 	/*
626 	 * If there are still characters in the silo,
627 	 * just reenable the transmitter.
628 	 */
629 	addr->dmfcsr = DMF_IE | DMFIR_TBUF | unit;
630 	if (addr->dmftsc) {
631 		addr->dmfcsr = DMF_IE | DMFIR_LCR | unit;
632 		addr->dmflctms = addr->dmflctms | DMF_TE;
633 		tp->t_state |= TS_BUSY;
634 		goto out;
635 	}
636 	/*
637 	 * If there are sleepers, and output has drained below low
638 	 * water mark, wake up the sleepers.
639 	 */
640 	if (tp->t_outq.c_cc<=TTLOWAT(tp)) {
641 		if (tp->t_state&TS_ASLEEP) {
642 			tp->t_state &= ~TS_ASLEEP;
643 			wakeup((caddr_t)&tp->t_outq);
644 		}
645 		if (tp->t_wsel) {
646 			selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
647 			tp->t_wsel = 0;
648 			tp->t_state &= ~TS_WCOLL;
649 		}
650 	}
651 	/*
652 	 * Now restart transmission unless the output queue is
653 	 * empty.
654 	 */
655 	if (tp->t_outq.c_cc == 0)
656 		goto out;
657 	if (tp->t_flags & (RAW|LITOUT))
658 		nch = ndqb(&tp->t_outq, 0);
659 	else {
660 		if ((nch = ndqb(&tp->t_outq, 0200)) == 0) {
661 			/*
662 		 	* If first thing on queue is a delay process it.
663 		 	*/
664 			nch = getc(&tp->t_outq);
665 			timeout(ttrstrt, (caddr_t)tp, (nch&0x7f)+6);
666 			tp->t_state |= TS_TIMEOUT;
667 			goto out;
668 		}
669 	}
670 	/*
671 	 * If characters to transmit, restart transmission.
672 	 */
673 	if (nch >= dmf_mindma) {
674 		register car;
675 
676 		dmf_dma[minor(tp->t_dev)] = 1;
677 		addr->dmfcsr = DMF_IE | DMFIR_LCR | unit;
678 		addr->dmflctms = addr->dmflctms | DMF_TE;
679 		car = UBACVT(tp->t_outq.c_cf, dmfinfo[dmf]->ui_ubanum);
680 		addr->dmfcsr = DMF_IE | DMFIR_TBA | unit;
681 		addr->dmftba = car;
682 		addr->dmftcc = ((car >> 2) & 0xc000) | nch;
683 		tp->t_state |= TS_BUSY;
684 	} else if (nch) {
685 		register char *cp = tp->t_outq.c_cf;
686 		register int i;
687 
688 		dmf_dma[minor(tp->t_dev)] = 0;
689 		nch = MIN(nch, DMF_SILOCNT);
690 		addr->dmfcsr = DMF_IE | DMFIR_LCR | unit;
691 		addr->dmflctms = addr->dmflctms | DMF_TE;
692 		addr->dmfcsr = DMF_IE | DMFIR_TBUF | unit;
693 		for (i = 0; i < nch; i++)
694 			addr->dmftbuf = *cp++;
695 		ndflush(&tp->t_outq, nch);
696 		tp->t_state |= TS_BUSY;
697 	}
698 out:
699 	splx(s);
700 }
701 
702 /*
703  * Stop output on a line, e.g. for ^S/^Q or output flush.
704  */
705 /*ARGSUSED*/
706 dmfstop(tp, flag)
707 	register struct tty *tp;
708 {
709 	register struct dmfdevice *addr;
710 	register unit = minor(tp->t_dev) & 7;
711 	int s;
712 
713 	addr = (struct dmfdevice *)tp->t_addr;
714 	/*
715 	 * Block input/output interrupts while messing with state.
716 	 */
717 	s = spltty();
718 	if (flag) {
719 		addr->dmfcsr = DMF_IE | DMFIR_TBUF | unit;
720 		if (addr->dmftsc) {
721 			/*
722 			 * Flush regardless of whether we're transmitting
723 			 * (TS_BUSY), if the silo contains untransmitted
724 			 * characters.
725 			 */
726 			addr->dmfcsr = DMFIR_LCR | unit | DMF_IE;
727 			addr->dmflctms = addr->dmflctms | DMF_TE | DMF_FLUSH;
728 			/* this will interrupt so let dmfxint handle the rest */
729 			tp->t_state |= TS_FLUSH|TS_BUSY;
730 		}
731 	} else {
732 		if (tp->t_state & TS_BUSY) {
733 			/*
734 			 * Stop transmission by disabling
735 			 * the transmitter.  We'll pick up where we
736 			 * left off by reenabling in dmfstart.
737 			 */
738 			addr->dmfcsr = DMFIR_LCR | unit | DMF_IE;
739 			addr->dmflctms = addr->dmflctms &~ DMF_TE;
740 			/* no interrupt here */
741 			tp->t_state &= ~TS_BUSY;
742 		}
743 	}
744 	splx(s);
745 }
746 
747 /*
748  * DMF32 modem control
749  */
750 dmfmctl(dev, bits, how)
751 	dev_t dev;
752 	int bits, how;
753 {
754 	register struct dmfdevice *dmfaddr;
755 	register int unit, mbits, lcr;
756 	int s;
757 
758 	unit = minor(dev);
759 	dmfaddr = (struct dmfdevice *)(dmf_tty[unit].t_addr);
760 	unit &= 07;
761 	s = spltty();
762 	dmfaddr->dmfcsr = DMF_IE | DMFIR_TBUF | unit;
763 	mbits = dmfaddr->dmfrms << 8;
764 	dmfaddr->dmfcsr = DMF_IE | DMFIR_LCR | unit;
765 	lcr = dmfaddr->dmflctms;
766 	mbits |= (lcr & 0xff00) >> 8;
767 	switch (how) {
768 	case DMSET:
769 		mbits = (mbits &0xff00) | bits;
770 		break;
771 
772 	case DMBIS:
773 		mbits |= bits;
774 		break;
775 
776 	case DMBIC:
777 		mbits &= ~bits;
778 		break;
779 
780 	case DMGET:
781 		(void) splx(s);
782 		return(mbits);
783 	}
784 	if (mbits & DMF_BRK)
785 		lcr |= DMF_RBRK;
786 	else
787 		lcr &= ~DMF_RBRK;
788 	dmfaddr->dmflctms = ((mbits & 037) << 8) | (lcr & 0xff);
789 	(void) splx(s);
790 	return(mbits);
791 }
792 
793 /*
794  * Reset state of driver if UBA reset was necessary.
795  * Reset the csr, lpr, and lcr registers on open lines, and
796  * restart transmitters.
797  */
798 dmfreset(uban)
799 	int uban;
800 {
801 	register int dmf, unit;
802 	register struct tty *tp;
803 	register struct uba_device *ui;
804 	register struct dmfdevice *addr;
805 	int i;
806 
807 	for (dmf = 0; dmf < NDMF; dmf++) {
808 		ui = dmfinfo[dmf];
809 		if (ui == 0 || ui->ui_alive == 0 || ui->ui_ubanum != uban)
810 			continue;
811 		printf(" dmf%d", dmf);
812 		if (dmf_ubinfo[uban]) {
813 			dmf_ubinfo[uban] = uballoc(uban, (caddr_t)cfree,
814 			    nclist*sizeof (struct cblock), 0);
815 			cbase[uban] = UBAI_ADDR(dmf_ubinfo[uban]);
816 		}
817 		addr = (struct dmfdevice *)ui->ui_addr;
818 		addr->dmfcsr = DMF_IE;
819 		addr->dmfrsp = dmf_timeout;
820 		unit = dmf * 8;
821 		for (i = 0; i < 8; i++) {
822 			tp = &dmf_tty[unit];
823 			if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) {
824 				dmfparam(unit);
825 				(void) dmfmctl(unit, DMF_ON, DMSET);
826 				tp->t_state &= ~TS_BUSY;
827 				dmfstart(tp);
828 			}
829 			unit++;
830 		}
831 	}
832 }
833 
834 /*
835  * dmflopen -- open the line printer port on a dmf32
836  */
837 /* ARGSUSED */
838 dmflopen(dev, flag)
839 	dev_t dev;
840 	int flag;
841 {
842 	register int dmf;
843 	register struct dmfl_softc *sc;
844 	register struct uba_device *ui;
845 	register struct dmfdevice *addr;
846 
847 	dmf = DMFL_UNIT(dev);
848 	if (dmf >= NDMF || (ui = dmfinfo[dmf]) == 0 || ui->ui_alive == 0)
849 		return (ENXIO);
850 	sc = &dmfl_softc[dmf];
851 	if (sc->dmfl_state & OPEN)
852 		return (EBUSY);
853 	addr = (struct dmfdevice *)ui->ui_addr;
854 	if (addr->dmfl_ctrl & DMFL_OFFLINE) {
855 #ifdef notdef
856 		log(LOG_WARNING, "dmf%d: line printer offline/jammed\n",
857 			dmf);
858 #endif
859 		return (EIO);
860 	}
861 	if ((addr->dmfl_ctrl & DMFL_CONV)) {
862 		log(LOG_WARNING, "dmf%d: line printer disconnected\n", dmf);
863 		return (EIO);
864 	}
865 
866 	addr->dmfl_ctrl = 0;
867 	sc->dmfl_state |= OPEN;
868 	return (0);
869 }
870 
871 /* ARGSUSED */
872 dmflclose(dev, flag)
873 	dev_t dev;
874 	int flag;
875 {
876 	register int dmf = DMFL_UNIT(dev);
877 	register struct dmfl_softc *sc = &dmfl_softc[dmf];
878 	register struct uba_device *ui = dmfinfo[dmf];
879 
880 	sc->dmfl_state = 0;
881 	if (sc->dmfl_info != 0)
882 		ubarelse((int)ui->ui_ubanum, &sc->dmfl_info);
883 
884 	((struct dmfdevice *)ui->ui_addr)->dmfl_ctrl = 0;
885 }
886 
887 dmflwrite(dev, uio)
888 	dev_t dev;
889 	struct uio *uio;
890 {
891 	register int n;
892 	register int error;
893 	register struct dmfl_softc *sc;
894 
895 	sc = &dmfl_softc[DMFL_UNIT(dev)];
896 	if (sc->dmfl_state & ERROR)
897 		return (EIO);
898 	while (n = (unsigned)uio->uio_resid) {
899 		if (n > DMFL_BUFSIZ) {
900 			n = DMFL_BUFSIZ;
901 			sc->dmfl_state |= MOREIO;
902 		} else
903 			sc->dmfl_state &= ~MOREIO;
904 		if (error = uiomove(sc->dmfl_buf, (int)n, UIO_WRITE, uio))
905 			return (error);
906 		if (error = dmflout(dev, sc->dmfl_buf, n))
907 			return (error);
908 	}
909 	return (0);
910 }
911 
912 
913 /*
914  * dmflout -- start io operation to dmf line printer
915  *		cp is addr of buf of n chars to be sent.
916  *
917  *	-- dmf will be put in formatted output mode, this will
918  *		be selectable from an ioctl if the
919  *		need ever arises.
920  */
921 dmflout(dev, cp, n)
922 	dev_t dev;
923 	char *cp;
924 	int n;
925 {
926 	register struct dmfl_softc *sc;
927 	register int dmf;
928 	register struct uba_device *ui;
929 	register struct dmfdevice *d;
930 	int s;
931 
932 	dmf = DMFL_UNIT(dev);
933 	sc = &dmfl_softc[dmf];
934 	if (sc->dmfl_state & ERROR)
935 		return (EIO);
936 	ui = dmfinfo[dmf];
937 	/*
938 	 * allocate unibus resources, will be released when io
939 	 * operation is done.
940 	 */
941 	if (sc->dmfl_info == 0)
942 		sc->dmfl_info = uballoc(ui->ui_ubanum, cp, n, 0);
943 	d = (struct dmfdevice *)ui->ui_addr;
944 	d->dmfl_ctrl = sc->dmfl_format;		/* indir reg 2 */
945 	/* indir reg auto increments on r/w */
946 	/* SO DON'T CHANGE THE ORDER OF THIS CODE */
947 	d->dmfl_indrct = 0;			/* prefix chars & num */
948 	d->dmfl_indrct = 0;			/* suffix chars & num */
949 	d->dmfl_indrct = sc->dmfl_info; 	/* dma lo 16 bits addr */
950 	d->dmfl_indrct = -n;			/* number of chars */
951 
952 	d->dmfl_indrct = ((sc->dmfl_info>>16)&3) | DMFL_OPTIONS;
953 						/* dma hi 2 bits addr */
954 	d->dmfl_indrct = sc->dmfl_lines 	/* lines per page */
955 		| (sc->dmfl_cols<<8);		/* carriage width */
956 	sc->dmfl_state |= ASLP;
957 	s = spltty();
958 	d->dmfl_ctrl |= DMFL_PEN | DMFL_IE;
959 	while (sc->dmfl_state & ASLP) {
960 		sleep(sc->dmfl_buf, PZERO + 8);
961 		while (sc->dmfl_state & ERROR) {
962 			timeout(dmflint, (caddr_t)dmf, 10 * hz);
963 			sleep((caddr_t)&sc->dmfl_state, PZERO + 8);
964 		}
965 	}
966 	splx(s);
967 	return (0);
968 }
969 
970 /*
971  * dmflint -- handle an interrupt from the line printer part of the dmf32
972  */
973 dmflint(dmf)
974 	int dmf;
975 {
976 	register struct uba_device *ui;
977 	register struct dmfl_softc *sc;
978 	register struct dmfdevice *d;
979 	short dmfl_stats;
980 
981 	ui = dmfinfo[dmf];
982 	sc = &dmfl_softc[dmf];
983 	d = (struct dmfdevice *)ui->ui_addr;
984 
985 	d->dmfl_ctrl &= ~DMFL_IE;
986 	dmfl_stats = d->dmfl_ctrl;
987 	if (sc->dmfl_state & ERROR) {
988 		if ((dmfl_stats & DMFL_OFFLINE) == 0)
989 			sc->dmfl_state &= ~ERROR;
990 		wakeup((caddr_t)&sc->dmfl_state);
991 		return;
992 	}
993 	if (dmfl_stats & DMFL_DMAERR)
994 		log(LOG_WARNING, "dmf%d: NXM\n", dmf);
995 	if (dmfl_stats & DMFL_OFFLINE) {
996 		log(LOG_WARNING, "dmf%d: printer error\n", dmf);
997 		sc->dmfl_state |= ERROR;
998 	}
999 #ifdef notdef
1000 	if (dmfl_stats & DMFL_PDONE) {
1001 		printf("bytes= %d\n", d->dmfl_indrct);
1002 		printf("lines= %d\n", d->dmfl_indrct);
1003 	}
1004 #endif
1005 	sc->dmfl_state &= ~ASLP;
1006 	wakeup((caddr_t)sc->dmfl_buf);
1007 	if (sc->dmfl_info && (sc->dmfl_state & MOREIO) == 0)
1008 		ubarelse(ui->ui_ubanum, &sc->dmfl_info);
1009 }
1010 
1011 /* stubs for interrupt routines for devices not yet supported */
1012 
1013 dmfsrint()
1014 {
1015 	printf("dmfsrint\n");
1016 }
1017 
1018 dmfsxint()
1019 {
1020 	printf("dmfsxint\n");
1021 }
1022 
1023 dmfdaint()
1024 {
1025 	printf("dmfdaint\n");
1026 }
1027 
1028 dmfdbint()
1029 {
1030 	printf("dmfdbint\n");
1031 }
1032 #endif NDMF
1033