Annotation of coherent/b/kernel/io.386/fdc.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * io.386/fdc.c
                      3:  *
                      4:  * Support 765-style controller for diskette and floppy tape
                      5:  *
                      6:  * Revised: Wed Jun  9 12:15:08 1993 CDT
                      7:  */
                      8: 
                      9: /*
                     10:  * ----------------------------------------------------------------------
                     11:  * Includes.
                     12:  */
                     13: #include       <sys/coherent.h>
                     14: 
                     15: #include       <errno.h>
                     16: #include       <sys/buf.h>
                     17: #include       <sys/con.h>
                     18: #include       <sys/devices.h>
                     19: #include       <sys/dmac.h>
                     20: #include       <sys/fdc765.h>
                     21: #include       <sys/stat.h>
                     22: 
                     23: /*
                     24:  * ----------------------------------------------------------------------
                     25:  * Definitions.
                     26:  *     Constants.
                     27:  *     Macros with argument lists.
                     28:  *     Typedefs.
                     29:  *     Enums.
                     30:  */
                     31: 
                     32: /* Number of ticks to busy-wait the kernel before timeout awaiting RQM. */
                     33: #define FDC_RQM_WAIT   2
                     34: 
                     35: enum {
                     36:        FL_TIMING = 1,
                     37:        FT_TIMING = 2
                     38: };
                     39: 
                     40: enum {
                     41:        FL_INTR = 1,
                     42:        FT_INTR = 2
                     43: };
                     44: 
                     45: /*
                     46:  * ----------------------------------------------------------------------
                     47:  * Functions.
                     48:  *     Import Functions.
                     49:  *     Export Functions.
                     50:  *     Local Functions.
                     51:  */
                     52: extern int     nulldev();
                     53: extern unsigned int inb();
                     54: 
                     55: void   fdcCmdStatus();
                     56: void   fdcDrvSelect();
                     57: void   fdcDrvStatus();
                     58: int    fdcGet();
                     59: void   fdcIntStatus();
                     60: int    fdcPut();
                     61: void   fdcRecal();
                     62: void   fdcReset();
                     63: void   fdcResetSel();
                     64: void   fdcSense();
                     65: void   fdcSpecify();
                     66: void   fdcStatus();
                     67: 
                     68: int    setFlIntr();
                     69: void   setFlTimer();
                     70: int    setFtIntr();
                     71: void   setFtTimer();
                     72: 
                     73: static int     fdcload();
                     74: static int     fdcunload();
                     75: static int     fdcopen();
                     76: static int     fdcclose();
                     77: static int     fdcblock();
                     78: static int     fdcread();
                     79: static int     fdcwrite();
                     80: static int     fdcioctl();
                     81: static int     fdctimeout();
                     82: 
                     83: static void    fdcIntr();
                     84: static void    fdcRate();
                     85: static int     fdcWaitRQM();
                     86: 
                     87: static int     setFdcIntr();
                     88: static void    setFdcTiming();
                     89: 
                     90: /*
                     91:  * ----------------------------------------------------------------------
                     92:  * Global Data.
                     93:  *     Import Variables.
                     94:  *     Export Variables.
                     95:  *     Local Variables.
                     96:  */
                     97: 
                     98: CON    fdccon  = {
                     99:        DFBLK | DFCHR,                  /* Flags */
                    100:        FL_MAJOR,                       /* Major index */
                    101:        fdcopen,                        /* Open */
                    102:        fdcclose,                       /* Close */
                    103:        fdcblock,                       /* Block */
                    104:        fdcread,                        /* Read */
                    105:        fdcwrite,                       /* Write */
                    106:        fdcioctl,                       /* Ioctl */
                    107:        nulldev,                        /* Powerfail */
                    108:        fdctimeout,                     /* Timeout */
                    109:        fdcload,                        /* Load */
                    110:        fdcunload                       /* Unload */
                    111: };
                    112: 
                    113: /*
                    114:  * Two patchable pointers, for enabling diskette and/or tape device control.
                    115:  */
                    116: CON * flCon = NULL;
                    117: CON * ftCon = NULL;
                    118: 
                    119: /* Global struct "fdc" passes FDC status to diskette and tape drivers. */
                    120: struct FDC fdc;
                    121: 
                    122: void   (*flIntr)();
                    123: void   (*ftIntr)();
                    124: 
                    125: static int     fdcIntOwner;
                    126: static int     fdcTiming;
                    127: 
                    128: /*
                    129:  * ----------------------------------------------------------------------
                    130:  * Code.
                    131:  */
                    132: 
                    133: /***************************************************************************/
                    134: /*
                    135:  * First part of fdc module.
                    136:  *
                    137:  * Kernel interface.
                    138:  */
                    139: 
                    140: /*
                    141:  * The load routine asks the
                    142:  * switches how many drives are present
                    143:  * in the machine, and sets up the field
                    144:  * in the floppy database. It also grabs
                    145:  * the level 6 interrupt vector.
                    146:  */
                    147: static int
                    148: fdcload()
                    149: {
                    150:        register int    s;
                    151: 
                    152:        if (flCon == NULL && ftCon == NULL) {
                    153:                printf("fdc has no target devices\n");
                    154:                return;
                    155:        }
                    156: 
                    157:        /*
                    158:         * Ensure DMA channel 2 is turned off.
                    159:         * The Computerland ROM does not disable DMA channel after autoboot
                    160:         * from hard disk.  The Western Digital controller board appears to
                    161:         * send a dma burst when the floppy controller chip is reset.
                    162:         */
                    163:        dmaoff(DMA_CH2);
                    164: 
                    165:        if (flCon)
                    166:                (*flCon->c_load)();
                    167:        if (ftCon)
                    168:                (*ftCon->c_load)();
                    169: 
                    170:        /*
                    171:         * Initialize the floppy disk controller (if we
                    172:         * have any floppy drives).
                    173:         */
                    174:        s = sphi();
                    175: 
                    176:        setivec(6, fdcIntr);
                    177:        fdcReset();
                    178: 
                    179:        spl(s);
                    180: }
                    181: 
                    182: /*
                    183:  * Release resources.
                    184:  */
                    185: static int
                    186: fdcunload()
                    187: {
                    188:        if (flCon == NULL && ftCon == NULL)
                    189:                return;
                    190:        
                    191:        if (flCon)
                    192:                (*flCon->c_uload)();
                    193:        if (ftCon)
                    194:                (*ftCon->c_uload)();
                    195: 
                    196:        /*
                    197:         * Cancel periodic (1 second) invocation.
                    198:         */
                    199:        drvl[FL_MAJOR].d_time = 0;
                    200:        fdcTiming = 0;
                    201: 
                    202:        /*
                    203:         * Turn motors off.
                    204:         */
                    205:        outb(FDCDOR, DORNMR);           /* Leave interrupts disabled. */
                    206: 
                    207:        /*
                    208:         * Clear interrupt vector.
                    209:         */
                    210:        clrivec(6);
                    211: }
                    212: 
                    213: static int
                    214: fdcopen(dev, mode)
                    215: dev_t  dev;
                    216: int    mode;
                    217: {
                    218:        if (FDC_DISKETTE(dev)) {
                    219:                if (flCon)
                    220:                        (*flCon->c_open)(dev, mode);
                    221:                else {
                    222:                        SET_U_ERROR(ENXIO, "fdcopen()-no floppy");
                    223:                        return;
                    224:                }
                    225:        } else if (FDC_TAPE(dev)) {
                    226:                if (ftCon)
                    227:                        (*ftCon->c_open)(dev, mode);
                    228:                else {
                    229:                        SET_U_ERROR(ENXIO, "fdcopen()-no tape");
                    230:                        return;
                    231:                }
                    232:        } else {
                    233:                SET_U_ERROR(ENXIO, "fdcopen()-no device");
                    234:                return;
                    235:        }
                    236: }
                    237: 
                    238: static int
                    239: fdcclose(dev, mode)
                    240: dev_t  dev;
                    241: int    mode;
                    242: {
                    243:        if (FDC_DISKETTE(dev)) {
                    244:                if (flCon)
                    245:                        (*flCon->c_close)(dev, mode);
                    246:                else {
                    247:                        SET_U_ERROR(ENXIO, "fdcclose()-no floppy");
                    248:                        return;
                    249:                }
                    250:        } else if (FDC_TAPE(dev)) {
                    251:                if (ftCon)
                    252:                        (*ftCon->c_close)(dev, mode);
                    253:                else {
                    254:                        SET_U_ERROR(ENXIO, "fdcclose()-no tape");
                    255:                        return;
                    256:                }
                    257:        } else {
                    258:                SET_U_ERROR(ENXIO, "fdcclose()-no device");
                    259:                return;
                    260:        }
                    261: }
                    262: 
                    263: static int
                    264: fdcread(dev, iop)
                    265: dev_t  dev;
                    266: IO     *iop;
                    267: {
                    268:        if (FDC_DISKETTE(dev)) {
                    269:                if (flCon)
                    270:                        (*flCon->c_read)(dev, iop);
                    271:                else {
                    272:                        SET_U_ERROR(ENXIO, "fdcread()-no floppy");
                    273:                        return;
                    274:                }
                    275:        } else if (FDC_TAPE(dev)) {
                    276:                if (ftCon)
                    277:                        (*ftCon->c_read)(dev, iop);
                    278:                else {
                    279:                        SET_U_ERROR(ENXIO, "fdcread()-no tape");
                    280:                        return;
                    281:                }
                    282:        } else {
                    283:                SET_U_ERROR(ENXIO, "fdcread()-no device");
                    284:                return;
                    285:        }
                    286: }
                    287: 
                    288: static int
                    289: fdcwrite(dev, iop)
                    290: dev_t  dev;
                    291: IO     *iop;
                    292: {
                    293:        if (FDC_DISKETTE(dev)) {
                    294:                if (flCon)
                    295:                        (*flCon->c_write)(dev, iop);
                    296:                else {
                    297:                        SET_U_ERROR(ENXIO, "fdcwrite()-no floppy");
                    298:                        return;
                    299:                }
                    300:        } else if (FDC_TAPE(dev)) {
                    301:                if (ftCon)
                    302:                        (*ftCon->c_write)(dev, iop);
                    303:                else {
                    304:                        SET_U_ERROR(ENXIO, "fdcwrite()-no tape");
                    305:                        return;
                    306:                }
                    307:        } else {
                    308:                SET_U_ERROR(ENXIO, "fdcwrite()-no device");
                    309:                return;
                    310:        }
                    311: }
                    312: 
                    313: static int
                    314: fdcioctl(dev, com, par)
                    315: dev_t  dev;
                    316: int    com;
                    317: char   *par;
                    318: {
                    319:        if (FDC_DISKETTE(dev)) {
                    320:                if (flCon)
                    321:                        (*flCon->c_ioctl)(dev, com, par);
                    322:                else {
                    323:                        SET_U_ERROR(ENXIO, "fdcioctl()-no floppy");
                    324:                        return;
                    325:                }
                    326:        } else if (FDC_TAPE(dev)) {
                    327:                if (ftCon)
                    328:                        (*ftCon->c_ioctl)(dev, com, par);
                    329:                else {
                    330:                        SET_U_ERROR(ENXIO, "fdcioctl()-no tape");
                    331:                        return;
                    332:                }
                    333:        } else {
                    334:                SET_U_ERROR(ENXIO, "fdcioctl()-no device");
                    335:                return;
                    336:        }
                    337: }
                    338: 
                    339: /* Can't set u.u_error inside block routine. */
                    340: static int
                    341: fdcblock(bp)
                    342: BUF    *bp;
                    343: {
                    344:        if (FDC_DISKETTE(bp->b_dev)) {
                    345:                if (flCon)
                    346:                        (*flCon->c_block)(bp);
                    347:        } else if (FDC_TAPE(bp->b_dev))
                    348:                if (ftCon)
                    349:                        (*ftCon->c_block)(bp);
                    350: }
                    351: 
                    352: /***************************************************************************/
                    353: /*
                    354:  * Second part of fdc module.
                    355:  *
                    356:  * Hardware interface.
                    357:  */
                    358: 
                    359: /*
                    360:  * Get status (if any) from last command
                    361:  */
                    362: void
                    363: fdcCmdStatus()
                    364: {
                    365:        register int    b;
                    366:        register int    n = 0;          /* # of status bytes read */
                    367:        register int    i = 0;          /* Timeout count */
                    368:        register int    s;
                    369: 
                    370:        s = sphi();
                    371: 
                    372:        /*
                    373:         * Read all the status bytes the controller will give us.
                    374:         */
                    375: 
                    376:        for (;;) {
                    377:                b = fdcGet();
                    378:                if (b == -1)
                    379:                        break;
                    380: 
                    381:                if (n < FDC_NUM_CMD_STAT)
                    382:                        fdc.fdc_cmdstat[n++] = b;
                    383:        }
                    384: 
                    385:        fdc.fdc_ncmdstat = n;
                    386:        spl(s);
                    387: }
                    388: 
                    389: /*
                    390:  * fdcDrvSelect()
                    391:  *
                    392:  * Select the drive indicated by "drive" (0..3).
                    393:  * If "motorOn" is nonzero, turn the motor on as well.
                    394:  */
                    395: void
                    396: fdcDrvSelect(drive, motorOn)
                    397: int drive, motorOn;
                    398: {
                    399:        unsigned char motorBits = 0;
                    400: 
                    401:        if (drive >= 4) {
                    402:                printf("Can't fdcDrvSelect(%d,%d) ", drive, motorOn);
                    403:                return;
                    404:        }
                    405: 
                    406:        /* If needed, generate motor on bit for current selected drive. */
                    407:        if (motorOn)
                    408:                motorBits = 0x10 << drive;
                    409: 
                    410:        outb(FDCDOR, DORNMR | DORIEN | drive | motorBits);
                    411:        fdcSense();                             /* Just in case --- */
                    412: }
                    413: 
                    414: /*
                    415:  * Send Sense Drive Status command to FDC.
                    416:  */
                    417: void
                    418: fdcDrvStatus(drive, head)
                    419: int drive, head;
                    420: {
                    421:        fdcPut(CMDSDRV);
                    422:        fdcPut(drive | (head << 2));
                    423: }
                    424: 
                    425: /*
                    426:  * Read NEC data register, doing needed handshake.
                    427:  * Return -1 in case of timeout before RQM or no data available.
                    428:  */
                    429: int
                    430: fdcGet()
                    431: {
                    432:        int ret = -1;
                    433: 
                    434:        /* Wait for RQM, then expect DIO true. */
                    435:        if (busyWait(fdcWaitRQM, FDC_RQM_WAIT) && (inb(FDCMSR) & MSRDIO))
                    436:                ret = inb(FDCDAT);
                    437: 
                    438:        return ret;
                    439: }
                    440: 
                    441: /*
                    442:  * Get Interrupt status
                    443:  */
                    444: void
                    445: fdcIntStatus()
                    446: {
                    447:        register int    b;
                    448:        register int    n = 0;          /* # of status bytes read */
                    449:        register int    i = 0;          /* Timeout count */
                    450:        register int    s;
                    451: 
                    452:        s = sphi();
                    453: 
                    454:        /*
                    455:         * Issue a sense interrupt command and stash result.
                    456:         */
                    457:        fdcPut(CMDSINT);
                    458: 
                    459:        n = 0;
                    460:        for (;;) {
                    461:                b = fdcGet();
                    462:                if (b == -1)
                    463:                        break;
                    464: 
                    465:                if (n < FDC_NUM_INT_STAT)
                    466:                        fdc.fdc_intstat[n++] = b;
                    467:        }
                    468:        fdc.fdc_nintstat = n;
                    469:        spl(s);
                    470: }
                    471: 
                    472: /*
                    473:  * Since the FDC is run in DMA mode, possible interrupt causes are:
                    474:  *
                    475:  * 1 Result phase of: Read Data, Read Track, Read ID, Read Deleted Data,
                    476:  *   Write Data, Format Cylinder, Write Deleted Data, Scan.
                    477:  *
                    478:  * 2 Ready line of diskette drive changes state.
                    479:  *
                    480:  * 3 End of Seek or Recalibrate.
                    481:  *
                    482:  * In case 1, the interrupt is cleared by read/write data to FDC.
                    483:  * In cases 2 and 3, a Sense Interrupt is needed to clear the interrupt
                    484:  * and determine its cause.
                    485:  *
                    486:  * The following comment is obsolete, but possibly of interest:
                    487:  ***********************************************
                    488:  * The interrupt routine gets all
                    489:  * the status bytes the controller chip
                    490:  * will give it, then issues a sense interrupt
                    491:  * status command (which is necessary for a seek
                    492:  * to complete!) and throws all of the status
                    493:  * bytes away.
                    494:  ***********************************************
                    495:  */
                    496: static void
                    497: fdcIntr()
                    498: {
                    499:        register int s;
                    500: 
                    501:        s = sphi();
                    502: 
                    503:        /* Invalidate previously stored interrupt and command status. */
                    504:        fdc.fdc_nintstat = 0;
                    505:        fdc.fdc_ncmdstat = 0;
                    506: 
                    507:        /* Vector to diskette or tape device interrupt handler. */
                    508:        if ((fdcIntOwner & FL_INTR) && flIntr)
                    509:                (*flIntr)();
                    510: 
                    511:        if ((fdcIntOwner & FT_INTR) && ftIntr)
                    512:                (*ftIntr)();
                    513:        spl(s);
                    514: }
                    515: 
                    516: /*
                    517:  * Send a command byte to the NEC chip, first waiting until the chip
                    518:  * says that it is ready.
                    519:  * Return 0 if able to send, or -1 if timed out or FDC had wrong I/O
                    520:  * direction.
                    521:  */
                    522: int
                    523: fdcPut(cmd)
                    524: int cmd;
                    525: {
                    526:        int ret = -1;
                    527: 
                    528:        /* Wait for RQM, then expect DIO false. */
                    529:        if (busyWait(fdcWaitRQM, FDC_RQM_WAIT)) {
                    530:                if ((inb(FDCMSR) & MSRDIO) == 0) {
                    531:                        outb(FDCDAT, cmd);
                    532:                        ret = 0;
                    533:                }
                    534:        }
                    535: 
                    536:        return ret;
                    537: }
                    538: 
                    539: /*
                    540:  * Set transfer rate (FDC_RATE_250K/300K/500K/1MEG)
                    541:  */
                    542: void
                    543: fdcRate(rate)
                    544: int rate;
                    545: {
                    546:        outb(FDCRATE, rate);
                    547: }
                    548: 
                    549: /*
                    550:  * Given drive # (0..3), send a Recalibrate command to the FDC.
                    551:  *
                    552:  * Sense interrupt - fdcIntStatus() - *must* be done when the
                    553:  * ensuing IRQ happens.
                    554:  */
                    555: void
                    556: fdcRecal(drive)
                    557: int drive;
                    558: {
                    559:        fdcPut(CMDRCAL);
                    560:        fdcPut(drive);
                    561: }
                    562: 
                    563: /*
                    564:  * Given drive # (0..3), head (0..1), and cylinder (0..255),
                    565:  * send a seek command to the FDC.
                    566:  *
                    567:  * Sense interrupt - fdcIntStatus() - *must* be done when the
                    568:  * ensuing IRQ happens.
                    569:  */
                    570: void
                    571: fdcSeek(drive, head, cyl)
                    572: int drive, head, cyl;
                    573: {
                    574:        fdcPut(CMDSEEK);
                    575:        fdcPut(drive | (head << 2));
                    576:        fdcPut(cyl);
                    577: }
                    578: 
                    579: /*
                    580:  * fdcSense() issues Sense Drive Status and Sense Interrupt Status,
                    581:  * saving information from the FDC into global struct "fdc".
                    582:  *
                    583:  * It is called in response to FDC interrupts.
                    584:  */
                    585: void
                    586: fdcSense()
                    587: {
                    588:        fdcCmdStatus();                 /* Get command status. */
                    589:        fdcIntStatus();                 /* Get int status, just in case. */
                    590: }
                    591: 
                    592: /*
                    593:  * Send Specify command and data bytes to FDC.
                    594:  * Always specify DMA mode (ND bit = 0).
                    595:  */
                    596: void
                    597: fdcSpecify(srt, hut, hlt)
                    598: int srt, hut, hlt;
                    599: {
                    600:        fdcPut(CMDSPEC);
                    601:        fdcPut((srt << 4) | hut);
                    602:        fdcPut(hlt << 1);
                    603: }
                    604: 
                    605: /*
                    606:  * Dissassemble the floppy error status for user reference.
                    607:  */
                    608: void
                    609: fdcStatus()
                    610: {
                    611:        printf("fd%d: head=%u",
                    612:          fdc.fdc_cmdstat[0] & 3, (fdc.fdc_cmdstat[0] & 4) >> 1);
                    613: 
                    614:        /*
                    615:         * Report on ST0 bits.
                    616:         */
                    617:        if (fdc.fdc_ncmdstat >= 1) {
                    618:                if (fdc.fdc_cmdstat[0] & ST0_NR)
                    619:                        printf(" <Not Ready>");
                    620: 
                    621:                if (fdc.fdc_cmdstat[0] & ST0_EC)
                    622:                        printf(" <Equipment Check>");
                    623:        }
                    624: 
                    625:        /*
                    626:         * Report on ST1 bits.
                    627:         */
                    628:        if (fdc.fdc_ncmdstat >= 2) {
                    629:                if (fdc.fdc_cmdstat[1] & ST1_MA)
                    630:                        printf(" <Missing Address Mark>");
                    631: 
                    632:                if (fdc.fdc_cmdstat[1] & ST1_NW)
                    633:                        printf(" <Write Protected>");
                    634: 
                    635:                if (fdc.fdc_cmdstat[1] & ST1_ND)
                    636:                        printf(" <No Data>");
                    637: 
                    638:                if (fdc.fdc_cmdstat[1] & ST1_OR)
                    639:                        printf(" <Overrun>");
                    640: 
                    641:                if (fdc.fdc_cmdstat[1] & ST1_DE)
                    642:                        printf(" <Data Error>");
                    643: 
                    644:                if (fdc.fdc_cmdstat[1] & ST1_EN)
                    645:                        printf(" <End of Cyl>");
                    646:        }
                    647: 
                    648:        /*
                    649:         * Report on ST2 bits.
                    650:         */
                    651:        if (fdc.fdc_ncmdstat >= 3) {
                    652:                if (fdc.fdc_cmdstat[2] & ST2_MD)
                    653:                        printf(" <Missing Data Address Mark>");
                    654: 
                    655:                if (fdc.fdc_cmdstat[2] & ST2_BC)
                    656:                        printf(" <Bad Cylinder>");
                    657: 
                    658:                if (fdc.fdc_cmdstat[2] & ST2_WC)
                    659:                        printf(" <Wrong Cylinder>");
                    660: 
                    661:                if (fdc.fdc_cmdstat[2] & ST2_DD)
                    662:                        printf(" <Bad Data CRC>");
                    663: 
                    664:                if (fdc.fdc_cmdstat[2] & ST2_CM)
                    665:                        printf(" <Data Deleted>");
                    666:        }
                    667: 
                    668:        printf("\n");
                    669: }
                    670: 
                    671: /*
                    672:  * Wait for FDC Main Status Register to assert Request for Master.
                    673:  * This function is designed to be called by busyWait().
                    674:  * It returns nonzero if RQM is asserted, 0 if not.
                    675:  */
                    676: static int
                    677: fdcWaitRQM()
                    678: {
                    679:        return (inb(FDCMSR) & MSRRQM);
                    680: }
                    681: 
                    682: /*
                    683:  * If sw is nonzero, start the timer for diskette;
                    684:  * else, stop the timer.
                    685:  */
                    686: void
                    687: setFlTimer(sw)
                    688: int sw;
                    689: {
                    690:        setFdcTiming(sw, FL_TIMING);
                    691: }
                    692: 
                    693: /*
                    694:  * If sw is nonzero, start the timer for floppy tape;
                    695:  * else, stop the timer.
                    696:  */
                    697: void
                    698: setFtTimer(sw)
                    699: int sw;
                    700: {
                    701:        setFdcTiming(sw, FT_TIMING);
                    702: }
                    703: 
                    704: static void
                    705: setFdcTiming(sw, mask)
                    706: int sw, mask;
                    707: {
                    708:        int s = sphi();
                    709: 
                    710:        /*
                    711:         * Only do something if current request changes status of
                    712:         * timing for the device.
                    713:         */
                    714:        if (sw && (fdcTiming & mask) == 0) {
                    715:                fdcTiming |= mask;
                    716:                drvl[FL_MAJOR].d_time = 1;
                    717:                goto setFdcTimingDone;
                    718:        }
                    719:        if (sw  == 0 && (fdcTiming & mask)) {
                    720:                fdcTiming &= ~mask;
                    721:                if (fdcTiming == 0)
                    722:                        drvl[FL_MAJOR].d_time = 0;
                    723:                goto setFdcTimingDone;
                    724:        }
                    725: 
                    726: setFdcTimingDone:
                    727:        spl(s);
                    728:        return;
                    729: }
                    730: 
                    731: static int
                    732: fdctimeout()
                    733: {
                    734:        if ((fdcTiming & FL_TIMING) && flCon)
                    735:                (*flCon->c_timer)();
                    736:        if ((fdcTiming & FT_TIMING) && ftCon)
                    737:                (*ftCon->c_timer)();
                    738: }
                    739: 
                    740: /*
                    741:  * Reset the fdc.
                    742:  * Sets drive select bits to 00, motor on bits to 0000.
                    743:  */
                    744: void
                    745: fdcReset()
                    746: {
                    747:        outb(FDCDOR, 0);
                    748: 
                    749:        /* "Not Reset FDC" must remain low for at least 3.5 usec */
                    750:        busyWait2(NULL, 4);
                    751:        outb(FDCDOR, DORNMR | DORIEN);
                    752: }
                    753: 
                    754: /*
                    755:  * Reset the fdc.
                    756:  * Maintain drive select and motor enable (as specified) during the reset.
                    757:  */
                    758: void
                    759: fdcResetSel(drive, motorOn)
                    760: int drive, motorOn;
                    761: {
                    762:        unsigned char motorBits = 0;
                    763:        unsigned char outByte;
                    764: 
                    765:        /* If needed, generate motor on bit for current selected drive. */
                    766:        if (motorOn)
                    767:                motorBits = 0x10 << drive;
                    768: 
                    769:        /*
                    770:         * Send drive select, motor on if needed, interrupt enable.
                    771:         * The "not reset" bit is zero, which is the point of this routine.
                    772:         */
                    773:        outByte = motorBits | drive | DORIEN;
                    774:        outb(FDCDOR, outByte);
                    775: 
                    776:        /* "Not Reset FDC" must remain low for at least 3.5 usec */
                    777:        busyWait2(NULL, 4);
                    778: 
                    779:        outByte |= DORNMR;
                    780:        outb(FDCDOR, outByte);
                    781: }
                    782: 
                    783: /*
                    784:  * If sw is nonzero, try to seize the fdc interrupt for the diskette;
                    785:  * else, try to release it.
                    786:  *
                    787:  * Return 1 on success, 0 on failure.
                    788:  */
                    789: int
                    790: setFlIntr(sw)
                    791: int sw;
                    792: {
                    793:        return setFdcIntr(sw, FL_INTR);
                    794: }
                    795: 
                    796: /*
                    797:  * If sw is nonzero, try to seize the fdc interrupt for floppy tape;
                    798:  * else, try to release it.
                    799:  *
                    800:  * Return 1 on success, 0 on failure.
                    801:  */
                    802: int
                    803: setFtIntr(sw)
                    804: int sw;
                    805: {
                    806:        return setFdcIntr(sw, FT_INTR);
                    807: }
                    808: 
                    809: static int
                    810: setFdcIntr(sw, mask)
                    811: int sw, mask;
                    812: {
                    813:        int ret;
                    814: 
                    815:        /*
                    816:         * if attaching
                    817:         *   if fdc interrupt is free
                    818:         *      attach as requested
                    819:         *   else
                    820:         *      return failure
                    821:         * else
                    822:         *   if fdc requesting device now owns fdc interrupt
                    823:         *      detach as requested
                    824:         *   else
                    825:         *      return failure
                    826:         */
                    827:        if (sw)
                    828:                if (fdcIntOwner == 0) {
                    829:                        fdcIntOwner = mask;
                    830:                        ret = 1;
                    831:                } else
                    832:                        ret = 0;
                    833:        else
                    834:                if (fdcIntOwner == mask) {
                    835:                        fdcIntOwner = 0;
                    836:                        ret = 1;
                    837:                } else
                    838:                        ret = 0;
                    839: }
                    840: 
                    841: /*                       * * * * End of fdc.c * * * *                  */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.