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