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.1 (Berkeley) 6/5/86 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 "../machine/pte.h" 28: 29: #include "param.h" 30: #include "buf.h" 31: #include "systm.h" 32: #include "conf.h" 33: #include "errno.h" 34: #include "time.h" 35: #include "kernel.h" 36: #include "uio.h" 37: #include "file.h" 38: 39: #include "../vax/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: rxslave(ui, reg) 147: struct uba_device *ui; 148: caddr_t reg; 149: { 150: 151: ui->ui_dk = 1; 152: return (ui->ui_slave == 0 || ui->ui_slave == 1); 153: } 154: 155: /*ARGSUSED*/ 156: rxattach(ui) 157: struct uba_device *ui; 158: { 159: 160: } 161: 162: /*ARGSUSED1*/ 163: rxopen(dev, flag) 164: dev_t dev; 165: { 166: register int unit = RXUNIT(dev); 167: register struct rx_softc *sc; 168: register struct uba_device *ui; 169: struct rx_ctlr *rxc; 170: 171: if (unit >= NRX || (ui = rxdinfo[unit]) == 0 || ui->ui_alive == 0) 172: return (ENXIO); 173: sc = &rx_softc[unit]; 174: if (sc->sc_open == 0 && sc->sc_csbits == 0) { 175: struct buf *bp = &erxbuf[unit]; 176: /* 177: * lock the device while an open 178: * is in progress 179: */ 180: sc->sc_flags = (minor(dev) & RXF_DEVTYPE) | RXF_LOCK; 181: sc->sc_csbits = RX_INTR; 182: sc->sc_csbits |= ui->ui_slave == 0 ? RX_DRV0 : RX_DRV1; 183: 184: bp->b_dev = dev; 185: bp->b_flags = B_RDSTAT | B_BUSY; 186: bp->b_error = 0; 187: bp->b_blkno = 0; 188: sc->sc_offset = 0; 189: sc->sc_resid = 0; 190: /* 191: * read device status to determine if 192: * a floppy is present in the drive and 193: * what density it is 194: */ 195: rxstrategy(bp); 196: iowait(bp); 197: if (bp->b_flags & B_ERROR) { 198: sc->sc_csbits = 0; 199: sc->sc_flags &= ~RXF_LOCK; 200: return (bp->b_error); 201: } 202: if (rxwstart++ == 0) { 203: rxc = &rx_ctlr[ui->ui_mi->um_ctlr]; 204: rxc->rxc_tocnt = 0; 205: timeout(rxwatch, (caddr_t)0, hz); /* start watchdog */ 206: } 207: #ifdef RXDEBUG 208: printf("rxopen: csbits=0x%x\n", sc->sc_csbits); 209: #endif 210: sc->sc_flags &= ~RXF_LOCK; 211: } else { 212: if (sc->sc_flags & RXF_LOCK) 213: return(EBUSY); 214: } 215: sc->sc_open = 1; 216: return (0); 217: } 218: 219: /*ARGSUSED1*/ 220: rxclose(dev, flag) 221: dev_t dev; 222: { 223: register struct rx_softc *sc = &rx_softc[RXUNIT(dev)]; 224: 225: sc->sc_open = 0; 226: #ifdef RXDEBUG 227: printf("rxclose: dev=0x%x, sc_open=%d\n", dev, sc->sc_open); 228: #endif 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, §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: 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: 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: if (um->um_ubinfo) 735: um->um_ubinfo = 0; 736: rx_ctlr[ctlr].rxc_state = RXS_IDLE; 737: rxaddr = (struct rxdevice *)um->um_addr; 738: rxaddr->rxcs = RX_INIT; 739: while ((rxaddr->rxcs&RX_DONE) == 0) 740: ; 741: rxstart(um); 742: } 743: } 744: 745: rxread(dev, uio) 746: dev_t dev; 747: struct uio *uio; 748: { 749: int unit = RXUNIT(dev); 750: struct rx_softc *sc = &rx_softc[unit]; 751: 752: if (uio->uio_offset + uio->uio_resid > RXSIZE) 753: return (ENXIO); 754: if (uio->uio_offset < 0 || (uio->uio_offset & SECMASK) != 0) 755: return (ENXIO); 756: sc->sc_offset = uio->uio_offset % DEV_BSIZE; 757: return (physio(rxstrategy, &rrxbuf[unit], dev, B_READ, minphys, uio)); 758: } 759: 760: rxwrite(dev, uio) 761: dev_t dev; 762: struct uio *uio; 763: { 764: int unit = RXUNIT(dev); 765: struct rx_softc *sc = &rx_softc[unit]; 766: 767: if (uio->uio_offset + uio->uio_resid > RXSIZE) 768: return (ENXIO); 769: if (uio->uio_offset < 0 || (uio->uio_offset & SECMASK) != 0) 770: return (ENXIO); 771: sc->sc_offset = uio->uio_offset % DEV_BSIZE; 772: return(physio(rxstrategy, &rrxbuf[unit], dev, B_WRITE, minphys, uio)); 773: } 774: 775: /* 776: * Control routine: 777: * processes four kinds of requests: 778: * 779: * (1) Set density (i.e., format the diskette) according to 780: * that specified data parameter 781: * (2) Arrange for the next sector to be written with a deleted- 782: * data mark. 783: * (3) Report whether the last sector read had a deleted-data mark 784: * (4) Report the density of the diskette in the indicated drive 785: * (since the density it automatically determined by the driver, 786: * this is the only way to let an application program know the 787: * density) 788: * 789: * Requests relating to deleted-data marks can be handled right here. 790: * A "set density" (format) request, however, must additionally be 791: * processed through "rxstart", just like a read or write request. 792: */ 793: 794: /*ARGSUSED3*/ 795: rxioctl(dev, cmd, data, flag) 796: dev_t dev; 797: caddr_t data; 798: { 799: int unit = RXUNIT(dev); 800: struct rx_softc *sc = &rx_softc[unit]; 801: 802: switch (cmd) { 803: 804: case RXIOC_FORMAT: 805: if ((flag&FWRITE) == 0) 806: return (EBADF); 807: if (sc->sc_open > 1) 808: return (EBUSY); 809: if (*(int *)data) 810: sc->sc_csbits |= RX_DDEN; 811: else 812: sc->sc_csbits &= ~RX_DDEN; 813: return (rxformat(dev)); 814: 815: case RXIOC_WDDS: 816: sc->sc_flags |= RXF_USEWDDS; 817: return (0); 818: 819: case RXIOC_RDDSMK: 820: *(int *)data = sc->sc_flags & RXF_DDMK; 821: return (0); 822: 823: case RXIOC_GDENS: 824: *(int *)data = sc->sc_csbits & RX_DDEN; 825: return (0); 826: } 827: return (ENXIO); 828: } 829: 830: /* 831: * Initiate a format command. 832: */ 833: rxformat(dev) 834: dev_t dev; 835: { 836: int unit = RXUNIT(dev); 837: struct buf *bp; 838: struct rx_softc *sc = &rx_softc[unit]; 839: int s, error = 0; 840: 841: bp = &rrxbuf[unit]; 842: bp->b_flags = B_BUSY | B_CTRL; 843: sc->sc_flags = RXF_FORMAT | RXF_LOCK; 844: bp->b_dev = dev; 845: bp->b_error = 0; 846: bp->b_blkno = 0; 847: rxstrategy(bp); 848: iowait(bp); 849: if (bp->b_flags & B_ERROR) 850: error = bp->b_error; 851: bp->b_flags &= ~B_BUSY; 852: sc->sc_flags &= ~RXF_LOCK; 853: return (error); 854: } 855: 856: /* 857: * A permanent hard error condition has occured, 858: * purge the buffer queue 859: */ 860: rxpurge(um) 861: register struct uba_ctlr *um; 862: { 863: register struct buf *bp, *dp; 864: 865: dp = um->um_tab.b_actf; 866: while (dp->b_actf) { 867: dp->b_errcnt++; 868: bp = dp->b_actf; 869: bp->b_error = EIO; 870: bp->b_flags |= B_ERROR; 871: iodone(bp); 872: dp->b_actf = bp->av_forw; 873: } 874: } 875: #endif