xref: /original-bsd/sys/vax/uba/rx.c (revision 92d3de31)
1 /*	rx.c	4.17	83/04/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 "../h/param.h"
24 #include "../h/buf.h"
25 #include "../h/systm.h"
26 #include "../h/conf.h"
27 #include "../h/errno.h"
28 #include "../h/time.h"
29 #include "../h/kernel.h"
30 #include "../h/uio.h"
31 #include "../h/file.h"
32 
33 #include "../vax/cpu.h"
34 #include "../vax/nexus.h"
35 
36 #include "../vaxuba/ubavar.h"
37 #include "../vaxuba/ubareg.h"
38 #include "../vaxuba/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 	int	sc_csbits;	/* constant bits for CS register */
77 	int	sc_open;	/* count number of opens */
78 	int	sc_offset;	/* raw mode kludge to avoid restricting */
79 				/* single sector transfers to start on */
80 				/* DEV_BSIZE boundaries */
81 	/*
82 	 * The rest of this structure is used to
83 	 * store temporaries while simulating multi
84 	 * sector transfers
85 	 */
86 	caddr_t	sc_uaddr;	/* unibus base address */
87 	long	sc_bcnt;	/* total transfer count */
88 	long	sc_resid;	/* no. of bytes left to transfer */
89 } rx_softc[NRX];
90 
91 struct rxerr {
92 	short	rxcs;
93 	short	rxdb;
94 	short	rxxt[4];	/* error code dump from controller */
95 } rxerr[NRX];
96 /* End of per-drive data */
97 
98 struct	uba_device *rxdinfo[NRX];
99 struct	uba_ctlr *rxminfo[NFX];
100 
101 int rxprobe(), rxslave(), rxattach(), rxdgo(), rxintr(), rxwatch(), rxphys();
102 u_short rxstd[] = { 0177170, 0177150, 0 };
103 struct uba_driver fxdriver =
104   { rxprobe, rxslave, rxattach, rxdgo, rxstd, "rx", rxdinfo, "fx", rxminfo };
105 
106 int	rxwstart;
107 #define	RXUNIT(dev)	(minor(dev)>>3)
108 #define	MASKREG(reg)	(reg&0xffff)
109 
110 /* constants related to floppy data capacity */
111 #define	RXSECS	2002				/* # sectors on a floppy */
112 #define	DDSTATE	(sc->sc_csbits&RX_DDEN)
113 #define	NBPS	(DDSTATE ? 256 : 128)		/* # bytes per sector */
114 #define	RXSIZE	(DDSTATE ? 512512 : 256256)	/* # bytes per disk */
115 #define	SECMASK	(DDSTATE ? 0xff : 0x7f)		/* shifted-out bits of offset */
116 
117 #define	B_CTRL		0x80000000		/* control (format) request */
118 #define B_RDSTAT	0x40000000		/* read drive status (open) */
119 
120 /*ARGSUSED*/
121 rxprobe (reg)
122 	caddr_t reg;
123 {
124 	register int br, cvec;			/* value-result */
125 	struct rxdevice *rxaddr = (struct rxdevice *)reg;
126 
127 #ifdef lint
128 	br = 0; cvec = br; br = cvec;
129 	rxintr(0);
130 #endif lint
131 	rxaddr->rxcs = RX_INTR;
132 	DELAY(10);
133 	rxaddr->rxcs = 0;
134 	return (sizeof (*rxaddr));
135 }
136 
137 rxslave(ui, reg)
138 	struct uba_device *ui;
139 	caddr_t reg;
140 {
141 
142 	ui->ui_dk = 1;
143 	return (ui->ui_slave == 0 || ui->ui_slave == 1);
144 }
145 
146 /*ARGSUSED*/
147 rxattach(ui)
148 	struct uba_device *ui;
149 {
150 
151 }
152 
153 /*ARGSUSED1*/
154 rxopen(dev, flag)
155 	dev_t dev;
156 {
157 	register int unit = RXUNIT(dev);
158 	register struct rx_softc *sc;
159 	register struct uba_device *ui;
160 	struct rx_ctlr *rxc;
161 
162 	if (unit >= NRX || (ui = rxdinfo[unit]) == 0 || ui->ui_alive == 0)
163 		return (ENXIO);
164 	sc = &rx_softc[unit];
165 	if (sc->sc_open == 0 && sc->sc_csbits == 0) {
166 		struct buf *bp = &erxbuf[unit];
167 		/*
168 		 * lock the device while an open
169 		 * is in progress
170 		 */
171 		sc->sc_flags = (minor(dev) & RXF_DEVTYPE) | RXF_LOCK;
172 		sc->sc_csbits = RX_INTR;
173 		sc->sc_csbits |= ui->ui_slave == 0 ? RX_DRV0 : RX_DRV1;
174 
175 		bp->b_dev = dev;
176 		bp->b_flags = B_RDSTAT | B_BUSY;
177 		bp->b_error = 0;
178 		bp->b_blkno = 0;
179 		/*
180 		 * read device status to determine if
181 		 * a floppy is present in the drive and
182 		 * what density it is
183 		 */
184 		rxstrategy(bp);
185 		iowait(bp);
186 		if (bp->b_flags & B_ERROR) {
187 			sc->sc_csbits = 0;
188 			return (bp->b_error);
189 		}
190 		if (rxwstart++ == 0) {
191 			rxc = &rx_ctlr[ui->ui_mi->um_ctlr];
192 			rxc->rxc_tocnt = 0;
193 			timeout(rxwatch, (caddr_t)0, hz);  /* start watchdog */
194 		}
195 #ifdef RXDEBUG
196 		printf("rxopen: csbits=0x%x\n", sc->sc_csbits);
197 #endif
198 		sc->sc_flags &= ~RXF_LOCK;
199 	} else	{
200 		if (sc->sc_flags & RXF_LOCK)
201 			return(EBUSY);
202 	}
203 	sc->sc_open++;
204 	return (0);
205 }
206 
207 /*ARGSUSED1*/
208 rxclose(dev, flag)
209 	dev_t dev;
210 {
211 	register struct rx_softc *sc = &rx_softc[RXUNIT(dev)];
212 
213 	--sc->sc_open;
214 #ifdef RXDEBUG
215 	printf("rxclose: dev=0x%x, sc_open=%d\n", dev, sc->sc_open);
216 #endif
217 }
218 
219 rxstrategy(bp)
220 	register struct buf *bp;
221 {
222 	struct uba_device *ui;
223 	register struct buf *dp;
224 	struct rx_softc *sc;
225 	int s, unit = RXUNIT(bp->b_dev);
226 
227 	if (unit >= NRX)
228 		goto bad;
229 	ui = rxdinfo[unit];
230 	if (ui == 0 || ui->ui_alive == 0)
231 		goto bad;
232 	sc = &rx_softc[unit];
233 	if (bp->b_blkno < 0 || (bp->b_blkno * DEV_BSIZE) > RXSIZE )
234 		goto bad;
235 #ifdef RXDEBUG
236 	printf("rxstrategy: bp=0x%x, flgs=0x%x, unit=%d, block=%d, count=%d\n",
237 		bp, bp->b_flags, unit, bp->b_blkno, bp->b_bcount);
238 #endif
239 	s = spl5();
240 	bp->b_cylin = bp->b_blkno;	/* don't care to calculate trackno */
241 	dp = &rxutab[unit];
242 	disksort(dp, bp);
243 	if (dp->b_active == 0) {
244 		rxustart(ui);
245 		bp = &ui->ui_mi->um_tab;
246 		if (bp->b_actf && bp->b_active == 0)
247 			rxstart(ui->ui_mi);
248 	}
249 	splx(s);
250 	return;
251 
252 bad:
253 	bp->b_flags |= B_ERROR;
254 	iodone(bp);
255 	bp->b_error = ENXIO;
256 	return;
257 }
258 
259 /*
260  * Unit start routine.
261  * Put this unit on the ready queue for the controller
262  */
263 rxustart(ui)
264 	register struct uba_device *ui;
265 {
266 	struct buf *dp = &rxutab[ui->ui_unit];
267 	struct uba_ctlr *um = ui->ui_mi;
268 
269 	dp->b_forw = NULL;
270 	if (um->um_tab.b_actf == NULL)
271 		um->um_tab.b_actf = dp;
272 	else
273 		um->um_tab.b_actl->b_forw = dp;
274 	um->um_tab.b_actl = dp;
275 	dp->b_active++;
276 }
277 /*
278  * Sector mapping routine.
279  * Two independent sets of choices are available:
280  *
281  * (a) The first logical sector may either be on track 1 or track 0.
282  * (b) The sectors on a track may either be taken in 2-for-1 interleaved
283  *	 fashion or directly.
284  * This gives a total of four possible mapping schemes.
285  *
286  * Physical tracks on the RX02 are numbered 0-76.  Physical sectors on
287  * each track are numbered 1-26.
288  *
289  * When interleaving is used, sectors on the first logical track are
290  * taken in the order 1, 3, 5, ..., 25, 2, 4, 6, ..., 26.  A skew of
291  * six sectors per track is also used (to allow time for the heads to
292  * move); hence, the sectors on the second logical track are taken in
293  * the order 7, 9, 11, ..., 25, 1, 3, 5, 8, 10, 12, ..., 26, 2, 4, 6;
294  * the third logical track starts with sector 13; and so on.
295  *
296  * When the mapping starts with track 1, track 0 is the last logical
297  * track, and this track is always handled directly (without inter-
298  * leaving), even when the rest of the disk is interleaved.  (This is
299  * still compatible with DEC RT-11, which does not use track 0 at all.)
300  */
301 rxmap(bp, psector, ptrack)
302 	struct buf *bp;
303 	int *psector, *ptrack;
304 {
305 	register int lt, ls, ptoff;
306 	struct rx_softc *sc = &rx_softc[RXUNIT(bp->b_dev)];
307 
308 	ls = ( bp->b_blkno * DEV_BSIZE + ( sc->sc_offset - sc->sc_resid ))/NBPS;
309 	lt = ls / 26;
310 	ls %= 26;
311 	/*
312 	 * The "physical track offset" (ptoff) takes the
313 	 * starting physical track (0 or 1) and the desired
314 	 * interleaving into account.  If lt+ptoff >= 77,
315 	 * then interleaving is not performed.
316 	 */
317 	ptoff = 0;
318 	if (sc->sc_flags & RXF_DIRECT)
319 		ptoff = 77;
320 	if (sc->sc_flags & RXF_TRKONE)
321 		ptoff++;
322 	if (lt + ptoff < 77)
323 		ls = ((ls << 1) + (ls >= 13) + (6*lt)) % 26;
324 	*ptrack = (lt + ptoff) % 77;
325 	*psector = ls + 1;
326 }
327 
328 /*
329  * Controller start routine.
330  * Start a new transfer or continue a multisector
331  * transfer. If this is a new transfer (dp->b_active == 1)
332  * save the start address of the data buffer and the total
333  * byte count in the soft control structure. These are
334  * restored into the buffer structure when the transfer has
335  * been completed, before calling 'iodone'.
336  */
337 rxstart(um)
338 	register struct uba_ctlr *um;
339 {
340 	register struct rxdevice *rxaddr;
341 	register struct rx_ctlr *rxc;
342 	register struct rx_softc *sc;
343 	struct buf *dp, *bp;
344 	int unit, sector, track;
345 
346 	if (um->um_tab.b_active)
347 		return;
348 loop:
349 	if ((dp = um->um_tab.b_actf) == NULL)
350 		return;
351 	if ((bp = dp->b_actf) == NULL) {
352 		um->um_tab.b_actf = dp->b_forw;
353 		goto loop;
354 	}
355 	um->um_tab.b_active++;
356 	unit = RXUNIT(bp->b_dev);
357 	sc = &rx_softc[unit];
358 	if (dp->b_active == 1) {
359 		sc->sc_resid = bp->b_bcount;
360 		sc->sc_uaddr = bp->b_un.b_addr;
361 		sc->sc_bcnt = bp->b_bcount;
362 		sc->sc_offset += sc->sc_bcnt;
363 		dp->b_active++;
364 	}
365 	rxaddr = (struct rxdevice *)um->um_addr;
366 	rxc = &rx_ctlr[um->um_ctlr];
367 	bp->b_bcount = sc->sc_resid;
368 	if (bp->b_bcount > NBPS)
369 		bp->b_bcount = NBPS;
370 	rxc->rxc_tocnt = 0;
371 #ifdef RXDEBUG
372 	printf("rxstart: ");
373 #endif
374 	if (rxaddr->rxcs == 0x800) {
375 		/*
376 		 * 'Volume valid'? (check if the
377 		 * drive unit has been powered down)
378 		 */
379 		rxaddr->rxcs = RX_INIT;
380 		while((rxaddr->rxcs&RX_DONE) == 0)
381 			;
382 	}
383 	if (bp->b_flags & B_CTRL) {				/* format */
384 		rxc->rxc_state = RXS_FORMAT;
385 		rxaddr->rxcs = RX_FORMAT | sc->sc_csbits;
386 		while ((rxaddr->rxcs&RX_TREQ) == 0)
387 			;
388 		rxaddr->rxdb = 'I';
389 		return;
390 	}
391 	if (bp->b_flags & B_RDSTAT) {			/* read drive status */
392 		rxc->rxc_state = RXS_RDSTAT;
393 		rxaddr->rxcs = RX_RDSTAT | sc->sc_csbits;
394 		return;
395 	}
396 
397 	if (bp->b_flags & B_READ) {
398 		rxmap(bp, &sector, &track);			/* read */
399 #ifdef RXDEBUG
400 		printf("read tr=%d, sc=%d", track, sector);
401 #endif
402 		rxc->rxc_state = RXS_READ;
403 		rxaddr->rxcs = RX_READ | sc->sc_csbits;
404 		while ((rxaddr->rxcs&RX_TREQ) == 0)
405 			;
406 		rxaddr->rxdb = (u_short)sector;
407 		while ((rxaddr->rxcs&RX_TREQ) == 0)
408 			;
409 		rxaddr->rxdb = (u_short)track;
410 	} else {
411 #ifdef RXDEBUG
412 		printf("write");
413 #endif
414 		rxc->rxc_state = RXS_FILL;			/* write */
415 		um->um_cmd = RX_FILL;
416 		(void) ubago(rxdinfo[unit]);
417 	}
418 #ifdef RXDEBUG
419 	printf("\n");
420 #endif
421 }
422 
423 rxdgo(um)
424 	struct uba_ctlr *um;
425 {
426 	register struct rxdevice *rxaddr = (struct rxdevice *)um->um_addr;
427 	int ubinfo = um->um_ubinfo;
428 	struct buf *bp = um->um_tab.b_actf->b_actf;
429 	struct rx_softc *sc = &rx_softc[RXUNIT(bp->b_dev)];
430 	struct rx_ctlr *rxc = &rx_ctlr[um->um_ctlr];
431 
432 	rxaddr->rxcs = um->um_cmd | ((ubinfo & 0x30000) >> 4) | sc->sc_csbits;
433 	if (rxc->rxc_state != RXS_RDERR) {
434 		while ((rxaddr->rxcs&RX_TREQ) == 0)
435 			;
436 		rxaddr->rxdb = (u_short) bp->b_bcount >> 1;
437 	}
438 	while ((rxaddr->rxcs&RX_TREQ) == 0)
439 		;
440 	rxaddr->rxdb = (u_short) ubinfo;
441 }
442 
443 rxintr(ctlr)
444 	int ctlr;
445 {
446 	int unit, sector, track;
447 	struct uba_ctlr *um = rxminfo[ctlr];
448 	register struct rxdevice *rxaddr;
449 	register struct buf *bp, *dp;
450 	register struct rx_softc *sc;
451 	struct uba_device *ui;
452 	struct rxerr *er;
453 	struct rx_ctlr *rxc;
454 
455 	if (!um->um_tab.b_active)
456 		return;
457 	dp = um->um_tab.b_actf;
458 	if (!dp->b_active)
459 		return;
460 	bp = dp->b_actf;
461 	unit = RXUNIT(bp->b_dev);
462 	sc = &rx_softc[unit];
463 	ui = rxdinfo[unit];
464 	rxaddr = (struct rxdevice *)um->um_addr;
465 	rxc = &rx_ctlr[um->um_ctlr];
466 	rxc->rxc_tocnt = 0;
467 	er = &rxerr[unit];
468 #ifdef RXDEBUG
469 	printf("rxintr: dev=%x, state=%d, status=0x%x",
470 		bp->b_dev, rxc->rxc_state, rxaddr->rxcs);
471 #endif
472 	if ((rxaddr->rxcs & RX_ERR) &&
473 	    (rxc->rxc_state != RXS_RDSTAT) && (rxc->rxc_state != RXS_RDERR))
474 		goto error;
475 	switch (rxc->rxc_state) {
476 
477 	/*
478 	 * Incomplete commands.  Perform next step
479 	 * and return.  Note that b_active is set on
480 	 * entrance and, therefore, also on exit.
481 	 */
482 	case RXS_READ:
483 		if (rxaddr->rxdb & RXES_DDMARK)
484 			sc->sc_flags |= RXF_DDMK;
485 		else
486 			sc->sc_flags &= ~RXF_DDMK;
487 		rxc->rxc_state = RXS_EMPTY;
488 		um->um_cmd = RX_EMPTY;
489 		(void) ubago(ui);
490 #ifdef RXDEBUG
491 		printf("\n");
492 #endif
493 		return;
494 
495 	case RXS_FILL:
496 		rxc->rxc_state = RXS_WRITE;
497 		if (sc->sc_flags & RXF_USEWDDS) {
498 			rxaddr->rxcs = RX_WDDS | sc->sc_csbits;
499 			sc->sc_flags &= ~RXF_USEWDDS;
500 		} else
501 			rxaddr->rxcs = RX_WRITE | sc->sc_csbits;
502 		rxmap(bp, &sector, &track);
503 		while ((rxaddr->rxcs&RX_TREQ) == 0)
504 			;
505 		rxaddr->rxdb = sector;
506 		while ((rxaddr->rxcs&RX_TREQ) == 0)
507 			;
508 		rxaddr->rxdb = track;
509 #ifdef RXDEBUG
510 		printf("\n");
511 #endif
512 		return;
513 
514 	/*
515 	 * Possibly completed command.
516 	 */
517 	case RXS_RDSTAT:
518 		if (bp->b_flags & B_RDSTAT) {
519 			if ((rxaddr->rxdb&RXES_READY) == 0) {
520 				bp->b_flags |= B_ERROR;
521 				bp->b_error = ENODEV;
522 			} else {
523 				sc->sc_csbits |= rxaddr->rxdb&RXES_DBLDEN ?
524 					RX_DDEN : RX_SDEN;
525 			}
526 			goto rdone;
527 		}
528 		if (rxaddr->rxdb&RXES_READY)
529 			goto rderr;
530 		bp->b_error = EBUSY;
531 		bp->b_flags |= B_ERROR;
532 		goto done;
533 
534 	/*
535 	 * Command completed.
536 	 */
537 	case RXS_EMPTY:
538 	case RXS_WRITE:
539 		goto done;
540 
541 	case RXS_FORMAT:
542 		goto rdone;
543 
544 	case RXS_RDERR:
545 		bp = bp->b_back;
546 		rxmap(bp, &sector, &track);
547 		printf("rx%d: hard error, trk %d psec %d ",
548 			unit, track, sector);
549 		printf("cs=%b, db=%b, err=", MASKREG(er->rxcs),
550 			RXCS_BITS, MASKREG(er->rxdb), RXES_BITS);
551 		printf("%x, %x, %x, %x\n", MASKREG(er->rxxt[0]),
552 			MASKREG(er->rxxt[1]), MASKREG(er->rxxt[2]),
553 			MASKREG(er->rxxt[3]));
554 		goto done;
555 
556 	default:
557 		printf("rx%d: state %d (reset)\n", unit, rxc->rxc_state);
558 		rxreset(um->um_ubanum);
559 		return;
560 	}
561 error:
562 	/*
563 	 * In case of an error:
564 	 *  (a) Give up now if a format (ioctl) was in progress, if a
565 	 *	  density error was detected, or if the drive went offline
566 	 *  (b) Retry up to nine times if a CRC (data) error was detected,
567 	 *	  then give up if the error persists.
568 	 *  (c) In all other cases, reinitialize the drive and try the
569 	 *	  operation once more before giving up.
570 	 */
571 	if (rxc->rxc_state == RXS_FORMAT || (rxaddr->rxdb&RXES_DENERR))
572 		goto giveup;
573 	if (rxaddr->rxdb & RXES_CRCERR) {
574 		if (++bp->b_errcnt >= 10)
575 			goto giveup;
576 		goto retry;
577 	}
578 	bp->b_errcnt += 9;
579 	if (bp->b_errcnt >= 10)
580 		goto giveup;
581 	rxaddr->rxcs = RX_INIT;
582 	/* no way to get an interrupt for "init done", so just wait */
583 	while ((rxaddr->rxcs&RX_DONE) == 0)
584 		;
585 	/* if someone opened the drive: give up */
586 	if ((rxaddr->rxdb&RXES_READY) == 0)
587 		goto giveup;
588 retry:
589 	/*
590 	 * In case we already have UNIBUS resources, give
591 	 * them back since we reallocate things in rxstart.
592 	 */
593 	if (um->um_ubinfo)
594 		ubadone(um);
595 	um->um_tab.b_active = 0;
596 	rxstart(um);
597 	return;
598 
599 giveup:
600 	/*
601 	 * Hard I/O error --
602 	 * Density errors are not noted on the console since the
603 	 * only way to determine the density of an unknown disk
604 	 * is to try one density or the other at random and see
605 	 * which one doesn't give a density error.
606 	 */
607 	if (rxaddr->rxdb & RXES_DENERR) {
608 		bp->b_error = ENODEV;
609 		bp->b_flags |= B_ERROR;
610 		goto done;
611 	}
612 	rxc->rxc_state = RXS_RDSTAT;
613 	rxaddr->rxcs = RX_RDSTAT | sc->sc_csbits;
614 	return;
615 
616 rderr:
617 	/*
618 	 * A hard error (other than not ready or density) has occurred.
619 	 * Read the extended error status information.
620 	 * Before doing this, save the current CS and DB register values,
621 	 * because the read error status operation may modify them.
622 	 * Insert buffer with request at the head of the queue, and
623 	 * save a pointer to the data buffer, so it can be restored
624 	 * when the read error status operation is finished.
625 	 */
626 	bp->b_error = EIO;
627 	bp->b_flags |= B_ERROR;
628 	ubadone(um);
629 	erxbuf[unit].b_back = bp;	/* save the data buffer pointer */
630 	er->rxcs = rxaddr->rxcs;
631 	er->rxdb = rxaddr->rxdb;
632 	bp = &erxbuf[unit];
633 	bp->b_un.b_addr = (caddr_t)er->rxxt;
634 	bp->b_bcount = sizeof (er->rxxt);
635 	bp->b_flags &= ~(B_DIRTY|B_UAREA|B_PHYS|B_PAGET);
636 	if (dp->b_actf == NULL)
637 		dp->b_actl = bp;
638 	bp->b_forw = dp->b_actf;
639 	dp->b_actf = bp;
640 	rxc->rxc_state = RXS_RDERR;
641 	um->um_cmd = RX_RDERR;
642 	(void) ubago(ui);
643 	return;
644 
645 done:
646 	ubadone(um);
647 rdone:
648 	um->um_tab.b_active = 0;
649 	um->um_tab.b_errcnt = 0;
650 	if ((sc->sc_resid -= NBPS) > 0) {
651 		bp->b_un.b_addr += NBPS;
652 #ifdef RXDEBUG
653 		printf("\n");
654 #endif
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(" old bp=0x%x, new=0x%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&RXIOC_MASK) {
797 
798 	case RXIOC_FORMAT:
799 #ifdef notdef	/* temporarily removed (the flag argument is */
800 		/* is actually always zero at this point) */
801 		if ((flag&FWRITE) == 0)
802 			return (EBADF);
803 #endif
804 		if (sc->sc_open > 1 )
805 			return (EBUSY);
806 		if (*(int *)data)
807 			sc->sc_csbits |= RX_DDEN;
808 		else
809 			sc->sc_csbits &= ~RX_DDEN;
810 		return (rxformat(dev));
811 
812 	case RXIOC_WDDS:
813 		sc->sc_flags |= RXF_USEWDDS;
814 		return (0);
815 
816 	case RXIOC_RDDSMK:
817 		*(int *)data = sc->sc_flags & RXF_DDMK;
818 		return (0);
819 
820 	case RXIOC_GDENS:
821 		*(int *)data = sc->sc_csbits & RX_DDEN;
822 		return (0);
823 	}
824 	return (ENXIO);
825 }
826 
827 /*
828  * Initiate a format command.
829  */
830 rxformat(dev)
831 	dev_t dev;
832 {
833 	int unit = RXUNIT(dev);
834 	struct buf *bp;
835 	struct rx_softc *sc = &rx_softc[unit];
836 	int s, error = 0;
837 
838 	bp = &rrxbuf[unit];
839 	bp->b_flags = B_BUSY | B_CTRL;
840 	sc->sc_flags = RXF_FORMAT | RXF_LOCK;
841 	bp->b_dev = dev;
842 	bp->b_error = 0;
843 	bp->b_blkno = 0;
844 	rxstrategy(bp);
845 	iowait(bp);
846 	if (bp->b_flags & B_ERROR)
847 		error = bp->b_error;
848 	bp->b_flags &= ~B_BUSY;
849 	sc->sc_flags &= ~RXF_LOCK;
850 	return (error);
851 }
852 #endif
853