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, §or, &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, §or, &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, §or, &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