xref: /original-bsd/sys/vax/uba/uu.c (revision 08eb28af)
1 /*
2  * Copyright (c) 1982, 1986 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  *	@(#)uu.c	7.5 (Berkeley) 12/16/90
7  */
8 
9 #include "uu.h"
10 #if NUU > 0
11 /*
12  * TU58 DECtape II/DL11 device driver
13  *
14  * The TU58 is treated as a block device (only).  Error detection and
15  * recovery is not very extensive, but sufficient to handle the most
16  * common errors. It is assumed that the TU58 will follow the RSP
17  * protocol exactly, very few protocol errors are checked for.
18  *
19  * To reduce interrupt latency, `options UUDMA' should be specified
20  * in the config file to make sure the `pseudo-DMA' code in locore.s
21  * will be compiled into the system. Otherwise overrun errors will
22  * occur frequently (these errors are not reported).
23  *
24  * TODO:
25  *
26  * - Add ioctl code to wind/rewind cassette
27  *
28  */
29 
30 #include "../include/pte.h"
31 
32 #include "sys/param.h"
33 #include "sys/systm.h"
34 #include "sys/buf.h"
35 #include "sys/conf.h"
36 #include "sys/time.h"
37 #include "sys/kernel.h"
38 #include "sys/errno.h"
39 #include "sys/file.h"
40 
41 #include "../include/cpu.h"
42 #include "../vax/nexus.h"
43 #include "../vax/rsp.h"
44 
45 #include "ubavar.h"
46 #include "ubareg.h"
47 #include "uureg.h"
48 
49 #define	NTUBLK	512		/* number of blocks on a TU58 cassette */
50 #define	WRV     01              /* bit in minor dev => write w. read verify */
51 #define	NDPC	02		/* drives per controller */
52 #define	NUX	NDPC * NUU	/* number of drives */
53 #define	NUUQ	02		/* # of block which can be queued up */
54 #define	UMASK	01		/* unit number mask */
55 #define UUIPL	0x14		/* ipl level to use */
56 
57 struct packet uucmd[NUU];	/* a command sent to the TU58 */
58 struct packet uudata[NUU];	/* a command or data returned from TU58 */
59 struct buf uitab[NUU];		/* buffer queue headers */
60 
61 /*
62  * Driver soft carrier structure
63  */
64 struct uu_softc {
65 	u_char	*tu_rbptr;	/* pointer to buffer for read */
66 	int	tu_rcnt;	/* how much to read */
67 	u_char	*tu_wbptr;	/* pointer to buffer for write */
68 	int	tu_wcnt;	/* how much to write */
69 	int	tu_state;	/* current state of tansfer operation */
70 	int	tu_flag;	/* read in progress flag */
71 	char	*tu_addr;	/* real buffer data address */
72 	int	tu_count;	/* real requested count */
73 	int	tu_serrs;	/* count of soft errors */
74 	int	tu_cerrs;	/* count of checksum errors */
75 	int	tu_herrs;	/* count of hard errors */
76 	char    tu_dopen[2];	/* drive is open */
77 } uu_softc[NUU];
78 
79 #if defined(VAX750) || defined(VAX730)
80 extern char *tustates[];
81 #else
82 char *tustates[TUS_NSTATES] = {
83 	"INIT1", "INIT2", "IDLE", "SENDH", "SENDD", "SENDC", "SENDR",
84 	"SENDW", "GETH", "GETD", "GETC", "GET", "WAIT", "RCVERR", "CHKERR"
85 };
86 #endif
87 
88 #define	UNIT(dev)	(minor(dev)>>1)
89 
90 u_char	uunull[2] = { 0, 0 };		/* nulls to send for initialization */
91 u_char	uuinit[2] = { TUF_INITF, TUF_INITF };	/* inits to send */
92 
93 struct	uba_device	*uudinfo[NUU];
94 
95 int uuprobe(), uuattach(), uurintr(), uuxintr(), uuwatch();
96 u_short uustd[] = { 0176500, 0 };
97 struct uba_driver uudriver =
98     { uuprobe, 0, uuattach, 0, uustd, "uu", uudinfo };
99 
100 int	uuwstart;
101 int	uuwake();
102 static char uu_pcnt[NUX];		/* pee/vee counters, one per drive */
103 
104 /*ARGSUSED*/
105 uuprobe(reg)
106 	caddr_t reg;
107 {
108 	register int br, cvec;			/* value result */
109 	struct uudevice *uuaddr = (struct uudevice *)reg;
110 
111 #ifdef lint
112 	br = 0; cvec = br; br = cvec;
113 	uurintr(0); uuxintr(0);
114 #endif
115 	uuaddr->tcs = UUCS_INTR;
116 	DELAY(1000);
117 	uuaddr->tcs = 0;
118 	cvec -= 4;		/* since we are using the xmitter intrpt */
119 	return(sizeof (*uuaddr));
120 }
121 
122 uuattach(ui)
123 	register struct uba_device *ui;
124 {
125 }
126 
127 /*ARGSUSED1*/
128 uuopen(dev, flag)
129 	dev_t dev;
130 	int flag;
131 {
132 	register struct uba_device *ui;
133 	register struct uu_softc *uuc;
134 	register struct uudevice *uuaddr;
135 	int ctlr, unit = UNIT(dev), s, error;
136 
137 	ctlr = unit / NDPC;
138 	if (unit >= NUX || (ui = uudinfo[ctlr]) == 0 || ui->ui_alive == 0)
139 		return (ENXIO);
140 	uuc = &uu_softc[ctlr];
141 	if (uuc->tu_dopen[unit&UMASK])
142 		return (EBUSY);
143 	if (uuwstart++ == 0)
144 		timeout(uuwatch, (caddr_t)0, hz);
145 
146 	uuc->tu_dopen[unit&UMASK]++;
147 	uuaddr = (struct uudevice *)ui->ui_addr;
148 	s = splx(UUIPL);
149 	/*
150 	 * If the other device on this controller
151 	 * is already active, no need to initialize
152 	 */
153 	if (uuc->tu_dopen[0] && uuc->tu_dopen[1])
154 		goto ok;
155 
156 	/*
157 	 * If the unit already initialized,
158 	 * just enable interrupts and return.
159 	 */
160 	if (uuc->tu_state == TUS_IDLE) {
161 		uuaddr->rcs = UUCS_INTR;
162 		goto ok;
163 	}
164 
165 	/*
166 	 * Must initialize, reset the cassette
167 	 * and wait for things to settle down.
168 	 */
169 	uureset(ctlr);
170 	if (error = tsleep((caddr_t)uuc, (PZERO+1) | PCATCH, devopn, 0)) {
171 		splx(s);
172 		return (error);
173 	}
174 	uitab[ctlr].b_active = NULL;
175 	if (uuc->tu_state != TUS_IDLE) {
176 		uuc->tu_state = TUS_INIT1;
177 		uuc->tu_dopen[unit&UMASK] = 0;
178 		uuc->tu_rcnt = uuc->tu_wcnt = 0;
179 		uuaddr->rcs = 0;
180 		uuaddr->tcs = 0;
181 		splx(s);
182 		return (EIO);
183 	}
184 ok:
185 	splx(s);
186 	return (0);
187 }
188 
189 /*
190  * Wait for all outstanding IO on this drive
191  * complete, before closing. If both drives on
192  * this controller are idle, mark the controller
193  * `inactive'.
194  */
195 
196 uuclose(dev, flag)
197 	dev_t dev;
198 	int flag;
199 {
200 	int s, unit = UNIT(dev);
201 	register struct uu_softc *uuc = &uu_softc[unit/NDPC];
202 	struct buf *bp, *last = NULL;
203 	struct uudevice *uuaddr = (struct uudevice *)uudinfo[unit/NDPC]->ui_addr;
204 
205 	s = splx(UUIPL);
206 	while (uu_pcnt[unit])
207 		sleep(&uu_pcnt[unit], PRIBIO);
208 	/*
209 	 * No more writes are pending, scan the
210 	 * buffer queue for oustanding reads from
211 	 * this unit.
212 	 */
213 	for (bp = uitab[unit/NDPC].b_actf; bp; bp = bp->b_actf) {
214 		if (bp->b_dev == dev)
215 			last = bp;
216 	}
217 	if (last) {
218 		last->b_flags |= B_CALL;
219 		last->b_iodone = uuwake;
220 		sleep((caddr_t)last, PRIBIO);
221 	}
222 	uuc->tu_dopen[unit&UMASK] = 0;
223 	if (!uuc->tu_dopen[0] && !uuc->tu_dopen[1]) {
224 		uuc->tu_flag = 0;
225 		uuaddr->rcs = 0;
226 	}
227 	splx(s);
228 	return (0);
229 }
230 
231 uuwake(bp)
232 	struct buf *bp;
233 {
234 	wakeup(bp);
235 }
236 
237 uureset(ctlr)
238 	int ctlr;
239 {
240 	register struct uu_softc *uuc = &uu_softc[ctlr];
241 	register struct packet *cmd = &uucmd[ctlr];
242 	struct uba_device *ui = uudinfo[ctlr];
243 	register struct uudevice *uuaddr = (struct uudevice *)ui->ui_addr;
244 
245 	uitab[ctlr].b_active++;
246 	uuc->tu_state = TUS_INIT1;
247 	uuc->tu_wbptr = uunull;
248 	uuc->tu_wcnt = sizeof (uunull);
249 	uuc->tu_rcnt = 0;
250 	cmd->pk_flag = TUF_CMD;
251 	cmd->pk_mcount = sizeof (*cmd) - 4;
252 	cmd->pk_mod = 0;
253 	cmd->pk_seq = 0;
254 	cmd->pk_sw = 0;
255 	uuaddr->rcs = 0;
256 	uuaddr->tcs = UUCS_INTR | UUCS_BREAK;
257 	uuxintr(ctlr);				/* start output */
258 }
259 
260 /*
261  * Strategy routine for block I/O
262  */
263 uustrategy(bp)
264 	register struct buf *bp;
265 {
266 	register struct buf *uutab;
267 	struct uba_device *ui;
268 	int s, unit = UNIT(bp->b_dev);
269 
270 	if ((unit > NUX) || (bp->b_blkno >= NTUBLK))
271 		goto bad;
272 	ui = uudinfo[unit/NDPC];
273 	if (ui == 0 || ui->ui_alive == 0)
274 		goto bad;
275 	uutab = &uitab[unit/NDPC];	/* one request queue per controller */
276 	s = splx(UUIPL);
277 	if ((bp->b_flags&B_READ) == 0)
278 		tu_pee(&uu_pcnt[unit]);
279 	bp->b_actf = NULL;
280 	if (uutab->b_actf == NULL)
281 		uutab->b_actf = bp;
282 	else
283 		uutab->b_actl->b_actf = bp;
284 	uutab->b_actl = bp;
285 	if (uutab->b_active == 0)
286 		uustart(ui);
287 	splx(s);
288 	return;
289 
290 bad:
291 	bp->b_flags |= B_ERROR;
292 	bp->b_error = ENXIO;
293 	iodone(bp);
294 	return;
295 }
296 
297 /*
298  * Start the transfer
299  */
300 uustart(ui)
301 	register struct uba_device *ui;
302 {
303 	register struct buf *bp;
304 	register struct uu_softc *uuc;
305 	struct packet *cmd;
306 	int ctlr = ui->ui_unit, s;
307 
308 	if ((bp = uitab[ctlr].b_actf) == NULL)
309 		return;
310 	s = splx(UUIPL);
311 	uuc = &uu_softc[ctlr];
312 	if (uuc->tu_state != TUS_IDLE) {
313 		uureset(ctlr);
314 		splx(s);
315 		return;
316 	}
317 	cmd = &uucmd[ctlr];
318 	uitab[ctlr].b_active++;
319 	uitab[ctlr].b_errcnt = 0;
320 	uuc->tu_addr = bp->b_un.b_addr;
321 	uuc->tu_count = cmd->pk_count = bp->b_bcount;
322 	cmd->pk_block = bp->b_blkno;
323 	if (bp->b_flags&B_READ) {
324 		cmd->pk_op = TUOP_READ;
325 		cmd->pk_mod = 0;
326 		uuc->tu_state = TUS_SENDR;
327 	} else {
328 		cmd->pk_op = TUOP_WRITE;
329 		cmd->pk_mod = minor(bp->b_dev)&WRV ? TUMD_WRV : 0;
330 		uuc->tu_state = TUS_SENDW;
331 	}
332 	cmd->pk_unit = UNIT(bp->b_dev)&UMASK;
333 	cmd->pk_sw = 0;
334 	cmd->pk_chksum =
335 	    tuchk(*((short *)cmd), (u_short *)&cmd->pk_op, (int)cmd->pk_mcount);
336 	uuc->tu_wbptr = (u_char *)cmd;
337 	uuc->tu_wcnt = sizeof (*cmd);
338 	uuxintr(ctlr);
339 	splx(s);
340 }
341 
342 /*
343  * TU58 receiver interrupt, handles whatever condition the
344  * pseudo DMA routine in locore is unable to handle,
345  * or, if UUDMA is undefined, handle all receiver interrupt
346  * processing.
347  */
348 uurintr(ctlr)
349 	int ctlr;
350 {
351 	struct uba_device *ui = uudinfo[ctlr];
352 	register struct uu_softc *uuc = &uu_softc[ctlr];
353 	register struct uudevice *uuaddr = (struct uudevice *)ui->ui_addr;
354 	register struct buf *uutab = &uitab[ctlr];
355 	struct packet *data, *cmd;
356 	struct buf *bp;
357 	int c, unit;
358 
359 	c = uuaddr->rdb;
360 	data = &uudata[ctlr];
361 	cmd = &uucmd[ctlr];
362 #if !defined(UUDMA)
363 	if (c & UURDB_ERROR)
364 		uuc->tu_state = TUS_RCVERR;
365 	else {
366 		if (uuc->tu_rcnt) {
367 			*uuc->tu_rbptr++ = c;
368 			if (--uuc->tu_rcnt)
369 				return;
370 		}
371 	}
372 #endif
373 
374 	/*
375 	 * Switch on the tu_state of the transfer.
376 	 */
377 	switch(uuc->tu_state) {
378 
379 	/*
380 	 * A data error occured in uudma
381 	 * (either overrun or break)
382 	 */
383 	case TUS_RCVERR:
384 		if ((c & UURDB_ORUN) == 0)
385 			printf("uu%d: break received, transfer restarted\n",
386 			    data->pk_unit);
387 #ifdef UUDEBUG
388 		else
389 			printf("uu%d: data overrun, recovered\n",
390 			    data->pk_unit);
391 #endif
392 		uuc->tu_serrs++;
393 		uu_restart(ctlr, ui);
394 		break;
395 
396 	/*
397 	 * If we get an unexpected "continue",
398 	 * start all over again...
399 	 */
400 	case TUS_INIT2:
401 		uuc->tu_state = c == TUF_CONT ? TUS_IDLE : TUS_INIT1;
402 		uuc->tu_flag = 0;
403 		wakeup((caddr_t)uuc);
404 		uustart(ui);
405 		break;
406 
407 	/*
408 	 * Only transition from this state
409 	 * is on a "continue", so if we don't
410 	 * get it, reset the world.
411 	 */
412 	case TUS_WAIT:			/* waiting for continue */
413 		switch(c) {
414 		case TUF_CONT:  /* got the expected continue */
415 			uuc->tu_flag = 0;
416 			data->pk_flag = TUF_DATA;
417 			data->pk_mcount = MIN(128, uuc->tu_count);
418 			data->pk_chksum =
419 			    tuchk(*((short *)data), (caddr_t)uuc->tu_addr,
420 				(int)data->pk_mcount);
421 			uuc->tu_state = TUS_SENDH;
422 			uuc->tu_wbptr = (u_char *)data;
423 			uuc->tu_wcnt = 2;
424 			uuxintr(ctlr);
425 			break;
426 
427 		case TUF_CMD:   /* sending us an END packet...error */
428 			uuc->tu_state = TUS_GET;
429 			uuc->tu_rbptr = (u_char *)data;
430 			uuc->tu_rcnt = sizeof (*data) - 1;
431 			uuc->tu_flag = 1;
432 			uuaddr->tcs = 0;
433 			*uuc->tu_rbptr++ = c & UUDB_DMASK;
434 			break;
435 
436 		case TUF_INITF:
437 			uureset(ctlr);
438 			break;
439 
440 		default:        /* something random...bad news */
441 			uuc->tu_state = TUS_INIT1;
442 			break;
443 		}
444 		break;
445 
446 	case TUS_SENDW:
447 		if (c != TUF_CONT && c != TUF_INITF)
448 			goto bad;
449 		uu_restart(ctlr, ui);
450 		break;
451 
452 	/*
453 	 * Got header, now get data; amount to
454 	 * fetch is included in packet.
455 	 * (data packets are handled entirely
456 	 * in uudma)
457 	 */
458 	case TUS_GETH:
459 #ifndef UUDMA
460 		if (data->pk_flag == TUF_DATA)
461 			uuc->tu_rbptr = (u_char *)uuc->tu_addr;
462 #endif
463 		uuc->tu_rcnt = data->pk_mcount;
464 		uuc->tu_state = TUS_GETD;
465 		break;
466 
467 	/*
468 	 * Got the data, now fetch the checksum.
469 	 */
470 	case TUS_GETD:
471 		uuc->tu_rbptr = (u_char *)&data->pk_chksum;
472 		uuc->tu_rcnt = sizeof (data->pk_chksum);
473 		uuc->tu_state = TUS_GETC;
474 		break;
475 
476 	case TUS_GETC:
477 		/* got entire packet */
478 		if (data->pk_chksum !=
479 		    tuchk(*((short *)data), (u_short *)
480 		     (data->pk_flag == TUF_DATA ?
481 		     (u_short *) uuc->tu_addr : (u_short *)&data->pk_op),
482 		     (int)data->pk_mcount))
483 	case TUS_CHKERR:
484 			uuc->tu_cerrs++;
485 	case TUS_GET:
486 		if (data->pk_flag == TUF_DATA) {
487 			/* data packet, advance to next */
488 			uuc->tu_addr += data->pk_mcount;
489 			uuc->tu_count -= data->pk_mcount;
490 			uuc->tu_state = TUS_GETH;
491 			uuc->tu_rbptr = (u_char *)data;	/* next packet */
492 			uuc->tu_rcnt = 2;
493 		} else if (data->pk_flag==TUF_CMD && data->pk_op==TUOP_END) {
494 			/* end packet, idle and reenable transmitter */
495 			uuc->tu_state = TUS_IDLE;
496 			uuc->tu_flag = 0;
497 			uuaddr->tcs = UUCS_INTR;
498 			if ((bp = uutab->b_actf) == NULL) {
499 				printf("uu%d: no bp, active %d\n",
500 				    data->pk_unit, uitab[ctlr].b_active);
501 				uustart(ui);
502 				return;
503 			}
504 			unit = UNIT(bp->b_dev);
505 			if (data->pk_mod > 1) {        /* hard error */
506 				printf("uu%d: hard error bn%d,", unit,
507 				    bp->b_blkno);
508 				printf(" pk_mod 0%o\n", data->pk_mod&0xff);
509 				bp->b_flags |= B_ERROR;
510 				uuc->tu_herrs++;
511 			} else if (data->pk_mod)	/* soft error */
512 				uuc->tu_serrs++;
513 			uutab->b_active = NULL;
514 			uutab->b_actf = bp->b_actf;
515 			bp->b_resid = uuc->tu_count;
516 			if ((bp->b_flags&B_READ) == 0)
517 				tu_vee(&uu_pcnt[unit]);
518 			iodone(bp);
519 			uustart(ui);
520 		} else {
521 			/*
522 			 * Neither data nor end: data was lost
523 			 * somehow, flush and restart the transfer.
524 			 */
525 			uuaddr->rcs = 0;
526 			uu_restart(ctlr, ui);
527 			uuc->tu_serrs++;
528 		}
529 		break;
530 
531 	case TUS_IDLE:
532 	case TUS_INIT1:
533 		break;
534 
535 	default:
536 bad:
537 		if (c == TUF_INITF) {
538 			printf("uu%d protocol error, state=", data->pk_unit);
539 			printstate(uuc->tu_state);
540 			printf(", op=%x, cnt=%d, block=%d\n",
541 			    cmd->pk_op, cmd->pk_count, cmd->pk_block);
542 			uutab->b_active = NULL;
543 			if (bp = uutab->b_actf) {
544 				bp->b_flags |= B_ERROR;
545 				uutab->b_actf = bp->b_actf;
546 				if ((bp->b_flags&B_READ) == 0)
547 					tu_vee(&uu_pcnt[unit]);
548 				iodone(bp);
549 			}
550 			uuc->tu_state = TUS_INIT1;
551 		} else {
552 			printf("uu%d receive state error, state=",
553 				data->pk_unit);
554 			printstate(uuc->tu_state);
555 			printf(", byte=%x\n", c & 0xff);
556 #ifdef notdef
557 			uuc->tu_state = TUS_INIT1;
558 #endif
559 			wakeup((caddr_t)uuc);
560 		}
561 	}
562 }
563 
564 
565 /*
566  * TU58 transmitter interrupt
567  */
568 uuxintr(ctlr)
569 	int ctlr;
570 {
571 	register struct uu_softc *uuc = &uu_softc[ctlr];
572 	register struct uudevice *uuaddr;
573 	register struct packet *data;
574 	struct uba_device *ui = uudinfo[ctlr];
575 	int c;
576 
577 	data = &uudata[ctlr];
578 	uuaddr = (struct uudevice *) ui->ui_addr;
579 top:
580 	if (uuc->tu_wcnt > 0) {
581 		/* still stuff to send, send one byte */
582 		while ((uuaddr->tcs & UUCS_READY) == 0)
583 			;
584 		uuaddr->tdb = *uuc->tu_wbptr++;
585 		uuc->tu_wcnt--;
586 		return;
587 	}
588 
589 	/*
590 	 * Last message byte was sent out.
591 	 * Switch on tu_state of transfer.
592 	 */
593 	switch(uuc->tu_state) {
594 
595 	/*
596 	 * Two nulls have been sent, remove break, and send inits
597 	 */
598 	case TUS_INIT1:
599 		uuc->tu_flag = 0;
600 		uuaddr->tcs = UUCS_INTR;
601 		uuc->tu_state = TUS_INIT2;
602 		uuc->tu_wbptr = uuinit;
603 		uuc->tu_wcnt = sizeof (uuinit);
604 		goto top;
605 
606 	/*
607 	 * Inits have been sent, wait for a continue msg.
608 	 */
609 	case TUS_INIT2:
610 		c = uuaddr->rdb;	/* prevent overrun error */
611 		uuaddr->rcs = UUCS_INTR;
612 		uuc->tu_flag = 1;
613 		break;
614 
615 	/*
616 	 * Read cmd packet sent, get ready for data
617 	 */
618 	case TUS_SENDR:
619 		uuc->tu_state = TUS_GETH;
620 		uuc->tu_rbptr = (u_char *)data;
621 		uuc->tu_rcnt = 2;
622 		uuc->tu_flag = 1;
623 		uuaddr->tcs = 0;
624 		uuaddr->rcs = UUCS_INTR;
625 		break;
626 
627 	/*
628 	 * Write cmd packet sent, wait for continue
629 	 */
630 	case TUS_SENDW:
631 		uuc->tu_state = TUS_WAIT;
632 		uuc->tu_flag = 1;
633 		if ((uuaddr->rcs&UUCS_INTR) == 0) {
634 			printf("NO IE\n");
635 			uuaddr->rcs = UUCS_INTR;
636 		}
637 		break;
638 
639 	/*
640 	 * Header sent, send data.
641 	 */
642 	case TUS_SENDH:
643 		uuc->tu_state = TUS_SENDD;
644 		uuc->tu_wbptr = (u_char *)uuc->tu_addr;
645 		uuc->tu_wcnt = data->pk_mcount;
646 		goto top;
647 
648 	/*
649 	 * Data sent, follow with checksum.
650 	 */
651 	case TUS_SENDD:
652 		uuc->tu_state = TUS_SENDC;
653 		uuc->tu_wbptr = (u_char *)&data->pk_chksum;
654 		uuc->tu_wcnt = 2;
655 		goto top;
656 
657 	/*
658 	 * Checksum sent, wait for continue.
659 	 */
660 	case TUS_SENDC:
661 		/*
662 		 * Update buffer address and count.
663 		 */
664 		uuc->tu_addr += data->pk_mcount;
665 		uuc->tu_count -= data->pk_mcount;
666 		if (uuc->tu_count > 0) {
667 			uuc->tu_state = TUS_WAIT;
668 			uuc->tu_flag = 1;
669 			break;
670 		}
671 
672 		/*
673 		 * End of transmission, get ready for end packet.
674 		 */
675 		uuc->tu_state = TUS_GET;
676 		uuc->tu_rbptr = (u_char *)data;
677 		uuc->tu_rcnt = sizeof (*data);
678 		uuc->tu_flag = 1;
679 		uuaddr->tcs = 0;
680 		break;
681 
682 	/*
683 	 * Random interrupt
684 	 */
685 	case TUS_IDLE:		/* stray interrupt? */
686 
687 	default:
688 		break;
689 	}
690 }
691 
692 uuwatch()
693 {
694 	register struct uu_softc *uuc;
695 	register struct uudevice *uuaddr;
696 	struct uba_device *ui;
697 	struct buf *bp, *uutab;
698 	int s, ctlr, active = 0;
699 
700 	for (ctlr=0; ctlr<NUU; ctlr++) {
701 		int i;
702 
703 		uuc = &uu_softc[ctlr];
704 
705 		if (uuc->tu_dopen[0] || uuc->tu_dopen[1])
706 			active++;
707 		if (uuc->tu_flag == 0)
708 			/*
709 			 * If no read is in progress
710 			 * just skip
711 			 */
712 			continue;
713 
714 		ui = uudinfo[ctlr];
715 		uuaddr = (struct uudevice *)ui->ui_addr;
716 		uutab = &uitab[ctlr];
717 		if (uuc->tu_flag++ < 40)
718 			continue;
719 		printf("uu%d: read stalled\n", uudata[ctlr].pk_unit);
720 #ifdef UUDEBUG
721 		printf("%X %X %X %X %X %X %X\n", uuc->tu_rbptr, uuc->tu_rcnt,
722 		       uuc->tu_wbptr, uuc->tu_wcnt, uuc->tu_state, uuc->tu_addr,
723 		       uuc->tu_count);
724 #endif
725 		s = splx(UUIPL);
726 		uuc->tu_flag = 0;
727 		i = uuaddr->rdb;		/* dummy */
728 		uuaddr->rcs = UUCS_INTR;	/* in case we were flushing */
729 		uuaddr->tcs = UUCS_INTR;
730 		uuc->tu_state = TUS_IDLE;
731 		if (!uutab->b_active) {
732 			wakeup((caddr_t)uuc);
733 			goto retry;
734 		}
735 		if (++uutab->b_errcnt <= 1) {
736 			uustart(ui);
737 			goto retry;
738 		}
739 		if (bp = uutab->b_actf) {
740 			bp->b_flags |= B_ERROR;
741 			if ((bp->b_flags&B_READ) == 0)
742 				tu_vee(&uu_pcnt[UNIT(bp->b_dev)]);
743 			iodone(bp);
744 		}
745 retry:
746 		(void) splx(s);
747 	}
748 	if (active)
749 		timeout(uuwatch, (caddr_t)0, hz);
750 	else
751 		uuwstart = 0;
752 	return;
753 }
754 
755 #if !defined(VAX750) && !defined(VAX730)
756 /*
757  * Compute checksum TU58 fashion
758  */
759 #ifdef lint
760 tuchk(word, cp, n)
761 	register word;
762 	register unsigned short *cp;
763 	int n;
764 {
765 	register int c = n >> 1;
766 	register long temp;
767 
768 	do {
769 		temp = *cp++;	/* temp, only because vax cc won't *r++ */
770 		word += temp;
771 	} while (--c > 0);
772 	if (n & 1)
773 		word += *(unsigned char *)cp;
774 	while (word & 0xffff0000)
775 		word = (word & 0xffff) + ((word >> 16) & 0xffff);
776 	return (word);
777 }
778 #else
779 tuchk(word0, wp, n)
780 	register int word0;			/* r11 */
781 	register char *wp;			/* r10 */
782 	register int n;				/* r9 */
783 {
784 	asm("loop:");
785 	asm("	addw2	(r10)+,r11");		/* add a word to sum */
786 	asm("	adwc	$0,r11");		/* add in carry, end-around */
787 	asm("	acbl	$2,$-2,r9,loop");	/* done yet? */
788 	asm("	blbc	r9,ok");		/* odd byte count? */
789 	asm("	movzbw	(r10),r10");		/* yes, get last byte */
790 	asm("	addw2	r10,r11");		/* add it in */
791 	asm("	adwc	$0,r11");		/* and the carry */
792 	asm("ok:");
793 	asm("	movl	r11,r0");		/* return sum */
794 }
795 #endif
796 
797 /*
798  * Make sure this incredibly slow device
799  * doesn't eat up all the buffers in the
800  * system by putting the requesting process
801  * (remember: this device is 'single-user')
802  * to sleep if the write-behind queue grows
803  * larger than NUUQ.
804  */
805 tu_pee(cp)
806 	char *cp;
807 {
808 	register int s;
809 
810 	s = splx(UUIPL);
811 	if (++(*cp) > NUUQ)
812 		sleep(cp, PRIBIO);
813 	splx(s);
814 }
815 
816 tu_vee(cp)
817 	char *cp;
818 {
819 	register int s;
820 
821 	s = splx(UUIPL);
822 	if (--(*cp) <= NUUQ)
823 		wakeup(cp);
824 	splx(s);
825 }
826 #endif
827 
828 uuioctl(dev, cmd, data, flag)
829 	dev_t dev;
830 	caddr_t data;
831 {
832 	/*
833 	 * add code to wind/rewind cassette here
834 	 */
835 	return (ENXIO);
836 }
837 
838 uu_restart(ctlr, ui)
839 	int ctlr;
840 	struct uba_device *ui;
841 {
842 	uureset(ctlr);
843 	timeout(uustart, (caddr_t)ui, hz * 3);
844 }
845 
846 #endif
847