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