xref: /original-bsd/sys/vax/uba/rx.c (revision c8089215)
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  *	@(#)rx.c	7.5 (Berkeley) 12/16/90
7  */
8 
9 #include "rx.h"
10 #if NFX > 0
11 /*
12  * RX02 floppy disk device driver
13  *
14  */
15 
16 /*
17  * TODO:
18  *	- clean up the code for multisector transfers using
19  *	  a 'transfer in progress' flag
20  *	- Test Deleted Data read/write
21  *	- Test error handling/reporting and 'volume valid' stuff
22  *
23  * 	Note: If the drive subsystem is
24  * 	powered off at boot time, the controller won't interrupt!
25  */
26 
27 #include "../include/pte.h"
28 
29 #include "sys/param.h"
30 #include "sys/buf.h"
31 #include "sys/systm.h"
32 #include "sys/conf.h"
33 #include "sys/errno.h"
34 #include "sys/time.h"
35 #include "sys/kernel.h"
36 #include "sys/uio.h"
37 #include "sys/file.h"
38 
39 #include "../include/cpu.h"
40 #include "../vax/nexus.h"
41 
42 #include "ubavar.h"
43 #include "ubareg.h"
44 #include "rxreg.h"
45 
46 #define b_cylin	b_resid
47 
48 /* per-controller data */
49 struct	rx_ctlr {
50 	int	rxc_state;	/* controller state */
51 #define	RXS_READ	1	/* read started	*/
52 #define	RXS_EMPTY	2	/* empty started */
53 #define	RXS_FILL	3	/* fill started	*/
54 #define	RXS_WRITE	4	/* write started */
55 #define	RXS_FORMAT	5	/* format started */
56 #define	RXS_RDSTAT	6	/* status read started */
57 #define	RXS_RDERR	7	/* error read started */
58 #define	RXS_IDLE	8	/* device is idle */
59 	u_short	rxc_rxcs;	/* extended error status */
60 	u_short	rxc_rxdb;
61 	u_short	rxc_rxxt[4];
62 	int	rxc_tocnt;	/* for watchdog routine */
63 #define	RX_MAXTIMEOUT	30	/* # seconds to wait before giving up */
64 } rx_ctlr[NFX];
65 
66 /* per-drive buffers */
67 struct buf	rrxbuf[NRX];	/* buffers for raw I/O */
68 struct buf	erxbuf[NRX];	/* buffers for reading error status */
69 struct buf	rxutab[NRX];	/* per drive buffers */
70 
71 /* per-drive data */
72 struct rx_softc {
73 	int	sc_flags;	/* drive status flags */
74 #define	RXF_DIRECT	0x01	/* if set: use direct sector mapping */
75 #define	RXF_TRKONE	0x02	/* if set: start mapping on track 1 */
76 #define	RXF_DBLDEN	0x04	/* use double density */
77 #define	RXF_DEVTYPE	0x07	/* mapping flags */
78 #define	RXF_LOCK	0x10	/* exclusive use */
79 #define	RXF_DDMK	0x20	/* deleted-data mark detected */
80 #define	RXF_USEWDDS	0x40	/* write deleted-data sector */
81 #define	RXF_FORMAT	0x80	/* format in progress */
82 #define	RXF_BAD		0x100	/* drive bad, cannot be used */
83 	int	sc_csbits;	/* constant bits for CS register */
84 	int	sc_open;	/* count number of opens */
85 	int	sc_offset;	/* raw mode kludge to avoid restricting */
86 				/* single sector transfers to start on */
87 				/* DEV_BSIZE boundaries */
88 	/*
89 	 * The rest of this structure is used to
90 	 * store temporaries while simulating multi
91 	 * sector transfers
92 	 */
93 	caddr_t	sc_uaddr;	/* unibus base address */
94 	long	sc_bcnt;	/* total transfer count */
95 	long	sc_resid;	/* no. of bytes left to transfer */
96 } rx_softc[NRX];
97 
98 struct rxerr {
99 	short	rxcs;
100 	short	rxdb;
101 	short	rxxt[4];	/* error code dump from controller */
102 } rxerr[NRX];
103 /* End of per-drive data */
104 
105 struct	uba_device *rxdinfo[NRX];
106 struct	uba_ctlr *rxminfo[NFX];
107 
108 struct buf *savebp;
109 
110 int rxprobe(), rxslave(), rxattach(), rxdgo(), rxintr(), rxwatch(), rxphys();
111 u_short rxstd[] = { 0177170, 0177150, 0 };
112 struct uba_driver fxdriver =
113   { rxprobe, rxslave, rxattach, rxdgo, rxstd, "rx", rxdinfo, "fx", rxminfo };
114 
115 int	rxwstart;
116 #define	RXUNIT(dev)	(minor(dev)>>3)
117 #define	MASKREG(reg)	(reg&0xffff)
118 
119 /* constants related to floppy data capacity */
120 #define	RXSECS	2002				/* # sectors on a floppy */
121 #define	DDSTATE	(sc->sc_csbits&RX_DDEN)
122 #define	NBPS	(DDSTATE ? 256 : 128)		/* # bytes per sector */
123 #define	RXSIZE	(DDSTATE ? 512512 : 256256)	/* # bytes per disk */
124 #define	SECMASK	(DDSTATE ? 0xff : 0x7f)		/* shifted-out bits of offset */
125 
126 #define	B_CTRL		0x80000000		/* control (format) request */
127 #define B_RDSTAT	0x40000000		/* read drive status (open) */
128 
129 /*ARGSUSED*/
130 rxprobe (reg)
131 	caddr_t reg;
132 {
133 	register int br, cvec;			/* value-result */
134 	struct rxdevice *rxaddr = (struct rxdevice *)reg;
135 
136 #ifdef lint
137 	br = 0; cvec = br; br = cvec;
138 	rxintr(0);
139 #endif lint
140 	rxaddr->rxcs = RX_INTR;
141 	DELAY(10);
142 	rxaddr->rxcs = 0;
143 	return (sizeof (*rxaddr));
144 }
145 
146 /*ARGSUSED*/
147 rxslave(ui, reg)
148 	struct uba_device *ui;
149 	caddr_t reg;
150 {
151 	return (ui->ui_slave == 0 || ui->ui_slave == 1);
152 }
153 
154 /*ARGSUSED*/
155 rxattach(ui)
156 	struct uba_device *ui;
157 {
158 
159 }
160 
161 /*ARGSUSED1*/
162 rxopen(dev, flag)
163 	dev_t dev;
164 {
165 	register int unit = RXUNIT(dev);
166 	register struct rx_softc *sc;
167 	register struct uba_device *ui;
168 	struct rx_ctlr *rxc;
169 
170 	if (unit >= NRX || (ui = rxdinfo[unit]) == 0 || ui->ui_alive == 0)
171 		return (ENXIO);
172 	sc = &rx_softc[unit];
173 	if (sc->sc_open == 0 && sc->sc_csbits == 0) {
174 		struct buf *bp = &erxbuf[unit];
175 		/*
176 		 * lock the device while an open
177 		 * is in progress
178 		 */
179 		sc->sc_flags = (minor(dev) & RXF_DEVTYPE) | RXF_LOCK;
180 		sc->sc_csbits = RX_INTR;
181 		sc->sc_csbits |= ui->ui_slave == 0 ? RX_DRV0 : RX_DRV1;
182 
183 		bp->b_dev = dev;
184 		bp->b_flags = B_RDSTAT | B_BUSY;
185 		bp->b_error = 0;
186 		bp->b_blkno = 0;
187 		sc->sc_offset = 0;
188 		sc->sc_resid  = 0;
189 		/*
190 		 * read device status to determine if
191 		 * a floppy is present in the drive and
192 		 * what density it is
193 		 */
194 		rxstrategy(bp);
195 		iowait(bp);
196 		if (bp->b_flags & B_ERROR) {
197 			sc->sc_csbits = 0;
198 			sc->sc_flags &= ~RXF_LOCK;
199 			return (bp->b_error);
200 		}
201 		if (rxwstart++ == 0) {
202 			rxc = &rx_ctlr[ui->ui_mi->um_ctlr];
203 			rxc->rxc_tocnt = 0;
204 			timeout(rxwatch, (caddr_t)0, hz);  /* start watchdog */
205 		}
206 #ifdef RXDEBUG
207 		printf("rxopen: csbits=0x%x\n", sc->sc_csbits);
208 #endif
209 		sc->sc_flags &= ~RXF_LOCK;
210 	} else	{
211 		if (sc->sc_flags & RXF_LOCK)
212 			return(EBUSY);
213 	}
214 	sc->sc_open = 1;
215 	return (0);
216 }
217 
218 /*ARGSUSED1*/
219 rxclose(dev, flag)
220 	dev_t dev;
221 {
222 	register struct rx_softc *sc = &rx_softc[RXUNIT(dev)];
223 
224 	sc->sc_open = 0;
225 #ifdef RXDEBUG
226 	printf("rxclose: dev=0x%x, sc_open=%d\n", dev, sc->sc_open);
227 #endif
228 	return (0);
229 }
230 
231 rxstrategy(bp)
232 	register struct buf *bp;
233 {
234 	struct uba_device *ui;
235 	register struct buf *dp;
236 	struct rx_softc *sc;
237 	int s, unit = RXUNIT(bp->b_dev);
238 
239 	if (unit >= NRX)
240 		goto bad;
241 	ui = rxdinfo[unit];
242 	if (ui == 0 || ui->ui_alive == 0)
243 		goto bad;
244 	sc = &rx_softc[unit];
245 	if (bp->b_blkno < 0 || dbtob(bp->b_blkno) > RXSIZE)
246 		goto bad;
247 	if (sc->sc_flags & RXF_BAD) {
248 		bp->b_error = EIO;
249 		goto dbad;
250 	}
251 	s = spl5();
252 #ifdef RXDEBUG
253 	printf("rxstrat: bp=0x%x, fl=0x%x, un=%d, bl=%d, cnt=%d\n",
254 		bp, bp->b_flags, unit, bp->b_blkno, bp->b_bcount);
255 #endif
256 	bp->b_cylin = bp->b_blkno;	/* don't care to calculate trackno */
257 	dp = &rxutab[unit];
258 	disksort(dp, bp);
259 	if (dp->b_active == 0) {
260 		rxustart(ui);
261 		bp = &ui->ui_mi->um_tab;
262 		if (bp->b_actf && bp->b_active == 0)
263 			rxstart(ui->ui_mi);
264 	}
265 	splx(s);
266 	return;
267 
268 bad:
269 	bp->b_error = ENXIO;
270 dbad:
271 	bp->b_flags |= B_ERROR;
272 	iodone(bp);
273 	return;
274 }
275 
276 /*
277  * Unit start routine.
278  * Put this unit on the ready queue for the controller
279  */
280 rxustart(ui)
281 	register struct uba_device *ui;
282 {
283 	struct buf *dp = &rxutab[ui->ui_unit];
284 	struct uba_ctlr *um = ui->ui_mi;
285 
286 	dp->b_forw = NULL;
287 	if (um->um_tab.b_actf == NULL)
288 		um->um_tab.b_actf = dp;
289 	else
290 		um->um_tab.b_actl->b_forw = dp;
291 	um->um_tab.b_actl = dp;
292 	dp->b_active++;
293 }
294 /*
295  * Sector mapping routine.
296  * Two independent sets of choices are available:
297  *
298  * (a) The first logical sector may either be on track 1 or track 0.
299  * (b) The sectors on a track may either be taken in 2-for-1 interleaved
300  *	 fashion or directly.
301  * This gives a total of four possible mapping schemes.
302  *
303  * Physical tracks on the RX02 are numbered 0-76.  Physical sectors on
304  * each track are numbered 1-26.
305  *
306  * When interleaving is used, sectors on the first logical track are
307  * taken in the order 1, 3, 5, ..., 25, 2, 4, 6, ..., 26.  A skew of
308  * six sectors per track is also used (to allow time for the heads to
309  * move); hence, the sectors on the second logical track are taken in
310  * the order 7, 9, 11, ..., 25, 1, 3, 5, 8, 10, 12, ..., 26, 2, 4, 6;
311  * the third logical track starts with sector 13; and so on.
312  *
313  * When the mapping starts with track 1, track 0 is the last logical
314  * track, and this track is always handled directly (without inter-
315  * leaving), even when the rest of the disk is interleaved.  (This is
316  * still compatible with DEC RT-11, which does not use track 0 at all.)
317  */
318 rxmap(bp, psector, ptrack)
319 	struct buf *bp;
320 	int *psector, *ptrack;
321 {
322 	register int lt, ls, ptoff;
323 	struct rx_softc *sc = &rx_softc[RXUNIT(bp->b_dev)];
324 
325 	ls = (dbtob(bp->b_blkno) + (sc->sc_offset - sc->sc_resid)) / NBPS;
326 	lt = ls / 26;
327 	ls %= 26;
328 	/*
329 	 * The "physical track offset" (ptoff) takes the
330 	 * starting physical track (0 or 1) and the desired
331 	 * interleaving into account.  If lt+ptoff >= 77,
332 	 * then interleaving is not performed.
333 	 */
334 	ptoff = 0;
335 	if (sc->sc_flags & RXF_DIRECT)
336 		ptoff = 77;
337 	if (sc->sc_flags & RXF_TRKONE)
338 		ptoff++;
339 	if (lt + ptoff < 77)
340 		ls = ((ls << 1) + (ls >= 13) + (6*lt)) % 26;
341 	*ptrack = (lt + ptoff) % 77;
342 	*psector = ls + 1;
343 }
344 
345 /*
346  * Controller start routine.
347  * Start a new transfer or continue a multisector
348  * transfer. If this is a new transfer (dp->b_active == 1)
349  * save the start address of the data buffer and the total
350  * byte count in the soft control structure. These are
351  * restored into the buffer structure when the transfer has
352  * been completed, before calling 'iodone'.
353  */
354 rxstart(um)
355 	register struct uba_ctlr *um;
356 {
357 	register struct rxdevice *rxaddr;
358 	register struct rx_ctlr *rxc;
359 	register struct rx_softc *sc;
360 	struct buf *dp, *bp;
361 	int unit, sector, track;
362 
363 	if (um->um_tab.b_active)
364 		return;
365 loop:
366 	if ((dp = um->um_tab.b_actf) == NULL)
367 		return;
368 	if ((bp = dp->b_actf) == NULL) {
369 		um->um_tab.b_actf = dp->b_forw;
370 		goto loop;
371 	}
372 	um->um_tab.b_active++;
373 	unit = RXUNIT(bp->b_dev);
374 	sc = &rx_softc[unit];
375 	if (sc->sc_flags & RXF_BAD) {
376 		rxpurge(um);
377 		return;
378 	}
379 	if (dp->b_active == 1) {
380 		sc->sc_resid = bp->b_bcount;
381 		sc->sc_uaddr = bp->b_un.b_addr;
382 		sc->sc_bcnt = bp->b_bcount;
383 		sc->sc_offset += sc->sc_bcnt;
384 		dp->b_active++;
385 	}
386 	rxaddr = (struct rxdevice *)um->um_addr;
387 	rxc = &rx_ctlr[um->um_ctlr];
388 	bp->b_bcount = sc->sc_resid;
389 	if (bp->b_bcount > NBPS)
390 		bp->b_bcount = NBPS;
391 	rxc->rxc_tocnt = 0;
392 #ifdef RXDEBUG
393 	printf("rxstart: ");
394 #endif
395 	if (rxaddr->rxcs == 0x800) {
396 		/*
397 		 * 'Volume valid'? (check if the
398 		 * drive unit has been powered down)
399 		 */
400 		rxaddr->rxcs = RX_INIT;
401 		while((rxaddr->rxcs&RX_DONE) == 0)
402 			;
403 	}
404 	if (bp->b_flags & B_CTRL) {				/* format */
405 		rxc->rxc_state = RXS_FORMAT;
406 		rxaddr->rxcs = RX_FORMAT | sc->sc_csbits;
407 		while ((rxaddr->rxcs&RX_TREQ) == 0)
408 			;
409 		rxaddr->rxdb = 'I';
410 		return;
411 	}
412 	if (bp->b_flags & B_RDSTAT) {			/* read drive status */
413 		rxc->rxc_state = RXS_RDSTAT;
414 		rxaddr->rxcs = RX_RDSTAT | sc->sc_csbits;
415 		return;
416 	}
417 
418 	if (bp->b_flags & B_READ) {
419 		rxmap(bp, &sector, &track);			/* read */
420 #ifdef RXDEBUG
421 		printf("read tr=%d, sc=%d", track, sector);
422 #endif
423 		rxc->rxc_state = RXS_READ;
424 		rxaddr->rxcs = RX_READ | sc->sc_csbits;
425 		while ((rxaddr->rxcs&RX_TREQ) == 0)
426 			;
427 		rxaddr->rxdb = (u_short)sector;
428 		while ((rxaddr->rxcs&RX_TREQ) == 0)
429 			;
430 		rxaddr->rxdb = (u_short)track;
431 	} else {
432 #ifdef RXDEBUG
433 		printf("write");
434 #endif
435 		rxc->rxc_state = RXS_FILL;			/* write */
436 		um->um_cmd = RX_FILL;
437 		(void) ubago(rxdinfo[unit]);
438 	}
439 #ifdef RXDEBUG
440 	printf("\n");
441 #endif
442 }
443 
444 rxdgo(um)
445 	struct uba_ctlr *um;
446 {
447 	register struct rxdevice *rxaddr = (struct rxdevice *)um->um_addr;
448 	int ubinfo = um->um_ubinfo;
449 	struct buf *bp = um->um_tab.b_actf->b_actf;
450 	struct rx_softc *sc = &rx_softc[RXUNIT(bp->b_dev)];
451 	struct rx_ctlr *rxc = &rx_ctlr[um->um_ctlr];
452 
453 	rxaddr->rxcs = um->um_cmd | ((ubinfo & 0x30000) >> 4) | sc->sc_csbits;
454 	if (rxc->rxc_state != RXS_RDERR) {
455 		while ((rxaddr->rxcs&RX_TREQ) == 0)
456 			;
457 		rxaddr->rxdb = (u_short) bp->b_bcount >> 1;
458 	}
459 	while ((rxaddr->rxcs&RX_TREQ) == 0)
460 		;
461 	rxaddr->rxdb = (u_short) ubinfo;
462 }
463 
464 rxintr(ctlr)
465 	int ctlr;
466 {
467 	int unit, sector, track;
468 	struct uba_ctlr *um = rxminfo[ctlr];
469 	register struct rxdevice *rxaddr;
470 	register struct buf *bp, *dp;
471 	register struct rx_softc *sc;
472 	struct uba_device *ui;
473 	struct rxerr *er;
474 	struct rx_ctlr *rxc;
475 
476 	if (!um->um_tab.b_active)
477 		return;
478 	dp = um->um_tab.b_actf;
479 	if (!dp->b_active)
480 		return;
481 	bp = dp->b_actf;
482 	unit = RXUNIT(bp->b_dev);
483 	sc = &rx_softc[unit];
484 	ui = rxdinfo[unit];
485 	rxaddr = (struct rxdevice *)um->um_addr;
486 	rxc = &rx_ctlr[um->um_ctlr];
487 	rxc->rxc_tocnt = 0;
488 	er = &rxerr[unit];
489 #ifdef RXDEBUG
490 	printf("rxint: dev=%x, st=%d, cs=0x%x, db=0x%x\n",
491 		bp->b_dev, rxc->rxc_state, rxaddr->rxcs, rxaddr->rxdb);
492 #endif
493 	if ((rxaddr->rxcs & RX_ERR) &&
494 	    (rxc->rxc_state != RXS_RDSTAT) && (rxc->rxc_state != RXS_RDERR))
495 		goto error;
496 	switch (rxc->rxc_state) {
497 
498 	/*
499 	 * Incomplete commands.  Perform next step
500 	 * and return.  Note that b_active is set on
501 	 * entrance and, therefore, also on exit.
502 	 */
503 	case RXS_READ:
504 		if (rxaddr->rxdb & RXES_DDMARK)
505 			sc->sc_flags |= RXF_DDMK;
506 		else
507 			sc->sc_flags &= ~RXF_DDMK;
508 		rxc->rxc_state = RXS_EMPTY;
509 		um->um_cmd = RX_EMPTY;
510 		(void) ubago(ui);
511 		return;
512 
513 	case RXS_FILL:
514 		rxc->rxc_state = RXS_WRITE;
515 		if (sc->sc_flags & RXF_USEWDDS) {
516 			rxaddr->rxcs = RX_WDDS | sc->sc_csbits;
517 			sc->sc_flags &= ~RXF_USEWDDS;
518 		} else
519 			rxaddr->rxcs = RX_WRITE | sc->sc_csbits;
520 		rxmap(bp, &sector, &track);
521 		while ((rxaddr->rxcs&RX_TREQ) == 0)
522 			;
523 		rxaddr->rxdb = sector;
524 		while ((rxaddr->rxcs&RX_TREQ) == 0)
525 			;
526 		rxaddr->rxdb = track;
527 		return;
528 
529 	/*
530 	 * Possibly completed command.
531 	 */
532 	case RXS_RDSTAT:
533 		if (bp->b_flags & B_RDSTAT) {
534 			if ((rxaddr->rxdb&RXES_READY) == 0) {
535 				bp->b_flags |= B_ERROR;
536 				bp->b_error = ENODEV;
537 			} else {
538 				sc->sc_csbits |= rxaddr->rxdb&RXES_DBLDEN ?
539 					RX_DDEN : RX_SDEN;
540 			}
541 			goto rdone;
542 		}
543 		if (rxaddr->rxdb&RXES_READY)
544 			goto rderr;
545 		bp->b_error = ENODEV;
546 		bp->b_flags |= B_ERROR;
547 		goto done;
548 
549 	/*
550 	 * Command completed.
551 	 */
552 	case RXS_EMPTY:
553 	case RXS_WRITE:
554 		goto done;
555 
556 	case RXS_FORMAT:
557 		goto rdone;
558 
559 	case RXS_RDERR:
560 		bp = savebp;
561 		rxmap(bp, &sector, &track);
562 		printf("rx%d: hard error, trk %d psec %d ",
563 			unit, track, sector);
564 		printf("cs=%b, db=%b, err=", MASKREG(er->rxcs),
565 			RXCS_BITS, MASKREG(er->rxdb), RXES_BITS);
566 		printf("%x, %x, %x, %x\n", MASKREG(er->rxxt[0]),
567 			MASKREG(er->rxxt[1]), MASKREG(er->rxxt[2]),
568 			MASKREG(er->rxxt[3]));
569 		goto done;
570 
571 	default:
572 		printf("rx%d: state %d (reset)\n", unit, rxc->rxc_state);
573 		rxreset(um->um_ubanum);
574 		return;
575 	}
576 error:
577 	/*
578 	 * In case of an error:
579 	 *  (a) Give up now if a format (ioctl) was in progress, if a
580 	 *	  density error was detected, or if the drive went offline
581 	 *  (b) Retry up to nine times if a CRC (data) error was detected,
582 	 *	  then give up if the error persists.
583 	 *  (c) In all other cases, reinitialize the drive and try the
584 	 *	  operation once more before giving up.
585 	 */
586 	if (rxc->rxc_state == RXS_FORMAT || (rxaddr->rxdb&RXES_DENERR))
587 		goto giveup;
588 	if (rxaddr->rxdb & RXES_CRCERR) {
589 		if (++um->um_tab.b_errcnt >= 10)
590 			goto giveup;
591 		goto retry;
592 	}
593 	um->um_tab.b_errcnt += 9;
594 	if (um->um_tab.b_errcnt >= 10)
595 		goto giveup;
596 	rxaddr->rxcs = RX_INIT;
597 	/* no way to get an interrupt for "init done", so just wait */
598 	while ((rxaddr->rxcs&RX_DONE) == 0)
599 		;
600 	/* if someone opened the drive: give up */
601 	if ((rxaddr->rxdb&RXES_READY) == 0)
602 		goto giveup;
603 retry:
604 	/*
605 	 * In case we already have UNIBUS resources, give
606 	 * them back since we reallocate things in rxstart.
607 	 */
608 	if (um->um_ubinfo)
609 		ubadone(um);
610 	um->um_tab.b_active = 0;
611 	rxstart(um);
612 	return;
613 
614 giveup:
615 	/*
616 	 * Hard I/O error --
617 	 * ALL errors are considered fatal and will abort the
618 	 * transfer and purge the i/o request queue
619 	 */
620 	sc->sc_flags |= RXF_BAD;
621 	sc->sc_resid = 0;	/* make sure the transfer is terminated */
622 	rxc->rxc_state = RXS_RDSTAT;
623 	rxaddr->rxcs = RX_RDSTAT | sc->sc_csbits;
624 	return;
625 
626 rderr:
627 	/*
628 	 * A hard error (other than not ready) has occurred.
629 	 * Read the extended error status information.
630 	 * Before doing this, save the current CS and DB register values,
631 	 * because the read error status operation may modify them.
632 	 * Insert buffer with request at the head of the queue.
633 	 */
634 	bp->b_error = EIO;
635 	bp->b_flags |= B_ERROR;
636 	if (um->um_ubinfo)
637 		ubadone(um);
638 	savebp = bp;
639 	er->rxcs = rxaddr->rxcs;
640 	er->rxdb = rxaddr->rxdb;
641 	bp = &erxbuf[unit];
642 	bp->b_un.b_addr = (caddr_t)er->rxxt;
643 	bp->b_bcount = sizeof (er->rxxt);
644 	bp->b_flags &= ~(B_DIRTY|B_UAREA|B_PHYS|B_PAGET);
645 	if (dp->b_actf == NULL)
646 		dp->b_actl = bp;
647 	bp->b_forw = dp->b_actf;
648 	dp->b_actf = bp;
649 	rxc->rxc_state = RXS_RDERR;
650 	um->um_cmd = RX_RDERR;
651 	(void) ubago(ui);
652 	return;
653 
654 done:
655 	ubadone(um);
656 rdone:
657 	um->um_tab.b_active = 0;
658 	um->um_tab.b_errcnt = 0;
659 	if ((sc->sc_resid -= NBPS) > 0) {
660 		bp->b_un.b_addr += NBPS;
661 		rxstart(um);
662 		return;
663 	}
664 	bp->b_un.b_addr = sc->sc_uaddr;
665 	bp->b_resid = 0;
666 	bp->b_bcount = sc->sc_bcnt;
667 	dp->b_actf = bp->av_forw;
668 	iodone(bp);
669 	sc->sc_offset = 0;
670 	rxc->rxc_state = RXS_IDLE;
671 	um->um_tab.b_actf = dp->b_forw;
672 	dp->b_active = 0;
673 	dp->b_errcnt = 0;
674 #ifdef RXDEBUG
675 	printf(".. bp=%x, new=%x\n", bp, dp->b_actf);
676 #endif
677 	/*
678 	 * If this unit has more work to do,
679 	 * start it up right away
680 	 */
681 	if (dp->b_actf)
682 		rxustart(ui);
683 
684 	rxstart(um);
685 }
686 
687 /*ARGSUSED*/
688 
689 rxwatch()
690 {
691 	register struct uba_device *ui;
692 	register struct uba_ctlr *um;
693 	register struct rx_softc *sc;
694 	struct rx_ctlr *rxc;
695 	int i, dopen = 0;
696 
697 	for (i=0; i<NRX; i++) {
698 		ui = rxdinfo[i];
699 		if (ui == 0 || ui->ui_alive == 0)
700 			continue;
701 		sc = &rx_softc[i];
702 		if ((sc->sc_open == 0) && (rxutab[i].b_active == 0)) {
703 			sc->sc_csbits = 0;
704 			continue;
705 		}
706 		dopen++;
707 		um = ui->ui_mi;
708 		rxc = &rx_ctlr[um->um_ctlr];
709 		if (++rxc->rxc_tocnt >= RX_MAXTIMEOUT) {
710 			rxc->rxc_tocnt = 0;
711 			if (um->um_tab.b_active) {
712 				printf("rx%d: timeout\n", i);/* for debugging */
713 				rxintr(um->um_ctlr);
714 			}
715 		}
716 	}
717 	if (dopen)
718 		timeout(rxwatch, (caddr_t)0, hz);
719 	else
720 		rxwstart = 0;
721 }
722 
723 rxreset(uban)
724 	int uban;
725 {
726 	register struct uba_ctlr *um;
727 	register struct rxdevice *rxaddr;
728 	register int ctlr;
729 
730 	for (ctlr = 0; ctlr < NFX; ctlr++) {
731 		if ((um = rxminfo[ctlr]) == 0 || um->um_ubanum != uban ||
732 		    um->um_alive == 0)
733 			continue;
734 		printf(" fx%d", ctlr);
735 		if (um->um_ubinfo) {
736 			printf("<%d>", UBAI_BDP(um->um_ubinfo));
737 			um->um_ubinfo = 0;
738 		}
739 		rx_ctlr[ctlr].rxc_state = RXS_IDLE;
740 		rxaddr = (struct rxdevice *)um->um_addr;
741 		rxaddr->rxcs = RX_INIT;
742 		while ((rxaddr->rxcs&RX_DONE) == 0)
743 			;
744 		rxstart(um);
745 	}
746 }
747 
748 rxread(dev, uio)
749 	dev_t dev;
750 	struct uio *uio;
751 {
752 	int unit = RXUNIT(dev);
753 	struct rx_softc *sc = &rx_softc[unit];
754 
755 	if (uio->uio_offset + uio->uio_resid > RXSIZE)
756 		return (ENXIO);
757 	if (uio->uio_offset < 0 || (uio->uio_offset & SECMASK) != 0)
758 		return (ENXIO);
759 	sc->sc_offset = uio->uio_offset % DEV_BSIZE;
760 	return (physio(rxstrategy, &rrxbuf[unit], dev, B_READ, minphys, uio));
761 }
762 
763 rxwrite(dev, uio)
764 	dev_t dev;
765 	struct uio *uio;
766 {
767 	int unit = RXUNIT(dev);
768 	struct rx_softc *sc = &rx_softc[unit];
769 
770 	if (uio->uio_offset + uio->uio_resid > RXSIZE)
771 		return (ENXIO);
772 	if (uio->uio_offset < 0 || (uio->uio_offset & SECMASK) != 0)
773 		return (ENXIO);
774 	sc->sc_offset = uio->uio_offset % DEV_BSIZE;
775 	return(physio(rxstrategy, &rrxbuf[unit], dev, B_WRITE, minphys, uio));
776 }
777 
778 /*
779  * Control routine:
780  * processes four kinds of requests:
781  *
782  *	(1) Set density (i.e., format the diskette) according to
783  *		  that specified data parameter
784  *	(2) Arrange for the next sector to be written with a deleted-
785  *		  data mark.
786  *	(3) Report whether the last sector read had a deleted-data mark
787  *	(4) Report the density of the diskette in the indicated drive
788  *	    (since the density it automatically determined by the driver,
789  *	     this is the only way to let an application program know the
790  *	     density)
791  *
792  * Requests relating to deleted-data marks can be handled right here.
793  * A "set density" (format) request, however, must additionally be
794  * processed through "rxstart", just like a read or write request.
795  */
796 
797 /*ARGSUSED3*/
798 rxioctl(dev, cmd, data, flag)
799 	dev_t dev;
800 	caddr_t data;
801 {
802 	int unit = RXUNIT(dev);
803 	struct rx_softc *sc = &rx_softc[unit];
804 
805 	switch (cmd) {
806 
807 	case RXIOC_FORMAT:
808 		if ((flag&FWRITE) == 0)
809 			return (EBADF);
810 		if (sc->sc_open > 1)
811 			return (EBUSY);
812 		if (*(int *)data)
813 			sc->sc_csbits |= RX_DDEN;
814 		else
815 			sc->sc_csbits &= ~RX_DDEN;
816 		return (rxformat(dev));
817 
818 	case RXIOC_WDDS:
819 		sc->sc_flags |= RXF_USEWDDS;
820 		return (0);
821 
822 	case RXIOC_RDDSMK:
823 		*(int *)data = sc->sc_flags & RXF_DDMK;
824 		return (0);
825 
826 	case RXIOC_GDENS:
827 		*(int *)data = sc->sc_csbits & RX_DDEN;
828 		return (0);
829 	}
830 	return (ENXIO);
831 }
832 
833 /*
834  * Initiate a format command.
835  */
836 rxformat(dev)
837 	dev_t dev;
838 {
839 	int unit = RXUNIT(dev);
840 	struct buf *bp;
841 	struct rx_softc *sc = &rx_softc[unit];
842 	int error = 0;
843 
844 	bp = &rrxbuf[unit];
845 	bp->b_flags = B_BUSY | B_CTRL;
846 	sc->sc_flags = RXF_FORMAT | RXF_LOCK;
847 	bp->b_dev = dev;
848 	bp->b_error = 0;
849 	bp->b_blkno = 0;
850 	rxstrategy(bp);
851 	iowait(bp);
852 	if (bp->b_flags & B_ERROR)
853 		error = bp->b_error;
854 	bp->b_flags &= ~B_BUSY;
855 	sc->sc_flags &= ~RXF_LOCK;
856 	return (error);
857 }
858 
859 /*
860  * A permanent hard error condition has occured,
861  * purge the buffer queue
862  */
863 rxpurge(um)
864 	register struct uba_ctlr *um;
865 {
866 	register struct buf *bp, *dp;
867 
868 	dp = um->um_tab.b_actf;
869 	while (dp->b_actf) {
870 		dp->b_errcnt++;
871 		bp = dp->b_actf;
872 		bp->b_error = EIO;
873 		bp->b_flags |= B_ERROR;
874 		iodone(bp);
875 		dp->b_actf = bp->av_forw;
876 	}
877 }
878 #endif
879