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

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.3 ! root       53: #include "i386/isa/rtc.h"
1.1.1.2   root       54: #undef NFD
                     55: #define NFD 2
1.1       root       56: 
1.1.1.2   root       57: #define        FDUNIT(s)       ((s>>3)&1)
                     58: #define        FDTYPE(s)       ((s)&7)
1.1       root       59: 
                     60: #define b_cylin b_resid
                     61: #define b_step b_resid
                     62: #define FDBLK 512
                     63: #define NUMTYPES 4
                     64: 
                     65: struct fd_type {
                     66:        int     sectrac;                /* sectors per track         */
                     67:        int     secsize;                /* size code for sectors     */
                     68:        int     datalen;                /* data len when secsize = 0 */
                     69:        int     gap;                    /* gap len between sectors   */
                     70:        int     tracks;                 /* total num of tracks       */
                     71:        int     size;                   /* size of disk in sectors   */
                     72:        int     steptrac;               /* steps per cylinder        */
                     73:        int     trans;                  /* transfer speed code       */
                     74: };
                     75: 
                     76: struct fd_type fd_types[NUMTYPES] = {
                     77:        { 18,2,0xFF,0x1B,80,2880,1,0 }, /* 1.44 meg HD 3.5in floppy    */
                     78:        { 15,2,0xFF,0x1B,80,2400,1,0 }, /* 1.2 meg HD floppy           */
                     79:        { 9,2,0xFF,0x23,40,720,2,1 },   /* 360k floppy in 1.2meg drive */
                     80:        { 9,2,0xFF,0x2A,40,720,1,1 },   /* 360k floppy in DD drive     */
                     81: };
                     82: 
                     83: struct fd_u {
                     84:        int type;               /* Drive type (HD, DD     */
                     85:        int active;             /* Drive activity boolean */
                     86:        int motor;              /* Motor on flag          */
                     87:        struct buf head;        /* Head of buf chain      */
                     88:        struct buf rhead;       /* Raw head of buf chain  */
                     89:        int reset;
                     90: } fd_unit[NFD];
                     91: 
                     92: 
1.1.1.3 ! root       93: struct buf fdtab, fdutab[NFD]; /* controller activity */
1.1       root       94: extern int hz;
                     95: 
                     96: /* state needed for current transfer */
                     97: static fdc;    /* floppy disk controller io base register */
1.1.1.3 ! root       98: int    fd_dmachan;
1.1       root       99: static int fd_skip;
                    100: static int fd_state;
                    101: static int fd_retry;
                    102: static int fd_drive;
1.1.1.3 ! root      103: static int fd_hddrv;
1.1       root      104: static int fd_track = -1;
                    105: static int fd_status[7];
                    106: 
                    107: /****************************************************************************/
                    108: /*                      autoconfiguration stuff                             */
                    109: /****************************************************************************/
                    110: int fdprobe(), fdattach(), fd_turnoff();
                    111: 
                    112: struct isa_driver fddriver = {
                    113:        fdprobe, fdattach, "fd",
                    114: };
                    115: 
1.1.1.3 ! root      116: /*
        !           117:  * probe for existance of controller
        !           118:  */
1.1       root      119: fdprobe(dev)
                    120: struct isa_device *dev;
                    121: {
1.1.1.3 ! root      122:        fdc = dev->id_iobase;
        !           123: 
        !           124:        /* see if it can handle a command */
        !           125:        if (out_fdc(NE7CMD_SPECIFY) < 0) {
        !           126:                fdc = 0;
        !           127:                return(0);
        !           128:        }
        !           129:        out_fdc(0xDF);
        !           130:        out_fdc(2);
1.1       root      131:        return 1;
                    132: }
                    133: 
1.1.1.3 ! root      134: /*
        !           135:  * wire controller into system, look for floppy units
        !           136:  */
1.1       root      137: fdattach(dev)
                    138: struct isa_device *dev;
1.1.1.3 ! root      139: {
        !           140:        int     i, hdr;
        !           141:        unsigned fdt,st0, cyl;
        !           142: 
        !           143:        fd_dmachan = dev->id_drq;
        !           144: 
        !           145:        fdt = rtcin(RTC_FDISKETTE);
        !           146:        hdr = 0;
        !           147: 
        !           148:        /* check for each floppy drive */
        !           149:        for (i = 0; i < NFD; i++) {
        !           150:                /* is there a unit? */
        !           151:                if ((fdt & 0xf0) == RTCFDT_NONE)
        !           152:                        continue;
        !           153: 
        !           154: #ifdef notyet
        !           155:                /* select it */
        !           156:                fd_turnon(i);
        !           157:                DELAY(10000);
        !           158:                out_fdc(NE7CMD_RECAL);  /* Recalibrate Function */
        !           159:                out_fdc(i);
        !           160:                DELAY(10000);
        !           161: 
        !           162:                /* anything responding */
        !           163:                out_fdc(NE7CMD_SENSEI);
        !           164:                st0 = in_fdc();
        !           165:                cyl = in_fdc();
        !           166:                if (st0 & 0xd0)
        !           167:                        continue;
        !           168: 
        !           169: #endif
        !           170:                /* yes, announce it */
        !           171:                if (!hdr)
        !           172:                        printf(" drives ");
        !           173:                else
        !           174:                        printf(", ");
        !           175:                printf("%d: ", i);
        !           176: 
        !           177:                if ((fdt & 0xf0) == RTCFDT_12M) {
        !           178:                        printf("1.2M");
        !           179:                        fd_unit[i].type = 1;
        !           180:                }
        !           181:                if ((fdt & 0xf0) == RTCFDT_144M) {
        !           182:                        printf("1.44M");
        !           183:                        fd_unit[i].type = 0;
        !           184:                }
        !           185: 
        !           186:                fdt <<= 4;
        !           187:                fd_turnoff(i);
        !           188:                hdr = 1;
        !           189:        }
1.1       root      190: 
                    191:        /* Set transfer to 500kbps */
                    192:        outb(fdc+fdctl,0);
                    193:        fd_turnoff(0);
                    194: }
                    195: 
                    196: int
                    197: fdsize(dev)
                    198: dev_t  dev;
                    199: {
1.1.1.3 ! root      200:        return(0);
1.1       root      201: }
                    202: 
                    203: /****************************************************************************/
                    204: /*                               fdstrategy                                 */
                    205: /****************************************************************************/
                    206: fdstrategy(bp)
                    207:        register struct buf *bp;        /* IO operation to perform */
                    208: {
                    209:        register struct buf *dp,*dp0,*dp1;
                    210:        long nblocks,blknum;
                    211:        int     unit, type, s;
                    212: 
                    213:        unit = FDUNIT(minor(bp->b_dev));
1.1.1.3 ! root      214:        /*type = FDTYPE(minor(bp->b_dev));*/
        !           215:        type = fd_unit[unit].type;
1.1       root      216: 
                    217: #ifdef FDTEST
                    218: printf("fdstrat%d, blk = %d, bcount = %d, addr = %x|",
                    219:        unit, bp->b_blkno, bp->b_bcount,bp->b_un.b_addr);
                    220: #endif
                    221:        if ((unit >= NFD) || (bp->b_blkno < 0)) {
                    222:                printf("fdstrat: unit = %d, blkno = %d, bcount = %d\n",
                    223:                        unit, bp->b_blkno, bp->b_bcount);
                    224:                pg("fd:error in fdstrategy");
                    225:                bp->b_error = EINVAL;
                    226:                bp->b_flags |= B_ERROR;
                    227:                goto bad;
                    228:        }
                    229:        /*
                    230:         * Set up block calculations.
                    231:         */
                    232:        blknum = (unsigned long) bp->b_blkno * DEV_BSIZE/FDBLK;
                    233:        nblocks = fd_types[type].size;
                    234:        if (blknum + (bp->b_bcount / FDBLK) > nblocks) {
                    235:                if (blknum == nblocks) {
                    236:                        bp->b_resid = bp->b_bcount;
                    237:                } else {
                    238:                        bp->b_error = ENOSPC;
                    239:                        bp->b_flags |= B_ERROR;
                    240:                }
                    241:                goto bad;
                    242:        }
                    243:        bp->b_cylin = blknum / (fd_types[type].sectrac * 2);
                    244:        dp = &fd_unit[unit].head;
                    245:        dp->b_step = (fd_types[fd_unit[unit].type].steptrac);
                    246:        s = splbio();
                    247:        disksort(dp, bp);
1.1.1.3 ! root      248:        if (dp->b_active == 0) {
1.1       root      249: #ifdef FDDEBUG
                    250: printf("T|");
                    251: #endif
                    252:                dp->b_active = 1;
                    253:                fd_drive = unit;
                    254:                fd_track = -1;  /* force seek on first xfer */
                    255:                untimeout(fd_turnoff,unit);
                    256:                fdstart(unit);          /* start drive if idle */
                    257:        }
                    258:        splx(s);
                    259:        return;
                    260: 
                    261: bad:
                    262:        biodone(bp);
                    263: }
                    264: 
                    265: /****************************************************************************/
                    266: /*                            motor control stuff                           */
                    267: /****************************************************************************/
                    268: set_motor(unit,reset)
                    269: int unit,reset;
                    270: {
                    271:        int m0,m1;
                    272:        m0 = fd_unit[0].motor;
                    273:        m1 = fd_unit[1].motor;
1.1.1.3 ! root      274:        outb(fdc+fdout, (unit&FDO_FDSEL)
        !           275:                | (reset ? 0 : (FDO_FRST|FDO_FDMAEN))
        !           276:                | (m0 ? FDO_MOEN0 : 0)
        !           277:                | (m1 ? FDO_MOEN1 : 0));
1.1       root      278: }
                    279: 
                    280: fd_turnoff(unit)
                    281: int unit;
                    282: {
                    283:        fd_unit[unit].motor = 0;
                    284:        if (unit) set_motor(0,0);
                    285:        else set_motor(1,0);
                    286: }
                    287: 
                    288: fd_turnon(unit)
                    289: int unit;
                    290: {
                    291:        fd_unit[unit].motor = 1;
                    292:        set_motor(unit,0);
                    293: }
                    294: 
                    295: /****************************************************************************/
                    296: /*                             fdc in/out                                   */
                    297: /****************************************************************************/
                    298: int
                    299: in_fdc()
                    300: {
1.1.1.3 ! root      301:        int i, j = 100000;
        !           302:        while ((i = inb(fdc+fdsts) & (NE7_DIO|NE7_RQM)) != (NE7_DIO|NE7_RQM) && j-- > 0)
1.1       root      303:                if (i == NE7_RQM) return -1;
1.1.1.3 ! root      304:        if (j <= 0)
        !           305:                return(-1);
1.1       root      306:        return inb(fdc+fddata);
                    307: }
                    308: 
                    309: out_fdc(x)
                    310: int x;
                    311: {
1.1.1.3 ! root      312:        int i = 100000;
1.1       root      313: 
1.1.1.3 ! root      314:        while ((inb(fdc+fdsts) & NE7_DIO) && i-- > 0);
        !           315:        while ((inb(fdc+fdsts) & NE7_RQM) == 0 && i-- > 0);
        !           316:        if (i <= 0) return (-1);
        !           317:        outb(fdc+fddata,x);
        !           318:        return (0);
1.1       root      319: }
                    320: 
1.1.1.3 ! root      321: static fdopenf;
1.1       root      322: /****************************************************************************/
                    323: /*                           fdopen/fdclose                                 */
                    324: /****************************************************************************/
                    325: Fdopen(dev, flags)
                    326:        dev_t   dev;
                    327:        int     flags;
                    328: {
                    329:        int unit = FDUNIT(minor(dev));
1.1.1.3 ! root      330:        /*int type = FDTYPE(minor(dev));*/
1.1       root      331:        int s;
                    332: 
1.1.1.3 ! root      333:        fdopenf = 1;
1.1       root      334:        /* check bounds */
                    335:        if (unit >= NFD) return(ENXIO);
1.1.1.3 ! root      336:        /*if (type >= NUMTYPES) return(ENXIO);*/
1.1       root      337: 
                    338:        /* Set proper disk type, only allow one type */
                    339:        return 0;
                    340: }
                    341: 
                    342: fdclose(dev, flags)
                    343:        dev_t dev;
                    344: {
1.1.1.2   root      345:        return(0);
1.1       root      346: }
                    347: 
                    348: 
                    349: /****************************************************************************/
                    350: /*                                 fdstart                                  */
                    351: /****************************************************************************/
                    352: fdstart(unit)
                    353: int unit;
                    354: {
                    355:        register struct buf *dp,*bp;
                    356:        int s;
                    357: 
                    358: #ifdef FDTEST
                    359: printf("st%d|",unit);
                    360: #endif 
1.1.1.3 ! root      361:        dp = &fd_unit[unit].head;
        !           362:        bp = dp->b_actf;
1.1       root      363:        s = splbio();
                    364:        if (!fd_unit[unit].motor) {
                    365:                fd_turnon(unit);
1.1.1.3 ! root      366: #ifdef notdef
        !           367:                if ((bp->b_flags & B_READ) == 0) {
        !           368:                        /* Wait for 1 sec */
        !           369: #endif
        !           370:                        timeout(fdstart,unit,hz);
        !           371:                /*}*/
        !           372:        } else
1.1       root      373:                 {
                    374:                /* make sure drive is selected as well as on */
                    375: 
                    376:                fd_retry = 0;
                    377:                if (fd_unit[unit].reset) fd_state = 1;
                    378:                else {
                    379:                        /* DO a RESET */
                    380:                        fd_unit[unit].reset = 1;
                    381:                        fd_state = 5;
                    382:                }
                    383:                fd_skip = 0;
                    384: #ifdef FDDEBUG
                    385: printf("Seek %d %d\n", bp->b_cylin, dp->b_step);
                    386: #endif
                    387:                if (bp->b_cylin != fd_track) {
                    388:                /* Seek necessary, never quite sure where head is at! */
1.1.1.3 ! root      389:                out_fdc(NE7CMD_SEEK);   /* Seek function */
1.1       root      390:                out_fdc(unit);  /* Drive number */
                    391:                out_fdc(bp->b_cylin * dp->b_step);
1.1.1.3 ! root      392:                fd_state = 6;
        !           393:                } else {
        !           394:                fd_state = 1;
        !           395:                fdintr(0xff);
        !           396:                }
1.1       root      397:        }
                    398:        splx(s);
                    399: }
                    400: 
                    401: fd_timeout(x)
                    402: int x;
                    403: {
1.1.1.3 ! root      404:        int st0, st3, cyl;
1.1       root      405:        struct buf *dp,*bp;
                    406: 
                    407:        dp = &fd_unit[fd_drive].head;
                    408:        bp = dp->b_actf;
                    409: 
1.1.1.3 ! root      410:        out_fdc(NE7CMD_SENSED);
        !           411:        out_fdc(fd_hddrv);
        !           412:        st3 = in_fdc();
        !           413: 
        !           414:        out_fdc(NE7CMD_SENSEI);
        !           415:        st0 = in_fdc();
        !           416:        cyl = in_fdc();
        !           417: printf("fd%d: Operation timeout ST0 %b cyl %d ST3 %b\n", fd_drive,
        !           418: st0, NE7_ST0BITS, cyl, st3, NE7_ST3BITS);
1.1       root      419: 
1.1.1.3 ! root      420:        if (bp) {
        !           421:                fd_state = 4;
        !           422:                fdintr(fd_drive);
        !           423:        }
1.1       root      424: }
                    425: 
                    426: /****************************************************************************/
                    427: /*                                 fdintr                                   */
                    428: /****************************************************************************/
                    429: fdintr(unit)
                    430: {
                    431:        register struct buf *dp,*bp;
                    432:        struct buf *dpother;
1.1.1.3 ! root      433:        int read,head,trac,sec,i,s,sectrac,cyl,st0;
1.1       root      434:        unsigned long blknum;
                    435:        struct fd_type *ft;
                    436: 
                    437: #ifdef FDTEST
                    438:        printf("state %d, unit %d, dr %d|",fd_state,unit,fd_drive);
                    439: #endif
                    440: 
1.1.1.3 ! root      441:        if (!fdopenf) return;
1.1       root      442:        dp = &fd_unit[fd_drive].head;
                    443:        bp = dp->b_actf;
                    444:        read = bp->b_flags & B_READ;
1.1.1.3 ! root      445:        /*ft = &fd_types[FDTYPE(bp->b_dev)];*/
        !           446:        ft = &fd_types[fd_unit[fd_drive].type];
1.1       root      447: 
                    448:        switch (fd_state) {
                    449:        case 1 : /* SEEK DONE, START DMA */
                    450:                /* Make sure seek really happened*/
                    451:                if (unit != 0xff) {
1.1.1.3 ! root      452:                        int descyl = bp->b_cylin * dp->b_step;
        !           453:                        out_fdc(NE7CMD_SENSEI);
1.1       root      454:                        i = in_fdc();
                    455:                        cyl = in_fdc();
1.1.1.3 ! root      456:                        if (cyl != descyl) {
        !           457: printf("fd%d: Seek to cyl %d failed; am at cyl %d (ST0 = %b)\n", fd_drive,
        !           458: descyl, cyl, i, NE7_ST0BITS);
        !           459: fd_state = 4;
1.1       root      460:                                return;
                    461:                        }
                    462:                }
                    463: 
                    464:                fd_track = bp->b_cylin;
1.1.1.3 ! root      465:                isa_dmastart(bp->b_flags, bp->b_un.b_addr+fd_skip,
        !           466:                        FDBLK, fd_dmachan);
1.1       root      467:                blknum = (unsigned long)bp->b_blkno*DEV_BSIZE/FDBLK
                    468:                        + fd_skip/FDBLK;
                    469:                sectrac = ft->sectrac;
                    470:                sec = blknum %  (sectrac * 2);
                    471:                head = sec / sectrac;
                    472:                sec = sec % sectrac + 1;
1.1.1.3 ! root      473: fd_hddrv = ((head&1)<<2)+fd_drive;
1.1       root      474: 
1.1.1.3 ! root      475:                if (read)  out_fdc(NE7CMD_READ);        /* READ */
        !           476:                else out_fdc(NE7CMD_WRITE);             /* WRITE */
1.1       root      477:                out_fdc(head << 2 | fd_drive);  /* head & unit */
                    478:                out_fdc(fd_track);              /* track */
                    479:                out_fdc(head);
                    480:                out_fdc(sec);                   /* sector XXX +1? */
                    481:                out_fdc(ft->secsize);           /* sector size */
                    482:                out_fdc(sectrac);               /* sectors/track */
                    483:                out_fdc(ft->gap);               /* gap size */
                    484:                out_fdc(ft->datalen);           /* data length */
                    485:                fd_state = 2;
                    486:                break;
                    487:        case 2 : /* IO DONE, post-analyze */
                    488:                untimeout(fd_timeout,2);
                    489:                for(i=0;i<7;i++) {
                    490:                        fd_status[i] = in_fdc();
                    491:                }
                    492:                if (fd_status[0]&0xF8) {
                    493: #ifdef FDOTHER
                    494: printf("status0 err %d:",fd_status[0]);
                    495: #endif
                    496:                        goto retry;
                    497:                }
                    498:                /* All OK */
1.1.1.3 ! root      499:                isa_dmadone(bp->b_flags, bp->b_un.b_addr+fd_skip,
        !           500:                        FDBLK, fd_dmachan);
1.1       root      501:                fd_skip += FDBLK;
                    502:                if (fd_skip >= bp->b_bcount) {
                    503: #ifdef FDTEST
                    504: printf("DONE %d|", bp->b_blkno);
                    505: #endif
                    506:                        /* ALL DONE */
                    507:                        fd_skip = 0;
                    508:                        bp->b_resid = 0;
                    509:                        dp->b_actf = bp->av_forw;
                    510:                        biodone(bp);
                    511:                        nextstate(dp);
                    512: 
                    513:                } else {
                    514: #ifdef FDDEBUG
                    515: printf("next|");
                    516: #endif
                    517:                        /* set up next transfer */
                    518:                        blknum = (unsigned long)bp->b_blkno*DEV_BSIZE/FDBLK
                    519:                                + fd_skip/FDBLK;
                    520:                        fd_state = 1;
                    521:                        bp->b_cylin = (blknum / (ft->sectrac * 2));
                    522:                        if (bp->b_cylin != fd_track) {
                    523: #ifdef FDTEST
                    524: printf("Seek|");
                    525: #endif
                    526:                                /* SEEK Necessary */
1.1.1.3 ! root      527:                                out_fdc(NE7CMD_SEEK);   /* Seek function */
1.1       root      528:                                out_fdc(fd_drive);/* Drive number */
                    529:                                out_fdc(bp->b_cylin * dp->b_step);
1.1.1.3 ! root      530:                        fd_state = 6;
1.1       root      531:                                break;
                    532:                        } else fdintr(0xff);
                    533:                }
                    534:                break;
                    535:        case 3:
1.1.1.3 ! root      536:                out_fdc(NE7CMD_SENSEI);
        !           537:                st0 = in_fdc();
        !           538:                cyl = in_fdc();
        !           539:                if (cyl != 0)
        !           540:                        printf("fd%d: recal failed ST0 %b cyl %d\n", fd_drive,
        !           541:                                st0, NE7_ST0BITS, cyl);
        !           542: 
1.1       root      543:                /* Seek necessary */
1.1.1.3 ! root      544:                out_fdc(NE7CMD_SEEK);   /* Seek function */
1.1       root      545:                out_fdc(fd_drive);/* Drive number */
                    546:                out_fdc(bp->b_cylin * dp->b_step);
1.1.1.3 ! root      547:                fd_state = 6;
1.1       root      548:                break;
                    549:        case 4:
1.1.1.3 ! root      550:                out_fdc(NE7CMD_SPECIFY); /* specify command */
1.1       root      551:                out_fdc(0xDF);
                    552:                out_fdc(2);
1.1.1.3 ! root      553:                out_fdc(NE7CMD_RECAL);  /* Recalibrate Function */
1.1       root      554:                out_fdc(fd_drive);
1.1.1.3 ! root      555:                fd_state = 7;
1.1       root      556:                break;
                    557:        case 5:
                    558: #ifdef FDOTHER
                    559:                printf("**RESET**\n");
                    560: #endif
                    561:                /* Try a reset, keep motor on */
                    562:                set_motor(fd_drive,1);
1.1.1.3 ! root      563:                DELAY(100);
1.1       root      564:                set_motor(fd_drive,0);
                    565:                outb(fdc+fdctl,ft->trans);
                    566:                fd_retry++;
                    567:                fd_state = 4;
                    568:                break;
1.1.1.3 ! root      569:        case 6:
        !           570:                /* allow heads to settle */
        !           571:                timeout(fdintr,fd_drive,hz/30);
        !           572:                fd_state = 1;
        !           573:                return;
        !           574:                break;
        !           575:                
        !           576:        case 7:
        !           577:                /* allow heads to settle */
        !           578:                timeout(fdintr,fd_drive,hz/3);
        !           579:                fd_state = 3;
        !           580:                return;
        !           581:                break;
        !           582:                
1.1       root      583:        default:
                    584:                printf("Unexpected FD int->");
1.1.1.3 ! root      585:                out_fdc(NE7CMD_SENSEI);
        !           586:                st0 = in_fdc();
        !           587:                cyl = in_fdc();
1.1       root      588:                printf("ST0 = %lx, PCN = %lx\n",i,sec);
                    589:                out_fdc(0x4A); 
                    590:                out_fdc(fd_drive);
                    591:                for(i=0;i<7;i++) {
                    592:                        fd_status[i] = in_fdc();
                    593:                }
                    594:        printf("intr status :%lx %lx %lx %lx %lx %lx %lx ",
                    595:                fd_status[0], fd_status[1], fd_status[2], fd_status[3],
                    596:                fd_status[4], fd_status[5], fd_status[6] );
                    597:                break;
                    598:        }
                    599:        return;
                    600: retry:
                    601:        switch(fd_retry) {
                    602:        case 0: case 1:
1.1.1.3 ! root      603:        case 2:
1.1       root      604:                break;
1.1.1.3 ! root      605:        case 3:
1.1       root      606:        case 4:
1.1.1.3 ! root      607:        case 5:
        !           608:                fd_retry++;
        !           609:                fd_state = 4;
        !           610:                fdintr(0xff);
        !           611:                return;
        !           612:        case 6:
1.1       root      613:                fd_retry++;
                    614:                fd_state = 5;
                    615:                fdintr(0xff);
                    616:                return;
1.1.1.3 ! root      617:        case 7:
1.1       root      618:                break;
                    619:        default:
1.1.1.3 ! root      620: /*printf("fd%d: hard error (ST0 %b ST1 %b ST2 %b ST3 %b cyl %d hd %d sec %d)\n",
        !           621:                fd_drive, fd_status[0], NE7_ST0BITS, fd_status[1], NE7_ST1BITS,
        !           622:                fd_status[2], NE7_ST2BITS,  fd_status[3], NE7_ST3BITS, 
        !           623:                fd_status[4], fd_status[5], fd_status[6]);*/
        !           624: printf("fd%d: hard error (ST0 %b ", fd_drive, fd_status[0], NE7_ST0BITS);
        !           625: printf(" ST1 %b ", fd_status[1], NE7_ST1BITS);
        !           626: printf(" ST2 %b ", fd_status[2], NE7_ST2BITS);
        !           627: printf(" ST3 %b ", fd_status[3], NE7_ST3BITS);
        !           628: printf("cyl %d hd %d sec %d)\n", fd_status[4], fd_status[5], fd_status[6]);
1.1       root      629:                badtrans(dp,bp);
                    630:                return;
                    631:        }
                    632:        fd_state = 1;
                    633:        fd_retry++;
                    634:        fdintr(0xff);
                    635: }
                    636: 
                    637: badtrans(dp,bp)
                    638: struct buf *dp,*bp;
                    639: {
                    640: 
                    641:        bp->b_flags |= B_ERROR;
                    642:        bp->b_error = EIO;
                    643:        bp->b_resid = bp->b_bcount - fd_skip;
                    644:        dp->b_actf = bp->av_forw;
                    645:        fd_skip = 0;
                    646:        biodone(bp);
                    647:        nextstate(dp);
                    648: 
                    649: }
                    650: 
                    651: /*
                    652:        nextstate : After a transfer is done, continue processing
                    653:        requests on the current drive queue.  If empty, go to
                    654:        the other drives queue.  If that is empty too, timeout
                    655:        to turn off the current drive in 5 seconds, and go
                    656:        to state 0 (not expecting any interrupts).
                    657: */
                    658: 
                    659: nextstate(dp)
                    660: struct buf *dp;
                    661: {
                    662:        struct buf *dpother;
                    663:        
                    664:        if (dp->b_actf) fdstart(fd_drive);
1.1.1.3 ! root      665:        else {
1.1       root      666:                untimeout(fd_turnoff,fd_drive);
1.1.1.3 ! root      667:                timeout(fd_turnoff,fd_drive,hz);
1.1       root      668:                fd_state = 0;
                    669:                dp->b_active = 0;
                    670:        }
                    671: }
                    672: #endif

unix.superglobalmegacorp.com

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