Annotation of Net2/arch/i386/isa/fd.c, revision 1.1.1.2

1.1       root        1: /*-
                      2:  * Copyright (c) 1990 The Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * This code is derived from software contributed to Berkeley by
                      6:  * Don Ahn.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  * 3. All advertising materials mentioning features or use of this software
                     17:  *    must display the following acknowledgement:
                     18:  *     This product includes software developed by the University of
                     19:  *     California, Berkeley and its contributors.
                     20:  * 4. Neither the name of the University nor the names of its contributors
                     21:  *    may be used to endorse or promote products derived from this software
                     22:  *    without specific prior written permission.
                     23:  *
                     24:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     25:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     26:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     27:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     28:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     29:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     30:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     31:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     32:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     33:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     34:  * SUCH DAMAGE.
                     35:  *
                     36:  *     @(#)fd.c        7.4 (Berkeley) 5/25/91
                     37:  */
                     38: 
                     39: #include "fd.h"
                     40: #if NFD > 0
                     41: 
                     42: #include "param.h"
                     43: #include "dkbad.h"
                     44: #include "systm.h"
                     45: #include "conf.h"
                     46: #include "file.h"
                     47: #include "ioctl.h"
                     48: #include "buf.h"
                     49: #include "uio.h"
                     50: #include "i386/isa/isa_device.h"
                     51: #include "i386/isa/fdreg.h"
                     52: #include "i386/isa/icu.h"
1.1.1.2 ! root       53: #undef NFD
        !            54: #define NFD 2
        !            55: /*#define      FDDEBUG
        !            56: #define FDTEST
        !            57: #define FDOTHER*/
1.1       root       58: 
1.1.1.2 ! root       59: #define        FDUNIT(s)       ((s>>3)&1)
        !            60: #define        FDTYPE(s)       ((s)&7)
1.1       root       61: 
                     62: #define b_cylin b_resid
                     63: #define b_step b_resid
                     64: #define FDBLK 512
                     65: #define NUMTYPES 4
                     66: 
                     67: struct fd_type {
                     68:        int     sectrac;                /* sectors per track         */
                     69:        int     secsize;                /* size code for sectors     */
                     70:        int     datalen;                /* data len when secsize = 0 */
                     71:        int     gap;                    /* gap len between sectors   */
                     72:        int     tracks;                 /* total num of tracks       */
                     73:        int     size;                   /* size of disk in sectors   */
                     74:        int     steptrac;               /* steps per cylinder        */
                     75:        int     trans;                  /* transfer speed code       */
                     76: };
                     77: 
                     78: struct fd_type fd_types[NUMTYPES] = {
                     79:        { 18,2,0xFF,0x1B,80,2880,1,0 }, /* 1.44 meg HD 3.5in floppy    */
                     80:        { 15,2,0xFF,0x1B,80,2400,1,0 }, /* 1.2 meg HD floppy           */
                     81:        { 9,2,0xFF,0x23,40,720,2,1 },   /* 360k floppy in 1.2meg drive */
                     82:        { 9,2,0xFF,0x2A,40,720,1,1 },   /* 360k floppy in DD drive     */
                     83: };
                     84: 
                     85: struct fd_u {
                     86:        int type;               /* Drive type (HD, DD     */
                     87:        int active;             /* Drive activity boolean */
                     88:        int motor;              /* Motor on flag          */
                     89:        struct buf head;        /* Head of buf chain      */
                     90:        struct buf rhead;       /* Raw head of buf chain  */
                     91:        int reset;
                     92: } fd_unit[NFD];
                     93: 
                     94: 
                     95: extern int hz;
                     96: 
                     97: /* state needed for current transfer */
                     98: static fdc;    /* floppy disk controller io base register */
                     99: int    fd_dmachan = 2;
                    100: static int fd_skip;
                    101: static int fd_state;
                    102: static int fd_retry;
                    103: static int fd_drive;
                    104: static int fd_track = -1;
                    105: static int fd_status[7];
                    106: 
                    107: /*
                    108:        make sure bounce buffer for DMA is aligned since the DMA chip
                    109:        doesn't roll over properly over a 64k boundary
                    110: */
                    111: extern struct buf *dma_bounce[];
                    112: 
                    113: /****************************************************************************/
                    114: /*                      autoconfiguration stuff                             */
                    115: /****************************************************************************/
                    116: int fdprobe(), fdattach(), fd_turnoff();
                    117: 
                    118: struct isa_driver fddriver = {
                    119:        fdprobe, fdattach, "fd",
                    120: };
                    121: 
                    122: fdprobe(dev)
                    123: struct isa_device *dev;
                    124: {
                    125:        return 1;
                    126: }
                    127: 
                    128: fdattach(dev)
                    129: struct isa_device *dev;
                    130: {      int     s;
                    131: 
                    132:        fdc = dev->id_iobase;
                    133:        /* Set transfer to 500kbps */
                    134:        outb(fdc+fdctl,0);
                    135:        fd_turnoff(0);
                    136: }
                    137: 
                    138: int
                    139: fdsize(dev)
                    140: dev_t  dev;
                    141: {
                    142:        return(2400);
                    143: }
                    144: 
                    145: /****************************************************************************/
                    146: /*                               fdstrategy                                 */
                    147: /****************************************************************************/
                    148: fdstrategy(bp)
                    149:        register struct buf *bp;        /* IO operation to perform */
                    150: {
                    151:        register struct buf *dp,*dp0,*dp1;
                    152:        long nblocks,blknum;
                    153:        int     unit, type, s;
                    154: 
                    155:        unit = FDUNIT(minor(bp->b_dev));
                    156:        type = FDTYPE(minor(bp->b_dev));
                    157: 
                    158: #ifdef FDTEST
                    159: printf("fdstrat%d, blk = %d, bcount = %d, addr = %x|",
                    160:        unit, bp->b_blkno, bp->b_bcount,bp->b_un.b_addr);
                    161: #endif
                    162:        if ((unit >= NFD) || (bp->b_blkno < 0)) {
                    163:                printf("fdstrat: unit = %d, blkno = %d, bcount = %d\n",
                    164:                        unit, bp->b_blkno, bp->b_bcount);
                    165:                pg("fd:error in fdstrategy");
                    166:                bp->b_error = EINVAL;
                    167:                bp->b_flags |= B_ERROR;
                    168:                goto bad;
                    169:        }
                    170:        /*
                    171:         * Set up block calculations.
                    172:         */
                    173:        blknum = (unsigned long) bp->b_blkno * DEV_BSIZE/FDBLK;
                    174:        nblocks = fd_types[type].size;
                    175:        if (blknum + (bp->b_bcount / FDBLK) > nblocks) {
                    176:                if (blknum == nblocks) {
                    177:                        bp->b_resid = bp->b_bcount;
                    178:                } else {
                    179:                        bp->b_error = ENOSPC;
                    180:                        bp->b_flags |= B_ERROR;
                    181:                }
                    182:                goto bad;
                    183:        }
                    184:        bp->b_cylin = blknum / (fd_types[type].sectrac * 2);
                    185:        dp = &fd_unit[unit].head;
                    186:        dp0 = &fd_unit[0].head;
                    187:        dp1 = &fd_unit[1].head;
                    188:        dp->b_step = (fd_types[fd_unit[unit].type].steptrac);
                    189:        s = splbio();
                    190:        disksort(dp, bp);
                    191:        if ((dp0->b_active == 0)&&(dp1->b_active == 0)) {
                    192: #ifdef FDDEBUG
                    193: printf("T|");
                    194: #endif
                    195:                dp->b_active = 1;
                    196:                fd_drive = unit;
                    197:                fd_track = -1;  /* force seek on first xfer */
                    198:                untimeout(fd_turnoff,unit);
                    199:                fdstart(unit);          /* start drive if idle */
                    200:        }
                    201:        splx(s);
                    202:        return;
                    203: 
                    204: bad:
                    205:        biodone(bp);
                    206: }
                    207: 
                    208: /****************************************************************************/
                    209: /*                            motor control stuff                           */
                    210: /****************************************************************************/
                    211: set_motor(unit,reset)
                    212: int unit,reset;
                    213: {
                    214:        int m0,m1;
                    215:        m0 = fd_unit[0].motor;
                    216:        m1 = fd_unit[1].motor;
                    217:        outb(fdc+fdout,unit | (reset ? 0 : 0xC)  | (m0 ? 16 : 0) | (m1 ? 32 : 0));
                    218: }
                    219: 
                    220: fd_turnoff(unit)
                    221: int unit;
                    222: {
                    223:        fd_unit[unit].motor = 0;
                    224:        if (unit) set_motor(0,0);
                    225:        else set_motor(1,0);
                    226: }
                    227: 
                    228: fd_turnon(unit)
                    229: int unit;
                    230: {
                    231:        fd_unit[unit].motor = 1;
                    232:        set_motor(unit,0);
                    233: }
                    234: 
                    235: /****************************************************************************/
                    236: /*                             fdc in/out                                   */
                    237: /****************************************************************************/
                    238: int
                    239: in_fdc()
                    240: {
                    241:        int i;
                    242:        while ((i = inb(fdc+fdsts) & (NE7_DIO|NE7_RQM)) != (NE7_DIO|NE7_RQM))
                    243:                if (i == NE7_RQM) return -1;
                    244:        return inb(fdc+fddata);
                    245: }
                    246: 
                    247: dump_stat()
                    248: {
                    249:        int i;
                    250:        for(i=0;i<7;i++) {
                    251:                fd_status[i] = in_fdc();
                    252:                if (fd_status[i] < 0) break;
                    253:        }
                    254: printf("FD bad status :%lx %lx %lx %lx %lx %lx %lx\n",
                    255:        fd_status[0], fd_status[1], fd_status[2], fd_status[3],
                    256:        fd_status[4], fd_status[5], fd_status[6] );
                    257: }
                    258: 
                    259: out_fdc(x)
                    260: int x;
                    261: {
                    262:        int r,errcnt;
                    263:        static int maxcnt = 0;
                    264:        errcnt = 0;
                    265:        do {
                    266:                r = (inb(fdc+fdsts) & (NE7_DIO|NE7_RQM));
                    267:                if (r== NE7_RQM) break;
                    268:                if (r==(NE7_DIO|NE7_RQM)) {
                    269:                        dump_stat(); /* error: direction. eat up output */
                    270: #ifdef FDOTHER
                    271: printf("%lx\n",x);
                    272: #endif
                    273:                }
                    274:                /* printf("Error r = %d:",r); */
                    275:                errcnt++;
                    276:        } while (1);
                    277:        if (errcnt > maxcnt) {
                    278:                maxcnt = errcnt;
                    279: #ifdef FDOTHER
                    280: printf("New MAX = %d\n",maxcnt);
                    281: #endif
                    282:        }
                    283:        outb(fdc+fddata,x);
                    284: }
                    285: 
                    286: /* see if fdc responding */
                    287: int
                    288: check_fdc()
                    289: {
                    290:        int i;
                    291:        for(i=0;i<100;i++) {
                    292:                if (inb(fdc+fdsts)& NE7_RQM) return 0;
                    293:        }
                    294:        return 1;
                    295: }
                    296: 
                    297: /****************************************************************************/
                    298: /*                           fdopen/fdclose                                 */
                    299: /****************************************************************************/
                    300: Fdopen(dev, flags)
                    301:        dev_t   dev;
                    302:        int     flags;
                    303: {
                    304:        int unit = FDUNIT(minor(dev));
                    305:        int type = FDTYPE(minor(dev));
                    306:        int s;
                    307: 
                    308:        /* check bounds */
                    309:        if (unit >= NFD) return(ENXIO);
                    310:        if (type >= NUMTYPES) return(ENXIO);
                    311: /*
                    312:        if (check_fdc()) return(EBUSY);
                    313: */
                    314: 
                    315:        /* Set proper disk type, only allow one type */
                    316:        return 0;
                    317: }
                    318: 
                    319: fdclose(dev, flags)
                    320:        dev_t dev;
                    321: {
1.1.1.2 ! root      322:        return(0);
1.1       root      323: }
                    324: 
                    325: 
                    326: /****************************************************************************/
                    327: /*                                 fdstart                                  */
                    328: /****************************************************************************/
                    329: fdstart(unit)
                    330: int unit;
                    331: {
                    332:        register struct buf *dp,*bp;
                    333:        int s;
                    334: 
                    335: #ifdef FDTEST
                    336: printf("st%d|",unit);
                    337: #endif 
                    338:        s = splbio();
                    339:        if (!fd_unit[unit].motor) {
                    340:                fd_turnon(unit);
                    341:                /* Wait for 1 sec */
                    342:                timeout(fdstart,unit,hz);
                    343:                /*DELAY(1000000);*/
                    344:        }else
                    345:                 {
                    346:                /* make sure drive is selected as well as on */
                    347:                /*set_motor(unit,0);*/
                    348: 
                    349:                dp = &fd_unit[unit].head;
                    350:                bp = dp->b_actf;
                    351:                fd_retry = 0;
                    352:                if (fd_unit[unit].reset) fd_state = 1;
                    353:                else {
                    354:                        /* DO a RESET */
                    355:                        fd_unit[unit].reset = 1;
                    356:                        fd_state = 5;
                    357:                }
                    358:                fd_skip = 0;
                    359: #ifdef FDDEBUG
                    360: printf("Seek %d %d\n", bp->b_cylin, dp->b_step);
                    361: #endif
                    362:                if (bp->b_cylin != fd_track) {
                    363:                /* Seek necessary, never quite sure where head is at! */
                    364:                out_fdc(15);    /* Seek function */
                    365:                out_fdc(unit);  /* Drive number */
                    366:                out_fdc(bp->b_cylin * dp->b_step);
                    367:                } else fdintr(0xff);
                    368:        }
                    369:        splx(s);
                    370: }
                    371: 
                    372: fd_timeout(x)
                    373: int x;
                    374: {
                    375:        int i,j;
                    376:        struct buf *dp,*bp;
                    377: 
                    378:        dp = &fd_unit[fd_drive].head;
                    379:        bp = dp->b_actf;
                    380: 
                    381:        out_fdc(0x4);
                    382:        out_fdc(fd_drive);
                    383:        i = in_fdc();
                    384:        printf("Timeout drive status %lx\n",i);
                    385: 
                    386:        out_fdc(0x8);
                    387:        i = in_fdc();
                    388:        j = in_fdc();
                    389:        printf("ST0 = %lx, PCN = %lx\n",i,j);
                    390: 
                    391:        if (bp) badtrans(dp,bp);
                    392: }
                    393: 
                    394: /****************************************************************************/
                    395: /*                                 fdintr                                   */
                    396: /****************************************************************************/
                    397: fdintr(unit)
                    398: {
                    399:        register struct buf *dp,*bp;
                    400:        struct buf *dpother;
                    401:        int read,head,trac,sec,i,s,sectrac,cyl;
                    402:        unsigned long blknum;
                    403:        struct fd_type *ft;
                    404: 
                    405: #ifdef FDTEST
                    406:        printf("state %d, unit %d, dr %d|",fd_state,unit,fd_drive);
                    407: #endif
                    408: 
                    409:        dp = &fd_unit[fd_drive].head;
                    410:        bp = dp->b_actf;
                    411:        read = bp->b_flags & B_READ;
                    412:        ft = &fd_types[FDTYPE(bp->b_dev)];
                    413: 
                    414:        switch (fd_state) {
                    415:        case 1 : /* SEEK DONE, START DMA */
                    416:                /* Make sure seek really happened*/
                    417:                if (unit != 0xff) {
                    418:                        out_fdc(0x8);
                    419:                        i = in_fdc();
                    420:                        cyl = in_fdc();
                    421:                        if (!(i&0x20) || (cyl != bp->b_cylin*dp->b_step)) {
                    422: printf("Stray int ST0 = %lx, PCN = %lx:",i,cyl);
                    423:                                return;
                    424:                        }
                    425:                }
                    426: 
                    427:                fd_track = bp->b_cylin;
                    428:                at_dma(read,bp->b_un.b_addr+fd_skip,FDBLK, fd_dmachan);
                    429:                blknum = (unsigned long)bp->b_blkno*DEV_BSIZE/FDBLK
                    430:                        + fd_skip/FDBLK;
                    431:                sectrac = ft->sectrac;
                    432:                sec = blknum %  (sectrac * 2);
                    433:                head = sec / sectrac;
                    434:                sec = sec % sectrac + 1;
                    435: 
                    436:                if (read)  out_fdc(0xE6);       /* READ */
                    437:                else out_fdc(0xC5);             /* WRITE */
                    438:                out_fdc(head << 2 | fd_drive);  /* head & unit */
                    439:                out_fdc(fd_track);              /* track */
                    440:                out_fdc(head);
                    441:                out_fdc(sec);                   /* sector XXX +1? */
                    442:                out_fdc(ft->secsize);           /* sector size */
                    443:                out_fdc(sectrac);               /* sectors/track */
                    444:                out_fdc(ft->gap);               /* gap size */
                    445:                out_fdc(ft->datalen);           /* data length */
                    446:                fd_state = 2;
                    447:                /* XXX PARANOIA */
                    448:                untimeout(fd_timeout,2);
                    449:                timeout(fd_timeout,2,hz);
                    450:                break;
                    451:        case 2 : /* IO DONE, post-analyze */
                    452:                untimeout(fd_timeout,2);
                    453:                for(i=0;i<7;i++) {
                    454:                        fd_status[i] = in_fdc();
                    455:                }
                    456:                if (fd_status[0]&0xF8) {
                    457: #ifdef FDOTHER
                    458: printf("status0 err %d:",fd_status[0]);
                    459: #endif
                    460:                        goto retry;
                    461:                }
                    462: /*
                    463:                if (fd_status[1]){
                    464:                        printf("status1 err %d:",fd_status[0]);
                    465:                        goto retry;
                    466:                }
                    467:                if (fd_status[2]){
                    468:                        printf("status2 err %d:",fd_status[0]);
                    469:                        goto retry;
                    470:                }
                    471: */
                    472:                /* All OK */
                    473:                if (!kernel_space(bp->b_un.b_addr+fd_skip)) {
                    474:                        /* RAW transfer */
                    475:                        if (read) bcopy(dma_bounce[fd_dmachan]->b_un.b_addr,
                    476:                                bp->b_un.b_addr+fd_skip, FDBLK);
                    477:                }
                    478:                fd_skip += FDBLK;
                    479:                if (fd_skip >= bp->b_bcount) {
                    480: #ifdef FDTEST
                    481: printf("DONE %d|", bp->b_blkno);
                    482: #endif
                    483:                        /* ALL DONE */
                    484:                        fd_skip = 0;
                    485:                        bp->b_resid = 0;
                    486:                        dp->b_actf = bp->av_forw;
                    487:                        biodone(bp);
                    488:                        nextstate(dp);
                    489: 
                    490:                } else {
                    491: #ifdef FDDEBUG
                    492: printf("next|");
                    493: #endif
                    494:                        /* set up next transfer */
                    495:                        blknum = (unsigned long)bp->b_blkno*DEV_BSIZE/FDBLK
                    496:                                + fd_skip/FDBLK;
                    497:                        fd_state = 1;
                    498:                        bp->b_cylin = (blknum / (ft->sectrac * 2));
                    499:                        if (bp->b_cylin != fd_track) {
                    500: #ifdef FDTEST
                    501: printf("Seek|");
                    502: #endif
                    503:                                /* SEEK Necessary */
                    504:                                out_fdc(15);    /* Seek function */
                    505:                                out_fdc(fd_drive);/* Drive number */
                    506:                                out_fdc(bp->b_cylin * dp->b_step);
                    507:                                break;
                    508:                        } else fdintr(0xff);
                    509:                }
                    510:                break;
                    511:        case 3:
                    512: #ifdef FDOTHER
                    513: printf("Seek %d %d\n", bp->b_cylin, dp->b_step);
                    514: #endif
                    515:                /* Seek necessary */
                    516:                out_fdc(15);    /* Seek function */
                    517:                out_fdc(fd_drive);/* Drive number */
                    518:                out_fdc(bp->b_cylin * dp->b_step);
                    519:                fd_state = 1;
                    520:                break;
                    521:        case 4:
                    522:                out_fdc(3); /* specify command */
                    523:                out_fdc(0xDF);
                    524:                out_fdc(2);
                    525:                out_fdc(7);     /* Recalibrate Function */
                    526:                out_fdc(fd_drive);
                    527:                fd_state = 3;
                    528:                break;
                    529:        case 5:
                    530: #ifdef FDOTHER
                    531:                printf("**RESET**\n");
                    532: #endif
                    533:                /* Try a reset, keep motor on */
                    534:                set_motor(fd_drive,1);
                    535:                set_motor(fd_drive,0);
                    536:                outb(fdc+fdctl,ft->trans);
                    537:                fd_retry++;
                    538:                fd_state = 4;
                    539:                break;
                    540:        default:
                    541:                printf("Unexpected FD int->");
                    542:                out_fdc(0x8);
                    543:                i = in_fdc();
                    544:                sec = in_fdc();
                    545:                printf("ST0 = %lx, PCN = %lx\n",i,sec);
                    546:                out_fdc(0x4A); 
                    547:                out_fdc(fd_drive);
                    548:                for(i=0;i<7;i++) {
                    549:                        fd_status[i] = in_fdc();
                    550:                }
                    551:        printf("intr status :%lx %lx %lx %lx %lx %lx %lx ",
                    552:                fd_status[0], fd_status[1], fd_status[2], fd_status[3],
                    553:                fd_status[4], fd_status[5], fd_status[6] );
                    554:                break;
                    555:        }
                    556:        return;
                    557: retry:
                    558:        switch(fd_retry) {
                    559:        case 0: case 1:
                    560:        case 2: case 3:
                    561:                break;
                    562:        case 4:
                    563:                fd_retry++;
                    564:                fd_state = 5;
                    565:                fdintr(0xff);
                    566:                return;
                    567:        case 5: case 6: case 7:
                    568:                break;
                    569:        default:
                    570:                printf("FD err %lx %lx %lx %lx %lx %lx %lx\n",
                    571:                fd_status[0], fd_status[1], fd_status[2], fd_status[3],
                    572:                fd_status[4], fd_status[5], fd_status[6] );
                    573:                badtrans(dp,bp);
                    574:                return;
                    575:        }
                    576:        fd_state = 1;
                    577:        fd_retry++;
                    578:        fdintr(0xff);
                    579: }
                    580: 
                    581: badtrans(dp,bp)
                    582: struct buf *dp,*bp;
                    583: {
                    584: 
                    585:        bp->b_flags |= B_ERROR;
                    586:        bp->b_error = EIO;
                    587:        bp->b_resid = bp->b_bcount - fd_skip;
                    588:        dp->b_actf = bp->av_forw;
                    589:        fd_skip = 0;
                    590:        biodone(bp);
                    591:        nextstate(dp);
                    592: 
                    593: }
                    594: 
                    595: /*
                    596:        nextstate : After a transfer is done, continue processing
                    597:        requests on the current drive queue.  If empty, go to
                    598:        the other drives queue.  If that is empty too, timeout
                    599:        to turn off the current drive in 5 seconds, and go
                    600:        to state 0 (not expecting any interrupts).
                    601: */
                    602: 
                    603: nextstate(dp)
                    604: struct buf *dp;
                    605: {
                    606:        struct buf *dpother;
                    607:        
                    608:        dpother = &fd_unit[fd_drive ? 0 : 1].head;
                    609:        if (dp->b_actf) fdstart(fd_drive);
                    610:        else if (dpother->b_actf) {
                    611: #ifdef FDTEST
                    612: printf("switch|");
                    613: #endif
                    614:                untimeout(fd_turnoff,fd_drive);
                    615:                timeout(fd_turnoff,fd_drive,5*hz);
                    616:                fd_drive = 1 - fd_drive;
                    617:                dp->b_active = 0;
                    618:                dpother->b_active = 1;
                    619:                fdstart(fd_drive);
                    620:        } else {
                    621: #ifdef FDTEST
                    622: printf("off|");
                    623: #endif
                    624:                untimeout(fd_turnoff,fd_drive);
                    625:                timeout(fd_turnoff,fd_drive,5*hz);
                    626:                fd_state = 0;
                    627:                dp->b_active = 0;
                    628:        }
                    629: }
                    630: #endif

unix.superglobalmegacorp.com

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