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*/
rxprobe(reg)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*/
rxopen(dev,flag)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*/
rxclose(dev,flag)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
rxstrategy(bp)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 */
rxustart(ui)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 */
rxstart(um)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, §or, &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
rxintr(ctlr)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, §or, &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, §or, &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
rxwatch()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
rxreset(uban)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
rxread(dev,uio)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
rxwrite(dev,uio)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*/
rxioctl(dev,cmd,data,flag)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 */
rxformat(dev)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 */
rxpurge(um)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