|
|
1.1 ! root 1: /* ! 2: * This is a driver for the IBM AT (286 & up) floppy, using interrupts and DMA ! 3: * on the NEC 756 floppy chip. ! 4: * Handles single/double/quad density drives, 8/9/15/18 sectors per track. ! 5: * ! 6: * Minor device assignments: xxuuhkkk ! 7: * uu - unit = 0/1/2/3 ! 8: * kkk - kind, struct fdata infra. ! 9: * h - alternating head rather than side by side ! 10: * ! 11: */ ! 12: ! 13: #include <sys/coherent.h> ! 14: #include <sys/buf.h> ! 15: #include <sys/con.h> ! 16: #include <sys/stat.h> ! 17: #include <errno.h> ! 18: #include <sys/timeout.h> ! 19: #include <sys/fdioctl.h> ! 20: #include <sys/sched.h> ! 21: #include <sys/dmac.h> ! 22: #include <sys/devices.h> ! 23: ! 24: #ifdef _I386 ! 25: #include <sys/reg.h> ! 26: #else ! 27: #include <sys/i8086.h> ! 28: #endif ! 29: ! 30: #define BIT(n) (1 << (n)) ! 31: ! 32: #include <sys/abios.h> ! 33: static short intimeout; ! 34: static request_block_fl fl_rb; ! 35: ! 36: void floppy_function(); ! 37: void floppy_functionb(); ! 38: static void fl_drive_off(); ! 39: ! 40: /* ! 41: * Patchable parameters (default to IBM PC/XT values). ! 42: */ ! 43: ! 44: int fl_srt = 0xC; /* Floppy seek step rate, in unit 2 millisec */ ! 45: /* NOT DIRECTLY ENCODED */ ! 46: /* COMPAQ wants 0xD */ ! 47: int fl_hlt = 1; /* Floppy head load time, in unit 4 millisec */ ! 48: int fl_hut = 0xF; /* Floppy head unload time, in unit 32 millisec */ ! 49: ! 50: int flload(); ! 51: int flunload(); ! 52: void flreset(); ! 53: int flopen(); ! 54: int flblock(); ! 55: int flread(); ! 56: int flwrite(); ! 57: int flioctl(); ! 58: static void flstart(); ! 59: static void flintr(); ! 60: static void fldone(); ! 61: static void fltimer(); ! 62: int nulldev(); ! 63: int nonedev(); ! 64: ! 65: CON flcon = { ! 66: DFBLK|DFCHR, /* Flags */ ! 67: FL_MAJOR, /* Major index */ ! 68: flopen, /* Open */ ! 69: nulldev, /* Close */ ! 70: flblock, /* Block */ ! 71: flread, /* Read */ ! 72: flwrite, /* Write */ ! 73: flioctl, /* Ioctl */ ! 74: nulldev, /* Powerfail */ ! 75: fltimer, /* Timeout */ ! 76: flload, /* Load */ ! 77: flunload /* Unload */ ! 78: }; ! 79: ! 80: /* ! 81: * Driver States. ! 82: */ ! 83: #ifdef OLD ! 84: #define SIDLE 0 /* Idle */ ! 85: #define SSEEK 1 /* Need seek */ ! 86: #define SRDWR 2 /* Need read/write command */ ! 87: #define SENDIO 3 /* Need end I/O processing */ ! 88: #define SDELAY 4 /* Delay before next disk operation */ ! 89: #define SHDLY 5 /* Head settling delay before r/w */ ! 90: #define SRESET 6 /* Doing a reset */ ! 91: #else ! 92: #define SIDLE 0 /* controller idle */ ! 93: #define SRETRY 1 /* seeking */ ! 94: #define SREAD 2 /* reading */ ! 95: #define SWRITE 3 /* writing */ ! 96: #define SRESET 4 /* reseting */ ! 97: ! 98: extern char *smsg[]; ! 99: #endif ! 100: ! 101: #define funit(x) (minor(x)>>4) /* Unit/drive number */ ! 102: #define fkind(x) (0x7) /* Kind of format */ ! 103: /* #define fkind(x) (minor(x)&0x7) Kind of format */ ! 104: #define fhbyh(x) (minor(x)&0x8) /* 0=Side by side, 1=Head by head */ ! 105: ! 106: static ! 107: struct fdata { ! 108: int fd_size; /* Blocks per diskette */ ! 109: int fd_nhds; /* Heads per drive */ ! 110: int fd_trks; /* Tracks per side */ ! 111: int fd_offs; /* Sector base */ ! 112: int fd_nspt; /* Sectors per track */ ! 113: char fd_GPL[4]; /* Controller gap param (indexed by rate) */ ! 114: char fd_N; /* Controller size param */ ! 115: char fd_FGPL; /* Format gap length */ ! 116: } fdata[] = { ! 117: /* 8 sectors per track, surface by surface seek. */ ! 118: { 320,1,40,0, 8, { 0x00,0x23,0x2A }, 2,0x50 }, /* Single sided */ ! 119: { 640,2,40,0, 8, { 0x00,0x23,0x2A }, 2,0x50 }, /* Double sided */ ! 120: { 1280,2,80,0, 8, { 0x00,0x23,0x2A }, 2,0x50 }, /* Quad density */ ! 121: /* 9 sectors per track, surface by surface seek. */ ! 122: { 360,1,40,0, 9, { 0x00,0x23,0x2A }, 2,0x50 }, /* Single sided */ ! 123: { 720,2,40,0, 9, { 0x00,0x23,0x2A }, 2,0x50 }, /* Double sided */ ! 124: { 1440,2,80,0, 9, { 0x00,0x23,0x2A }, 2,0x50 }, /* Quad density */ ! 125: /* 15 sectors per track, surface by surface seek. */ ! 126: { 2400,2,80,0,15, { 0x1B,0x00,0x00 }, 2,0x54 }, /* High capacity */ ! 127: /* 18 sectors per track, surface by surface seek. */ ! 128: { 2880,2,80,0,18, { 0x1B,0x00,0x00 }, 2,0x54 } /* 1.44 3.5" */ ! 129: }; ! 130: ! 131: ! 132: static ! 133: struct fl { ! 134: BUF *fl_actf; /* Queue, forward */ ! 135: BUF *fl_actl; /* Queue, backward */ ! 136: paddr_t fl_addr; /* Address */ ! 137: int fl_nsec; /* # of sectors */ ! 138: int fl_secn; /* Current sector */ ! 139: struct fdata fl_fd; /* Disk kind data */ ! 140: int fl_fcyl; /* Floppy cylinder # */ ! 141: char fl_incal[4]; /* Disk in cal flags */ ! 142: char fl_ndsk; /* # of 5 1/4" drives */ ! 143: char fl_unit; /* Unit # */ ! 144: char fl_mask; /* Handy unit mask */ ! 145: char fl_hbyh; /* 0/1 = Side by side/Head by head */ ! 146: char fl_nerr; /* Error count */ ! 147: int fl_ncmdstat; /* Number of cmd status bytes recvd */ ! 148: char fl_cmdstat[8]; /* Command Status buffer */ ! 149: int fl_nintstat; /* Number of intr status bytes recvd */ ! 150: char fl_intstat[4]; /* Interrupt Status buffer */ ! 151: int fl_fsec; /* Floppy sector # */ ! 152: int fl_head; /* Floppy head */ ! 153: char fl_init; /* FDC init done flag */ ! 154: char fl_state; /* Processing state */ ! 155: char fl_mstatus; /* Motor status */ ! 156: char fl_time[4]; /* Motor timeout */ ! 157: char fl_rate; /* Data rate: 500,300,250,?? kbps */ ! 158: char fl_type[4]; /* Type of drive: 2 = HiCap */ ! 159: int fl_wflag; /* Write operation */ ! 160: int fl_recov; /* Recovery initiated */ ! 161: } fl; ! 162: ! 163: static BUF flbuf; ! 164: static TIM fltim; ! 165: static TIM flrstlck; ! 166: ! 167: /* ! 168: * The load routine asks the ! 169: * switches how many drives are present ! 170: * in the machine, and sets up the field ! 171: * in the floppy database. It also grabs ! 172: * the level 6 interrupt vector. ! 173: */ ! 174: static ! 175: flload() ! 176: { ! 177: register int eflag; ! 178: register int s = 0; ! 179: ! 180: printf("loading fl\n"); ! 181: init_abios(); ! 182: ! 183: /* ! 184: * Read floppy equipment byte from CMOS ram ! 185: * drive 0 is in high nibble, drive 1 is in low nibble. ! 186: */ ! 187: outb( 0x70, 0x10 ); ! 188: /* delay */ ! 189: eflag = inb( 0x71 ); ! 190: ! 191: /* ! 192: * Flag hardware as an IBM AT if neither equipment byte nibble is ! 193: * greater than 4 (since 5 through 15 are reserved nibble values - see ! 194: * IBM AT Technical Reference manual, page 1-50). Note that this ! 195: * relies on the fact that in the XT, this byte will "float" high. ! 196: * NOTE: 1.44 Mbyte 3.5 inch drives are type 4 ! 197: */ ! 198: if ( (eflag & 0x88) == 0 ) { ! 199: ! 200: /* ! 201: * Reinitialize patchable parameters for IBM AT. ! 202: */ ! 203: fl_srt = 0xD; /* Floppy seek step rate, in unit 2 ms */ ! 204: /* NOT DIRECTLY ENCODED */ ! 205: fl_hlt = 25; /* Floppy head load time, in unit 4 ms */ ! 206: ! 207: /* ! 208: * Define AT drive information. ! 209: */ ! 210: fl.fl_type[0] = eflag >> 4; ! 211: fl.fl_type[1] = eflag & 15; ! 212: fl.fl_rate = 1; /* Must not be 2 */ ! 213: ! 214: /* ! 215: * Determine number of AT floppy drives. ! 216: */ ! 217: if ( eflag & 0xF0 ) { ! 218: fl.fl_ndsk++; ! 219: if ( eflag & 0x0F ) ! 220: fl.fl_ndsk++; ! 221: } ! 222: } else { ! 223: /* ! 224: * Define XT drive information. ! 225: */ ! 226: eflag = int11(); ! 227: fl.fl_rate = 2; ! 228: if ( eflag & 1 ) ! 229: fl.fl_ndsk = ((eflag >> 6) & 0x03) + 1; ! 230: } ! 231: ! 232: fl.fl_actf = NULL; /* Start up with this Null to avoid phony calls */ ! 233: ! 234: if ( fl.fl_ndsk ) { ! 235: ! 236: s = sphi(); ! 237: setivec(6, &flintr); ! 238: spl( s ); ! 239: ! 240: fl_rb.length = 0x51; ! 241: fl_rb.logical_id = 3; ! 242: fl_rb.unit = 0; ! 243: fl_rb.function = 3; ! 244: fl_rb.reserved = 0L; ! 245: fl_rb.ret_code = 0xffff; ! 246: d1_func(&fl_rb, START_P); ! 247: if (fl_rb.ret_code) ! 248: printf("\nfloppy function 3 returned = %d\n", ! 249: fl_rb.ret_code); ! 250: flreset(); ! 251: } ! 252: } ! 253: ! 254: /* ! 255: * Release resources. ! 256: */ ! 257: flunload() ! 258: { ! 259: printf("doing an flunload\n"); ! 260: /* ! 261: * Clear interrupt vector. ! 262: */ ! 263: if ( fl.fl_ndsk ) ! 264: clrivec(6); ! 265: ! 266: /* ! 267: * Cancel timed function. ! 268: */ ! 269: timeout( &fltim, 0, NULL, NULL ); ! 270: ! 271: /* ! 272: * Cancel periodic [1 second] invocation. ! 273: */ ! 274: drvl[FL_MAJOR].d_time = 0; ! 275: ! 276: /* ! 277: * Turn motors off. ! 278: */ ! 279: /* outb(FDCDOR, DORNMR | DORIEN );*/ ! 280: } ! 281: ! 282: ! 283: /** ! 284: * void ! 285: * flreset() -- reset floppy disk controller. ! 286: */ ! 287: static void ! 288: flreset() ! 289: { ! 290: register int s; ! 291: ! 292: fl.fl_state = SRESET; ! 293: fl_rb.length = 0x51; ! 294: fl_rb.logical_id = 3; ! 295: fl_rb.unit = 0; ! 296: fl_rb.function = 5; ! 297: fl_rb.reserved = 0L; ! 298: fl_rb.ret_code = 0xffff; ! 299: fl_rb.vars.f5.reserved = 0; ! 300: floppy_function(START_P); ! 301: ! 302: /* printf("before reset\n"); */ ! 303: {int i; for (i=0;i<1000; i++);} ! 304: s = sphi(); ! 305: while ((fl_rb.ret_code == 1) || (fl_rb.ret_code == 2)) ! 306: sleep(&flrstlck, CVWAIT, IVWAIT, SVWAIT); ! 307: spl( s ); ! 308: {int i; for (i=0;i<1000; i++);} ! 309: /* printf("after reset\n"); */ ! 310: ! 311: fl.fl_state = SIDLE; ! 312: if (fl_rb.ret_code != 0) ! 313: printf("FL: reset failed - %u\n", fl_rb.ret_code); ! 314: return; ! 315: } ! 316: ! 317: ! 318: /* ! 319: * The open routine screens out ! 320: * opens of illegal minor devices and ! 321: * performs the NEC specify command if ! 322: * this is the very first floppy disk ! 323: * open call. ! 324: */ ! 325: ! 326: static ! 327: flopen( dev, mode ) ! 328: dev_t dev; ! 329: int mode; ! 330: ! 331: { ! 332: /* ! 333: * Validate existence and data rate [Gap length != 0]. ! 334: */ ! 335: if ( funit(dev) >= fl.fl_ndsk ) ! 336: { ! 337: u.u_error = ENXIO; ! 338: return; ! 339: } ! 340: } ! 341: ! 342: /* ! 343: * The read routine just calls ! 344: * off to the common raw I/O processing ! 345: * code, using a static buffer header in ! 346: * the driver. ! 347: */ ! 348: ! 349: static ! 350: flread( dev, iop ) ! 351: dev_t dev; ! 352: IO *iop; ! 353: { ! 354: ioreq(&flbuf, iop, dev, BREAD); ! 355: } ! 356: ! 357: /* ! 358: * The write routine is just like the ! 359: * read routine, except that the function code ! 360: * is write instead of read. ! 361: */ ! 362: ! 363: static ! 364: flwrite( dev, iop ) ! 365: ! 366: dev_t dev; ! 367: IO *iop; ! 368: ! 369: { ! 370: ioreq(&flbuf, iop, dev, BWRITE); ! 371: } ! 372: ! 373: /* ! 374: * The ioctl routine simply queues a format request ! 375: * using flbuf. ! 376: * The only valid command is to format a track. ! 377: * The parameter block contains the header records supplied to the controller. ! 378: */ ! 379: ! 380: static ! 381: flioctl( dev, com, par ) ! 382: ! 383: dev_t dev; ! 384: int com; ! 385: char *par; ! 386: ! 387: { ! 388: register unsigned s; ! 389: register struct fdata *fdp; ! 390: unsigned hd, cyl; ! 391: ! 392: /* {int i; for (i=0;i<1000; i++);} */ ! 393: /* printf("fl in fioctl\n"); */ ! 394: if (com != FDFORMAT) { ! 395: u.u_error = EINVAL; ! 396: return; ! 397: } ! 398: ! 399: printf("No format allowed yet.\n"); ! 400: /* These is an ABIOS command to format. For now, just error out */ ! 401: u.u_error = EINVAL; ! 402: return; ! 403: ! 404: fdp = &fdata[ fkind(dev) ]; ! 405: cyl = getubd(par); ! 406: hd = getubd(par+1); ! 407: ! 408: if (hd > 1 || cyl >= fdp->fd_trks) { ! 409: u.u_error = EINVAL; ! 410: return; ! 411: } ! 412: ! 413: /* ! 414: * The following may need some explanation. ! 415: * dmareq will: ! 416: * claim the buffer, ! 417: * bounds check the parameter buffer, ! 418: * lock the parameter buffer in memory, ! 419: * convert io_seek to b_bno, ! 420: * dispatch the request, ! 421: * wait for completion, ! 422: * and unlock the parameter buffer. ! 423: * The b_bno is reconverted to hd, cyl in flfsm. ! 424: */ ! 425: ! 426: s = fhbyh(dev) ? (cyl * fdp->fd_nhds + hd) : (hd * fdp->fd_trks + cyl); ! 427: s *= fdp->fd_nspt; ! 428: u.u_io.io_seek = ((long)s) * BSIZE; ! 429: #ifdef _I386 ! 430: u.u_io.io.vbase = par; ! 431: #else ! 432: u.u_io.io_base = par; ! 433: #endif ! 434: u.u_io.io_ioc = fdp->fd_nspt * 4; ! 435: dmareq(&flbuf, &u.u_io, dev, FDFORMAT); ! 436: } ! 437: ! 438: /* ! 439: * Start up block I/O on a ! 440: * buffer. Check that the block number ! 441: * is not out of range, given the style of ! 442: * the disk. Put the buffer header into the ! 443: * device queue. Start up the disk if the ! 444: * device is idle. ! 445: */ ! 446: ! 447: static ! 448: flblock( bp ) ! 449: ! 450: register BUF *bp; ! 451: { ! 452: register unsigned bno; ! 453: ! 454: intimeout = 0; ! 455: ! 456: bno = bp->b_bno + (bp->b_count >> 9) - 1; ! 457: if ((unsigned)bp->b_bno > fdata[ fkind(bp->b_dev) ].fd_size) { ! 458: bp->b_flag |= BFERR; ! 459: bdone(bp); ! 460: return; ! 461: } ! 462: ! 463: if (bp->b_req != FDFORMAT && bno>=fdata[ fkind(bp->b_dev) ].fd_size) { ! 464: bp->b_resid = bp->b_count; ! 465: if (bp->b_flag & BFRAW) ! 466: bp->b_flag |= BFERR; ! 467: bdone(bp); /* return w/ b_resid != 0 */ ! 468: return; ! 469: } ! 470: ! 471: if ((bp->b_count&0x1FF) != 0) { ! 472: if (bp->b_req != FDFORMAT) { ! 473: bp->b_flag |= BFERR; ! 474: bdone(bp); ! 475: return; ! 476: } ! 477: } ! 478: ! 479: /* bp->b_actf = NULL; */ ! 480: ! 481: if (fl.fl_actf == NULL) ! 482: fl.fl_actf = bp; ! 483: else ! 484: fl.fl_actl->b_actf = bp; ! 485: ! 486: fl.fl_actl = bp; ! 487: ! 488: ! 489: if (fl.fl_state == SRESET) ! 490: printf("fl.fl_state (%d) != SIDLE (%d)\n", fl.fl_state,SIDLE); ! 491: ! 492: if (fl.fl_state == SIDLE) ! 493: { ! 494: drvl[FL_MAJOR].d_time = 0; ! 495: if (fldequeue()) ! 496: flstart(); ! 497: } ! 498: ! 499: } ! 500: ! 501: /** ! 502: * ! 503: * int ! 504: * fldequeue() - obtain next disk read/write operation ! 505: * ! 506: * Action: Pull some work from the disk queue. ! 507: * ! 508: * Return: 0 = no work. ! 509: * * = work to do. ! 510: */ ! 511: static int ! 512: fldequeue() ! 513: { ! 514: register BUF * bp = fl.fl_actf; ! 515: register struct fdata *dp; ! 516: ! 517: if (bp == NULL) ! 518: return (0); ! 519: ! 520: dp = &fdata[fkind(bp->b_dev)]; ! 521: fl.fl_secn = (bp->b_bno % dp->fd_nspt) + 1; ! 522: fl.fl_head = bp->b_bno / dp->fd_nspt; ! 523: fl.fl_fcyl = fl.fl_head / dp->fd_nhds; ! 524: fl.fl_head = fl.fl_head % dp->fd_nhds; ! 525: ! 526: fl.fl_nsec = bp->b_count / BSIZE; ! 527: ! 528: if (bp->b_faddr == 0L) ! 529: { ! 530: printf("FL: called with a null address for b_faddr, bno=%d\n" ! 531: ,bp->b_bno); ! 532: fl.fl_actf = bp->b_actf; ! 533: return 0; ! 534: } ! 535: else ! 536: fl.fl_addr = vtop(bp->b_faddr); ! 537: ! 538: return (1); ! 539: } ! 540: ! 541: ! 542: /** ! 543: * ! 544: * void ! 545: * flstart() - start or restart next disk read/write operation. ! 546: * ! 547: * Action: Initiate disk read/write operation. ! 548: **/ ! 549: static void ! 550: flstart() ! 551: { ! 552: fl_rb.length = 0x51; ! 553: fl_rb.logical_id = 3; ! 554: fl_rb.unit = 0; ! 555: fl_rb.reserved = 0L; ! 556: fl_rb.ret_code = 0xffff; ! 557: ! 558: /* Note that the items below are set up the same way for a ! 559: * read or a write. */ ! 560: fl_rb.vars.f8.reserved = 0; ! 561: fl_rb.vars.f8.reserved1 = 0L; ! 562: fl_rb.vars.f8.dptr = fl.fl_addr; ! 563: fl_rb.vars.f8.reserved2 = 0; ! 564: fl_rb.vars.f8.cylinder = fl.fl_fcyl; ! 565: fl_rb.vars.f8.head = fl.fl_head; ! 566: fl_rb.vars.f8.sector = fl.fl_secn; ! 567: fl_rb.vars.f8.sectors_read = fl.fl_nsec; ! 568: ! 569: if (fl.fl_actf->b_req == BWRITE) { ! 570: fl_rb.function = 9; ! 571: fl.fl_state = SWRITE; ! 572: } ! 573: else { ! 574: fl_rb.function = 8; ! 575: fl.fl_state = SREAD; ! 576: } ! 577: floppy_function(START_P); ! 578: } ! 579: ! 580: /** ! 581: * ! 582: * void ! 583: * flintr() - Interrupt routine. ! 584: * ! 585: */ ! 586: static void ! 587: flintr() ! 588: { ! 589: d1_func(&fl_rb, INTERRUPT_P); ! 590: /* printf("return val (int) = %x\n", fl_rb.ret_code); */ ! 591: defer(floppy_functionb, INTERRUPT_P); ! 592: } ! 593: ! 594: /** ! 595: * ! 596: * int ! 597: * flerror() ! 598: * ! 599: * Action: Check for drive error. ! 600: * If found, increment error count and report it. ! 601: * ! 602: * Return: 0 = No error found. ! 603: * 1 = Error occurred. ! 604: */ ! 605: static int ! 606: flerror() ! 607: { ! 608: register BUF * bp = fl.fl_actf; ! 609: ! 610: if (fl_rb.ret_code <= 2) ! 611: return 0; /* For now, do nothing */ ! 612: else ! 613: { ! 614: #if 0 ! 615: printf("fl%d%c: bno=%U head=%u cyl=%u error=%x", ! 616: fl.fl_drv, ! 617: (bp->b_dev & SDEV) ? 'x' : fl.fl_partn % NPARTN + 'a', ! 618: (bp->b_count/BSIZE) + bp->b_bno ! 619: + fl.fl_caching - fl.fl_nsec, ! 620: fl.fl_head, fl.fl_fcyl, fl_rb.ret_code); ! 621: #endif ! 622: return fl_rb.ret_code; ! 623: } ! 624: } ! 625: ! 626: /** ! 627: * ! 628: * void ! 629: * flrecov() ! 630: * ! 631: * Action: Attempt recovery. ! 632: */ ! 633: static void ! 634: flrecov() ! 635: { ! 636: register BUF *bp = fl.fl_actf; ! 637: ! 638: switch (fl_rb.ret_code) { ! 639: ! 640: case 0x8006: /* Media changed - retry */ ! 641: switch(fl.fl_state) ! 642: { ! 643: case SREAD: ! 644: case SWRITE: ! 645: flreset(); ! 646: fldequeue(); ! 647: flstart(); ! 648: break; ! 649: default: ! 650: break; ! 651: } ! 652: break; ! 653: default: /* Anything else - Give up on block */ ! 654: printf("FL: error %x in %s.\n", fl_rb.ret_code, ! 655: smsg[fl.fl_state]); ! 656: ! 657: bp->b_flag |= BFERR; ! 658: fldone(); ! 659: } ! 660: } ! 661: ! 662: /** ! 663: * ! 664: * void ! 665: * fldone() ! 666: * ! 667: * Action: Release current i/o buffer to the O/S. ! 668: */ ! 669: static void ! 670: fldone() ! 671: { ! 672: register BUF * bp = fl.fl_actf; ! 673: ! 674: drvl[FL_MAJOR].d_time = 0; ! 675: fl.fl_state = SIDLE; ! 676: bdone(bp); ! 677: ! 678: if (bp != NULL) ! 679: fl.fl_actf = bp->b_actf; ! 680: else ! 681: fl.fl_actf = NULL; ! 682: ! 683: if (fldequeue()) ! 684: flstart(); ! 685: else if (intimeout == 0) { ! 686: intimeout = 1; /* Set up to turn off the drive */ ! 687: drvl[FL_MAJOR].d_time = 5; ! 688: } ! 689: } ! 690: ! 691: ! 692: ! 693: void floppy_function(type) ! 694: int type; ! 695: { ! 696: d1_func(&fl_rb, type); ! 697: /* printf("FL: return val = %x\n", fl_rb.ret_code); */ ! 698: {int i; for (i=0;i<1000; i++);} ! 699: floppy_functionb(); ! 700: } ! 701: ! 702: void floppy_functionb() ! 703: { ! 704: static int test=0; ! 705: while (fl_rb.ret_code == 2) /* Wait for time */ ! 706: { ! 707: test++; ! 708: if (test > 1) printf("@"); ! 709: { ! 710: long i; ! 711: for(i=0L; i < fl_rb.vars.f8.wait_time; i+=16) ! 712: ; ! 713: } ! 714: /* ! 715: timeout(&fltim, 1, wakeup, (int)&fltim); ! 716: sleep((char *)&fltim, CVTTOUT, IVTTOUT, SVTTOUT); ! 717: */ ! 718: ! 719: d1_func(&fl_rb, INTERRUPT_P); ! 720: } ! 721: test=0; ! 722: if (fl_rb.ret_code == 0) /* Finished */ ! 723: { ! 724: if (fl.fl_state != SRESET) ! 725: { ! 726: fl.fl_actf->b_resid = 0; ! 727: fldone(); ! 728: } ! 729: else ! 730: wakeup(&flrstlck); ! 731: } ! 732: else if (fl_rb.ret_code == 1) /* Wait for int */ ! 733: { ! 734: /*fl.fl_state = SINT; */ ! 735: /*printf("Floppy driver is waiting for an interrupt\n"); */ ! 736: } ! 737: else ! 738: { ! 739: printf("bp->b_bno=%ld, fl.fl_secn=%d, fl.fl_fcyl=%d, fl.fl_h" ! 740: "ead=%d, fl.fl_nsec=%d\n", fl.fl_actf->b_bno, ! 741: fl.fl_secn, fl.fl_fcyl, fl.fl_head, fl.fl_nsec); ! 742: flrecov(); ! 743: } ! 744: } ! 745: ! 746: /** ! 747: * ! 748: * void ! 749: * fltimer() - wait for timeout ! 750: * ! 751: * Action: If drvl[FL_MAJOR] is greater than zero, decrement it. ! 752: * If it decrements to zero, call the abios again ! 753: * or turn off the disktimer it timeout = 1; ! 754: */ ! 755: static void ! 756: fltimer() ! 757: { ! 758: register int s; ! 759: ! 760: s = sphi(); ! 761: if (--drvl[FL_MAJOR].d_time > 0) { ! 762: spl(s); ! 763: return; ! 764: } ! 765: if (intimeout) { ! 766: intimeout = 2; ! 767: defer(fl_drive_off,0); ! 768: } ! 769: else ! 770: floppy_function(INTERRUPT_P); ! 771: spl(s); ! 772: } ! 773: ! 774: ! 775: static void ! 776: fl_drive_off() ! 777: { ! 778: fl_rb.logical_id = 3; ! 779: fl_rb.unit = 0; ! 780: fl_rb.function = 0xf; ! 781: fl_rb.reserved = 0L; ! 782: fl_rb.ret_code = 0xffff; ! 783: fl_rb.vars.ff.reserved = 0; ! 784: d1_func(&fl_rb, START_P); ! 785: if (fl_rb.ret_code) ! 786: printf("\nfloppy function 0xf returned = %d\n", ! 787: fl_rb.ret_code); ! 788: intimeout = 0; /* Drive is now turned off */ ! 789: ! 790: return; ! 791: } ! 792:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.