Annotation of Gnu-Mach/i386/i386at/fd.c, revision 1.1

1.1     ! root        1: /* 
        !             2:  * Mach Operating System
        !             3:  * Copyright (c) 1993,1991,1990,1989 Carnegie Mellon University
        !             4:  * All Rights Reserved.
        !             5:  * 
        !             6:  * Permission to use, copy, modify and distribute this software and its
        !             7:  * documentation is hereby granted, provided that both the copyright
        !             8:  * notice and this permission notice appear in all copies of the
        !             9:  * software, derivative works or modified versions, and any portions
        !            10:  * thereof, and that both notices appear in supporting documentation.
        !            11:  * 
        !            12:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
        !            13:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
        !            14:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
        !            15:  * 
        !            16:  * Carnegie Mellon requests users of this software to return to
        !            17:  * 
        !            18:  *  Software Distribution Coordinator  or  [email protected]
        !            19:  *  School of Computer Science
        !            20:  *  Carnegie Mellon University
        !            21:  *  Pittsburgh PA 15213-3890
        !            22:  * 
        !            23:  * any improvements or extensions that they make and grant Carnegie Mellon
        !            24:  * the rights to redistribute these changes.
        !            25:  */
        !            26: /*
        !            27:   Copyright 1988, 1989 by Intel Corporation, Santa Clara, California.
        !            28: 
        !            29:                All Rights Reserved
        !            30: 
        !            31: Permission to use, copy, modify, and distribute this software and
        !            32: its documentation for any purpose and without fee is hereby
        !            33: granted, provided that the above copyright notice appears in all
        !            34: copies and that both the copyright notice and this permission notice
        !            35: appear in supporting documentation, and that the name of Intel
        !            36: not be used in advertising or publicity pertaining to distribution
        !            37: of the software without specific, written prior permission.
        !            38: 
        !            39: INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
        !            40: INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
        !            41: IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
        !            42: CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
        !            43: LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
        !            44: NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
        !            45: WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
        !            46: */
        !            47: 
        !            48: /*     Copyright (c) 1987, 1988 TOSHIBA Corp.          */
        !            49: /*             All Rights Reserved                     */
        !            50: 
        !            51: #if 0
        !            52: 
        !            53: #include <fd.h>
        !            54: 
        !            55: #ifdef MACH_KERNEL
        !            56: #include <sys/types.h>
        !            57: #include <sys/ioctl.h>
        !            58: #include <device/buf.h>
        !            59: #include <device/errno.h>
        !            60: #else  MACH_KERNEL
        !            61: #include <sys/buf.h>
        !            62: #include <sys/errno.h>
        !            63: #include <sys/user.h>
        !            64: #include <sys/ioctl.h>
        !            65: #endif MACH_KERNEL
        !            66: #include <i386/pio.h>
        !            67: #include <i386/machspl.h>
        !            68: #include <chips/busses.h>
        !            69: #include <i386at/fdreg.h>
        !            70: #include <i386at/disk.h>
        !            71: #include <vm/vm_kern.h>
        !            72: 
        !            73: #ifdef DEBUG
        !            74: #define D(x) x
        !            75: #define DD(x) x
        !            76: #else  /* DEBUG */
        !            77: #define D(x)
        !            78: #define DD(x)
        !            79: #endif /* DEBUG */
        !            80: 
        !            81: /*
        !            82:  * Floppy Device-Table Definitions (drtabs)
        !            83:  *
        !            84:  *      Cyls,Sec,spc,part,Mtype,RWFpl,FGpl
        !            85:  */
        !            86: struct fddrtab m765f[] = {                     /* format table */
        !            87:        80, 18, 1440,  9, 0x88, 0x2a, 0x50,     /* [0] 3.50" 720  Kb  */
        !            88:        80, 36, 2880, 18, 0x08, 0x1b, 0x6c,     /* [1] 3.50" 1.44 Meg */
        !            89:        40, 18,  720,  9, 0xa8, 0x2a, 0x50,     /* [2] 5.25" 360  Kb  */
        !            90:        80, 30, 2400, 15, 0x08, 0x1b, 0x54      /* [3] 5.25" 1.20 Meg */
        !            91: };
        !            92: 
        !            93: /*
        !            94:  * The following are static initialization variables
        !            95:  * which are based on the configuration.
        !            96:  */
        !            97: struct ctrl_info ctrl_info[MAXUNIT>>1] = {             /* device data table */
        !            98:        {  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ,
        !            99:        {  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
        !           100: };
        !           101: 
        !           102: struct unit_info unit_info[MAXUNIT];           /* unit buffer headers  */
        !           103: 
        !           104: char *fderr = "FD Error on unit";
        !           105: char *fdmsg[] = {
        !           106:        "?",
        !           107:        "Missing data address mark",
        !           108:        "Write protected",
        !           109:        "Sector not found",
        !           110:        "Data Overrun",                         /* Over run error */
        !           111:        "Uncorrectable data read error",        /* CRC Error */
        !           112:        "FDC Error",
        !           113:        "Illegal format type",
        !           114:        "Drive not ready",
        !           115:        "diskette not present - please insert",
        !           116:        "Illegal interrupt type"
        !           117: };
        !           118: 
        !           119: struct buf     fdrbuf[MAXUNIT];        /* data transfer buffer structures */
        !           120: 
        !           121: int    fdminphys();
        !           122: int    fdintr(), fdprobe(), fdslave();
        !           123: void   fdattach();
        !           124: int    FdDmaEISA = 0;
        !           125: int    FdDmaThreshold = 16 * 1024 * 1024;
        !           126: vm_offset_t    FdDmaPage = (vm_offset_t) 0;
        !           127: vm_offset_t    fd_std[NFD] = { 0 };
        !           128: struct bus_device *fd_dinfo[NFD*2];
        !           129: struct bus_ctlr *fd_minfo[NFD];
        !           130: struct bus_driver      fddriver = 
        !           131:        {fdprobe, fdslave, fdattach, 0, fd_std, "fd", fd_dinfo, "fdc", fd_minfo, 0};
        !           132: 
        !           133: int    m765verify[MAXUNIT] = {1,1,1,1};        /* write after read flag */
        !           134:                                                /* 0 != verify mode     */ 
        !           135:                                                /* 0 == not verify mode */
        !           136: #ifdef MACH_KERNEL
        !           137: extern struct buf *geteblk();
        !           138: #endif MACH_KERNEL
        !           139: 
        !           140: #define trfrate(uip, type)   outb(VFOREG(uip->addr),(((type)&RATEMASK)>>6))
        !           141: #define rbskrate(uip, type)  trfrate(uip,(type)&RAPID?RPSEEK:NMSEEK)
        !           142: #define getparm(type)   ((type<0||type>3)?(struct fddrtab *)ERROR:&m765f[type])
        !           143: #define relative(s1,s2) ((s1)>(s2)?(s1)-(s2):(s2)-(s1))
        !           144: 
        !           145: fdprobe(port, ctlr)
        !           146: struct bus_ctlr *ctlr;
        !           147: {
        !           148:        int                     spot = STSREG((int) ctlr->address);
        !           149:        struct ctrl_info        *cip = &ctrl_info[ctlr->unit];
        !           150:        int                     i, in;
        !           151: 
        !           152:        outb(spot, DATAOK);
        !           153:        for (i = 1000; i--;) {
        !           154:                in = inb(spot);
        !           155:                if ((in&DATAOK) == DATAOK && !(in&0x0f)) {
        !           156:                        take_ctlr_irq(ctlr);
        !           157:                        cip->b_cmd.c_rbmtr = 0;         /* recalibrate/moter flag */
        !           158:                        cip->b_cmd.c_intr = CMDRST;     /* interrupt flag */
        !           159:                        cip->b_unitf = 0;
        !           160:                        cip->b_uip = 0;
        !           161:                        cip->b_rwerr = cip->b_seekerr = cip->b_rberr = 0;
        !           162:                        cip->usebuf = 0;
        !           163:                        if (FdDmaPage) {
        !           164:                                cip->b_pbuf = FdDmaPage + PAGE_SIZE * ctlr->unit;
        !           165:                                if (kmem_alloc_pageable(kernel_map,
        !           166:                                               (vm_offset_t *)&cip->b_vbuf,
        !           167:                                               PAGE_SIZE) != KERN_SUCCESS) {
        !           168:                                        printf("%s%d: can not kmem_alloc_pageable.\n",
        !           169:                                                ctlr->name, ctlr->unit);
        !           170:                                        return 0;
        !           171:                                }
        !           172:                                (void)pmap_map(cip->b_vbuf,
        !           173:                                               (vm_offset_t)cip->b_pbuf, 
        !           174:                                               (vm_offset_t)cip->b_pbuf+PAGE_SIZE,
        !           175:                                               VM_PROT_READ | VM_PROT_WRITE);
        !           176:                        }
        !           177:                        printf("%s%d: port = %x, spl = %d, pic = %d.\n", ctlr->name,
        !           178:                                ctlr->unit, ctlr->address, ctlr->sysdep, ctlr->sysdep1);
        !           179:                        return(1);
        !           180:                }
        !           181:        }
        !           182:        return(0);
        !           183: }
        !           184: 
        !           185: fdslave(dev, xxxx)
        !           186: struct bus_device              *dev;
        !           187: {
        !           188:        return(1);      /* gross hack */
        !           189: }
        !           190: 
        !           191: void fdattach(dev)
        !           192: struct bus_device *dev;
        !           193: {
        !           194:        struct unit_info        *uip = &unit_info[dev->unit];
        !           195:        struct ctrl_info        *cip = &ctrl_info[dev->ctlr];
        !           196: 
        !           197:        uip->dev = dev;
        !           198:        dev->address = dev->mi->address;
        !           199:        uip->addr = dev->address;
        !           200:        uip->b_cmd = &cip->b_cmd;
        !           201:        uip->b_seekaddr = 0;
        !           202:        uip->av_forw = 0;
        !           203:        uip->wakeme = 0;
        !           204:        if (cip->b_unitf) {
        !           205:                uip->b_unitf=cip->b_unitf->b_unitf;
        !           206:                cip->b_unitf->b_unitf=uip;
        !           207:        } else {
        !           208:                uip->b_unitf=uip;
        !           209:                cip->b_unitf=uip;
        !           210:        }
        !           211:        uip->d_drtab.dr_type &= ~OKTYPE; 
        !           212: 
        !           213:        printf(", port = %x, spl = %d, pic = %d.",
        !           214:                dev->address, dev->sysdep, dev->sysdep1);
        !           215: 
        !           216:        rstout(uip);
        !           217:        specify(uip);
        !           218: }
        !           219: /*****************************************************************************
        !           220:  *
        !           221:  * TITLE:      fdopen
        !           222:  *
        !           223:  * ABSTRACT:   Open a unit. 
        !           224:  *
        !           225:  ****************************************************************************/
        !           226: fdopen(dev, flag, otyp)
        !           227: dev_t  dev;
        !           228: int    flag;                   /* not used */
        !           229: int    otyp;                   /* not used */
        !           230: {
        !           231:        struct fddrtab          *driv;
        !           232:        struct buf              *wbp;
        !           233:        spl_t                   x = SPL();
        !           234:        int                     error = 0;
        !           235:        int                     unit = UNIT(dev);
        !           236:        struct unit_info        *uip = &unit_info[unit];
        !           237:        int                     slave = uip->dev->slave;
        !           238:        struct ctrl_info        *cip = &ctrl_info[uip->dev->ctlr];
        !           239:        struct  fdcmd           *cmdp = uip->b_cmd;
        !           240:        if (unit < MAXUNIT){
        !           241:          /* Since all functions that use this are called from open, we only
        !           242:             set this once, right here. */
        !           243:                rstout(uip);
        !           244:                cip->b_wup = uip;
        !           245:                openchk(cmdp);
        !           246:                cmdp->c_devflag |= FDMCHK;
        !           247:                chkbusy(cmdp);
        !           248:                cmdp->c_stsflag |= MTRFLAG;
        !           249:                mtr_on(uip);
        !           250:                if(inb(VFOREG(uip->addr))&OPENBIT || 
        !           251:                   !(uip->d_drtab.dr_type&OKTYPE)){
        !           252:                        uip->d_drtab.dr_type &= ~OKTYPE;
        !           253:                        if(!rbrate(RAPID, uip))
        !           254:                                fdseek(RAPID, uip, 2);
        !           255:                        if(inb(VFOREG(uip->addr))&OPENBIT)
        !           256:                                error = ENXIO;
        !           257:                }
        !           258:                cmdp->c_stsflag &= ~MTRFLAG;
        !           259:                mtr_on(uip);
        !           260:                openfre(cmdp);
        !           261:                if(!error && !(uip->d_drtab.dr_type & OKTYPE)) {
        !           262:                        if (MEDIATYPE(dev)>3)
        !           263:                                goto endopen;
        !           264:                        driv = &m765f[MEDIATYPE(dev)];
        !           265:                        wbp = geteblk(BLKSIZE);
        !           266:                        m765sweep(uip, driv);
        !           267:                        cmdp->c_rbmtr &= ~(1<<(RBSHIFT+(slave)));
        !           268:                        ++cip->b_rwerr;
        !           269:                        wbp->b_dev = dev; wbp->b_error = 0; wbp->b_resid = 0;
        !           270:                        wbp->b_flags = (B_READ|B_VERIFY); wbp->b_bcount = 512;
        !           271:                        wbp->b_pfcent = 2*driv->dr_spc + driv->dr_nsec - 1;
        !           272:                        setqueue(wbp, uip);
        !           273:                        biowait(wbp);
        !           274:                        brelse(wbp);
        !           275:                        error = 0;
        !           276:                        uip->d_drtab.dr_type |= OKTYPE;
        !           277:                }
        !           278:        } else
        !           279:                error = ENXIO;
        !           280:       endopen:
        !           281:        splx(x);
        !           282:        return(error);
        !           283: }
        !           284: /*****************************************************************************
        !           285:  *
        !           286:  * TITLE:      fdclose
        !           287:  *
        !           288:  * ABSTRACT:   Close a unit.
        !           289:  *
        !           290:  *     Called on last close. mark the unit closed and not-ready.
        !           291:  *
        !           292:  *     Unix doesn't actually "open" an inode for rootdev, swapdev or pipedev.
        !           293:  *     If UNIT(swapdev) != UNIT(rootdev), then must add code in init() to 
        !           294:  *     "open" swapdev.  These  devices should never be closed.
        !           295:  *
        !           296:  *****************************************************************************/
        !           297: fdclose(dev, flag, otyp, offset)
        !           298: dev_t  dev;            /* major, minor numbers */
        !           299: int    flag;           /* not used */
        !           300: int    otyp;           /* not used */
        !           301: off_t  offset;         /* not used */
        !           302: {
        !           303:        extern                  dev_t   rootdev, swapdev;
        !           304:        struct unit_info        *uip = &unit_info[UNIT(dev)];
        !           305:        spl_t s;
        !           306: 
        !           307: #ifdef MACH_KERNEL
        !           308: #else  MACH_KERNEL
        !           309:        if ((dev == rootdev) || (dev == swapdev))  /* never close these */
        !           310:                return(0);
        !           311: #endif MACH_KERNEL
        !           312: 
        !           313:        /* Clear the bit.
        !           314:         * If last close of drive insure drtab queue is empty before returning.
        !           315:         */
        !           316:        s = SPL();
        !           317:        while(uip->av_forw != 0) {
        !           318:                uip->wakeme = 1;
        !           319:                sleep(uip, PRIBIO);
        !           320:        }
        !           321:        splx(s);
        !           322: #ifdef MACH_KERNEL
        !           323:        return(0);
        !           324: #else  MACH_KERNEL
        !           325:        close(0);
        !           326: #endif MACH_KERNEL
        !           327: }
        !           328: /*****************************************************************************
        !           329:  *
        !           330:  * TITLE:      fdstrategy
        !           331:  *
        !           332:  * ABSTRACT:   Queue an I/O Request, and start it if not busy already.
        !           333:  *
        !           334:  *     Reject request if unit is not-ready.
        !           335:  *
        !           336:  *     Note:   check for not-ready done here ==> could get requests
        !           337:  *             queued prior to unit going not-ready.
        !           338:  *             not-ready status to those requests that are attempted
        !           339:  *             before a new volume is inserted.  Once a new volume is
        !           340:  *             inserted, would get good I/O's to wrong volume.
        !           341:  *
        !           342:  * CALLS:      iodone(),setqueue()
        !           343:  *
        !           344:  * CALLING ROUTINES:   fdread (indirectly, thru physio)
        !           345:  *                     fdwrite (indirectly, thru physio)
        !           346:  *
        !           347:  ****************************************************************************/
        !           348: fdstrategy(bp)
        !           349: struct buf *bp;        /* buffer header */
        !           350: {
        !           351:        unsigned                bytes_left;
        !           352:        daddr_t                 secno;
        !           353:        struct unit_info        *uip = &unit_info[UNIT(bp->b_dev)];
        !           354:        struct fddrtab          *dr = &uip->d_drtab;
        !           355:        struct fddrtab          *sdr;
        !           356: 
        !           357:        bp->b_error = 0;
        !           358:        /* set b_resid to b_bcount because we haven't done anything yet */
        !           359:        bp->b_resid = bp->b_bcount;
        !           360:        if (!(dr->dr_type & OKTYPE) || 
        !           361:            ((sdr = getparm(MEDIATYPE(bp->b_dev)))==(struct fddrtab *)ERROR) ||
        !           362:            /* wrong parameters */
        !           363:            (sdr->dr_ncyl != dr->dr_ncyl) || (sdr->dr_nsec != dr->dr_nsec) ||
        !           364:            ((sdr->dr_type|OKTYPE) != dr->dr_type) ||
        !           365:            (sdr->dr_rwgpl != dr->dr_rwgpl) ||
        !           366:            (sdr->dr_fgpl != dr->dr_fgpl)) {
        !           367:                bp->b_flags |= B_ERROR;
        !           368:                bp->b_error = EIO;
        !           369:                biodone(bp);
        !           370:                return(0);
        !           371:        }
        !           372:        /*
        !           373:         * Figure "secno" from b_blkno. Adjust sector # for partition.
        !           374:         *
        !           375:         * If reading just past the end of the device, it's
        !           376:         * End of File.  If not reading, or if read starts further in
        !           377:         * than the first sector after the partition, it's an error.
        !           378:         *
        !           379:         * secno is logical blockno / # of logical blocks per sector */
        !           380:        secno = (bp->b_blkno * NBPSCTR) >> 9;
        !           381:        if (secno >= dr->p_nsec) {
        !           382:                if (!((bp->b_flags & B_READ) && (secno == dr->p_nsec))){
        !           383:                        /* off the deep end */
        !           384:                        bp->b_flags |= B_ERROR;
        !           385:                        bp->b_error = ENXIO;
        !           386:                }
        !           387:                biodone(bp);
        !           388:                return(0);
        !           389:        }
        !           390: /* At this point, it is no longer possible to directly return from strategy.
        !           391:    We now set b_resid to the number of bytes we cannot transfer because
        !           392:    they lie beyond the end of the request's partition.  This value is 0
        !           393:    if the entire request is within the partition. */
        !           394:        bytes_left = (dr->p_nsec - secno) << 9;
        !           395:        bp->b_resid = ((bp->b_bcount<=bytes_left)?0:(bp->b_bcount-bytes_left));
        !           396:        bp->b_pfcent = secno;
        !           397:        setqueue(bp, uip);
        !           398:        return(0);
        !           399: }
        !           400: 
        !           401: /***************************************************************************
        !           402:  *
        !           403:  *     set queue to buffer
        !           404:  *
        !           405:  ***************************************************************************/
        !           406: setqueue(bp, uip)
        !           407: struct buf *bp;
        !           408: struct unit_info *uip;
        !           409: {
        !           410:        spl_t                   x = SPL();
        !           411:        struct ctrl_info        *cip = &ctrl_info[uip->dev->ctlr];
        !           412:        struct  fdcmd           *cmdp = uip->b_cmd;
        !           413: 
        !           414:        openchk(cmdp);          /* openning check */
        !           415:        cmdp->c_devflag |= STRCHK;
        !           416:        fd_disksort(uip, bp);   /* queue the request */
        !           417:        /*
        !           418:         * If no requests are in progress, start this one up.  Else
        !           419:         * leave it on the queue, and fdintr will call m765io later.
        !           420:         */
        !           421:        if(!cip->b_uip)
        !           422:                m765io(uip);
        !           423:        splx(x);
        !           424: }
        !           425: /***************************************************************************
        !           426:  *
        !           427:  *     check io_busy routine
        !           428:  *
        !           429:  ***************************************************************************/
        !           430: chkbusy(cmdp)
        !           431: struct fdcmd   *cmdp;
        !           432: {
        !           433:        while(cmdp->c_devflag & STRCHK){
        !           434:                cmdp->c_devflag |= STRWAIT;
        !           435:                sleep(&cmdp->c_devflag,PZERO);
        !           436:        } 
        !           437: }
        !           438: /***************************************************************************
        !           439:  *
        !           440:  *     check fdopen() routine
        !           441:  *
        !           442:  ***************************************************************************/
        !           443: openchk(cmdp)
        !           444: struct fdcmd   *cmdp;
        !           445: {
        !           446:        while(cmdp->c_devflag & FDMCHK ){
        !           447:                cmdp->c_devflag |= FDWAIT;
        !           448:                sleep(&cmdp->c_devflag,PZERO);
        !           449:        } 
        !           450: }
        !           451: /***************************************************************************
        !           452:  *
        !           453:  *     free fdopen() routine
        !           454:  *
        !           455:  ***************************************************************************/
        !           456: openfre(cmdp)
        !           457: struct fdcmd   *cmdp;
        !           458: {
        !           459:        cmdp->c_devflag &= ~FDMCHK;
        !           460:        if(cmdp->c_devflag & FDWAIT){
        !           461:                cmdp->c_devflag &= ~FDWAIT;
        !           462:                wakeup(&cmdp->c_devflag);
        !           463:        }
        !           464: }
        !           465: /*****************************************************************************
        !           466:  *
        !           467:  * TITLE:      m765io
        !           468:  *
        !           469:  * ABSTRACT:   Start handling an I/O request.
        !           470:  *
        !           471:  ****************************************************************************/
        !           472: m765io(uip)
        !           473: struct unit_info *uip;
        !           474: {
        !           475:        extern int(m765iosub)();
        !           476:        register struct buf *bp;
        !           477:        struct ctrl_info *cip = &ctrl_info[uip->dev->ctlr];
        !           478: 
        !           479:        bp = uip->av_forw; /*move bp to ctrl_info[ctrl].b_buf*/
        !           480:        cip->b_buf = bp;
        !           481:        cip->b_uip = uip;
        !           482:        cip->b_xferaddr  = bp->b_un.b_addr;
        !           483:        cip->b_xfercount = bp->b_bcount - bp->b_resid;
        !           484:        cip->b_sector    = bp->b_pfcent;
        !           485:        uip->b_cmd->c_stsflag |= MTRFLAG;
        !           486:        if(!mtr_start(uip))
        !           487:                timeout(m765iosub, uip, HZ);
        !           488:        else
        !           489:                m765iosub(uip);
        !           490: }
        !           491: /****************************************************************************
        !           492:  *
        !           493:  *     m765io subroutine
        !           494:  *
        !           495:  ****************************************************************************/
        !           496: m765iosub(uip)
        !           497: struct unit_info *uip;
        !           498: {
        !           499:        struct fddrtab          *dr = &uip->d_drtab;
        !           500:        int                     startsec;
        !           501:        int                     slave = uip->dev->slave;
        !           502:        struct ctrl_info        *cip = &ctrl_info[uip->dev->ctlr];
        !           503:        struct  fdcmd           *cmdp = uip->b_cmd;
        !           504: 
        !           505:        rwcmdset(uip);
        !           506:        if(cip->b_buf->b_flags&B_FORMAT)
        !           507:                goto skipchk;
        !           508:        startsec = (cmdp->c_rwdata[3] * dr->dr_nsec) + cmdp->c_rwdata[4];
        !           509:        if(startsec+(cip->b_xfercount>>9)-1 > dr->dr_spc)
        !           510:                cip->b_xferdma = (dr->dr_spc-startsec+1) << 9;
        !           511:        else
        !           512: skipchk:       cip->b_xferdma = cip->b_xfercount;
        !           513:        if(!(cmdp->c_rbmtr & (1<<(RBSHIFT+slave))))
        !           514:                        cip->b_status = rbirate(uip);
        !           515:        else if(uip->b_seekaddr != cmdp->c_saddr)
        !           516:                cip->b_status = fdiseek(uip,cmdp->c_saddr);
        !           517:        else
        !           518:                cip->b_status = outicmd(uip);
        !           519:        if(cip->b_status)
        !           520:                intrerr0(uip);
        !           521:        return;
        !           522: }
        !           523: /***************************************************************************
        !           524:  *
        !           525:  *     read / write / format / verify command set to command table
        !           526:  *
        !           527:  ***************************************************************************/
        !           528: rwcmdset(uip)
        !           529: struct unit_info *uip;
        !           530: {
        !           531:        short                   resid;
        !           532:        int                     slave = uip->dev->slave;
        !           533:        struct ctrl_info        *cip = &ctrl_info[uip->dev->ctlr];
        !           534:        struct fdcmd            *cmdp = uip->b_cmd;
        !           535: 
        !           536:        switch(cip->b_buf->b_flags&(B_FORMAT|B_VERIFY|B_READ|B_WRITE)){
        !           537:        case B_VERIFY|B_WRITE:  /* VERIFY after WRITE */
        !           538:                cmdp->c_rwdata[0] = RDMV;
        !           539:                break;
        !           540:        case B_FORMAT:
        !           541:                cmdp->c_dcount = FMTCNT; 
        !           542:                cmdp->c_rwdata[0] = FMTM;
        !           543:                cmdp->c_saddr = cip->b_sector / uip->d_drtab.dr_spc;
        !           544:                resid = cip->b_sector % uip->d_drtab.dr_spc;
        !           545:                cmdp->c_rwdata[1] = slave|((resid/uip->d_drtab.dr_nsec)<<2);
        !           546:                cmdp->c_rwdata[2] = 
        !           547:                        ((struct fmttbl *)cip->b_buf->b_un.b_addr)->s_type;
        !           548:                cmdp->c_rwdata[3] = uip->d_drtab.dr_nsec;
        !           549:                cmdp->c_rwdata[4] = uip->d_drtab.dr_fgpl;
        !           550:                cmdp->c_rwdata[5] = FMTDATA;
        !           551:                break;
        !           552:        case B_WRITE:
        !           553:        case B_READ:
        !           554:        case B_READ|B_VERIFY:
        !           555:                cmdp->c_dcount = RWCNT;
        !           556:                if(cip->b_buf->b_flags&B_READ)
        !           557:                        if(cip->b_buf->b_flags&B_VERIFY)
        !           558:                                cmdp->c_rwdata[0] = RDMV;
        !           559:                        else
        !           560:                                cmdp->c_rwdata[0] = RDM;
        !           561:                else
        !           562:                        cmdp->c_rwdata[0] = WTM;        /* format or write */
        !           563:                resid = cip->b_sector % uip->d_drtab.dr_spc;
        !           564:                cmdp->c_rwdata[3] = resid / uip->d_drtab.dr_nsec;
        !           565:                cmdp->c_rwdata[1] = slave|(cmdp->c_rwdata[3]<<2);
        !           566:                cmdp->c_rwdata[2] = cmdp->c_saddr = 
        !           567:                        cip->b_sector / uip->d_drtab.dr_spc;
        !           568:                cmdp->c_rwdata[4] = (resid % uip->d_drtab.dr_nsec) + 1;
        !           569:                cmdp->c_rwdata[5] = 2;
        !           570:                cmdp->c_rwdata[6] = uip->d_drtab.dr_nsec;
        !           571:                cmdp->c_rwdata[7] = uip->d_drtab.dr_rwgpl;
        !           572:                cmdp->c_rwdata[8] = DTL;
        !           573:                D(printf("SET %x %x C%x H%x S%x %x %x %x %x ",
        !           574:                        cmdp->c_rwdata[0], cmdp->c_rwdata[1],
        !           575:                        cmdp->c_rwdata[2], cmdp->c_rwdata[3],
        !           576:                        cmdp->c_rwdata[4], cmdp->c_rwdata[5],
        !           577:                        cmdp->c_rwdata[6], cmdp->c_rwdata[7],
        !           578:                        cmdp->c_rwdata[8]));
        !           579:                break;
        !           580:        }
        !           581: }
        !           582: /*****************************************************************************
        !           583:  *
        !           584:  * TITLE:      fdread
        !           585:  *
        !           586:  * ABSTRACT:   "Raw" read.  Use physio().
        !           587:  *
        !           588:  * CALLS:      m765breakup (indirectly, thru physio)
        !           589:  *
        !           590:  ****************************************************************************/
        !           591: fdread(dev, uio)
        !           592: register dev_t dev;
        !           593: struct uio *uio;
        !           594: { 
        !           595: #ifdef MACH_KERNEL
        !           596:        /* no need for page-size restriction */
        !           597:        return (block_io(fdstrategy, minphys, uio));
        !           598: #else  MACH_KERNEL
        !           599:        return(physio(fdstrategy,&fdrbuf[UNIT(dev)],dev,B_READ,fdminphys,uio));
        !           600: #endif MACH_KERNEL
        !           601: }
        !           602: /*****************************************************************************
        !           603:  *
        !           604:  * TITLE:      fdwrite
        !           605:  *
        !           606:  * ABSTRACT:   "Raw" write.  Use physio().
        !           607:  *
        !           608:  * CALLS:      m765breakup (indirectly, thru physio)
        !           609:  *
        !           610:  ****************************************************************************/
        !           611: fdwrite(dev, uio)
        !           612: register dev_t dev;
        !           613: struct uio *uio;
        !           614: {
        !           615: #ifdef MACH_KERNEL
        !           616:        /* no need for page-size restriction */
        !           617:        return (block_io(fdstrategy, minphys, uio));
        !           618: #else  MACH_KERNEL
        !           619:        return(physio(fdstrategy,&fdrbuf[UNIT(dev)],dev,B_WRITE,fdminphys,uio));
        !           620: #endif MACH_KERNEL
        !           621: }
        !           622: /*****************************************************************************
        !           623:  *
        !           624:  * TITLE:      fdminphys
        !           625:  *
        !           626:  * ABSTRACT:   Trim buffer length if buffer-size is bigger than page size
        !           627:  *
        !           628:  * CALLS:      physio
        !           629:  *
        !           630:  ****************************************************************************/
        !           631: fdminphys(bp)
        !           632: struct buf     *bp;
        !           633: {
        !           634:        if (bp->b_bcount > PAGESIZ)
        !           635:                bp->b_bcount = PAGESIZ;
        !           636: }
        !           637: #ifdef MACH_KERNEL
        !           638: /* IOC_OUT only and not IOC_INOUT */
        !           639: io_return_t fdgetstat(dev, flavor, data, count)
        !           640:        dev_t           dev;
        !           641:        int             flavor;
        !           642:        int *           data;           /* pointer to OUT array */
        !           643:        unsigned int    *count;         /* OUT */
        !           644: {
        !           645:        switch (flavor) {
        !           646: 
        !           647:        /* Mandatory flavors */
        !           648: 
        !           649:        case DEV_GET_SIZE: {
        !           650:                int ret;
        !           651:                struct disk_parms       p;
        !           652: 
        !           653:                ret = fd_getparms(dev, &p);
        !           654:                if (ret) return ret;
        !           655:                data[DEV_GET_SIZE_DEVICE_SIZE] = p.dp_pnumsec * NBPSCTR;
        !           656:                data[DEV_GET_SIZE_RECORD_SIZE] = NBPSCTR;
        !           657:                *count = DEV_GET_SIZE_COUNT;
        !           658:                break;
        !           659:        }
        !           660: 
        !           661:        /* Extra flavors */
        !           662: 
        !           663:        case V_GETPARMS:
        !           664:                if (*count < sizeof (struct disk_parms)/sizeof (int))
        !           665:                        return (D_INVALID_OPERATION);
        !           666:                *count = sizeof (struct disk_parms)/sizeof(int);
        !           667:                return (fd_getparms(dev, data));
        !           668:         default:
        !           669:                return (D_INVALID_OPERATION);
        !           670:        }
        !           671: }
        !           672: /* IOC_VOID or IOC_IN or IOC_INOUT */
        !           673: /*ARGSUSED*/
        !           674: io_return_t fdsetstat(dev, flavor, data, count)
        !           675:        dev_t           dev;
        !           676:        int             flavor;
        !           677:        int *           data;
        !           678:        unsigned int    count;
        !           679: {
        !           680:        int                     unit = UNIT(dev);
        !           681:        switch (flavor) {
        !           682:        case V_SETPARMS:    /* Caller wants reset_parameters */
        !           683:                return(fd_setparms(unit,*(int *)data));
        !           684:        case V_FORMAT:
        !           685:                return(fd_format(dev,data));
        !           686:        case V_VERIFY:  /* cmdarg : 0 == no verify, 0 != verify */
        !           687:                m765verify[unit] = *(int *)data;
        !           688:                return(D_SUCCESS);
        !           689:        default:
        !           690:                return(D_INVALID_OPERATION);
        !           691:        }
        !           692: }
        !           693: 
        !           694: /*
        !           695:  *      Get block size
        !           696:  */
        !           697: int
        !           698: fddevinfo(dev, flavor, info)
        !           699: dev_t   dev;
        !           700: int    flavor;
        !           701: char   *info;
        !           702: {
        !           703:        register struct fddrtab *dr;
        !           704:         register struct fdpart *p;
        !           705:        register int result = D_SUCCESS;
        !           706: 
        !           707:        switch (flavor) {
        !           708:        case D_INFO_BLOCK_SIZE:
        !           709:                dr = &unit_info[UNIT(dev)].d_drtab;
        !           710: 
        !           711:                if(dr->dr_type & OKTYPE)
        !           712:                        *((int *) info) =  512;
        !           713:                else
        !           714:                        result = D_INVALID_OPERATION;
        !           715: 
        !           716:                break;
        !           717:        default:
        !           718:                result = D_INVALID_OPERATION;
        !           719:        }
        !           720: 
        !           721:         return(result);
        !           722: }
        !           723: #else  MACH_KERNEL
        !           724: /*****************************************************************************
        !           725:  *
        !           726:  * TITLE:      fdioctl
        !           727:  *
        !           728:  * ABSTRACT:   m765 driver special functions.
        !           729:  *
        !           730:  * CALLING ROUTINES:   kernel
        !           731:  *
        !           732:  ****************************************************************************/
        !           733: int 
        !           734: fdioctl(dev, cmd, cmdarg, flag)
        !           735: dev_t  dev;            /* major, minor numbers */
        !           736: int    cmd;            /* command code */
        !           737: int    *cmdarg;        /* user structure with parameters */
        !           738: int    flag;           /* not used */
        !           739: {
        !           740:        register unsigned       unit = UNIT(dev);
        !           741:        switch (cmd) {
        !           742:        case V_SETPARMS:    /* Caller wants reset_parameters */
        !           743:                return(fd_setparms(unit,*cmdarg));
        !           744:        case V_GETPARMS:    /* Caller wants device parameters */
        !           745:                return(fd_getparms(dev,cmdarg));
        !           746:        case V_FORMAT:
        !           747:                return(fd_format(dev,cmdarg));
        !           748:        case V_VERIFY:  /* cmdarg : 0 == no verify, 0 != verify */
        !           749:                m765verify[unit] = *cmdarg;
        !           750:                return(0);
        !           751:        }
        !           752:        return(EINVAL);
        !           753: }
        !           754: #endif MACH_KERNEL
        !           755: /****************************************************************************
        !           756:  *
        !           757:  *     set fd parameters 
        !           758:  *
        !           759:  ****************************************************************************/
        !           760: int
        !           761: fd_setparms(unit, cmdarg)
        !           762: register unsigned int unit;
        !           763: long cmdarg;
        !           764: {
        !           765:        struct fddrtab   *fdparm;
        !           766:        spl_t            x;
        !           767:        struct unit_info *uip = &unit_info[unit];
        !           768:        struct  fdcmd    *cmdp = uip->b_cmd;
        !           769: 
        !           770:        cmdp->c_rbmtr &= ~(1<<(RBSHIFT+uip->dev->slave));
        !           771:        if ((fdparm = getparm(MEDIATYPE(cmdarg))) == (struct fddrtab *)ERROR)
        !           772:                return(EINVAL);
        !           773:        x = SPL();
        !           774:        openchk(cmdp);
        !           775:        cmdp->c_devflag |= FDMCHK;
        !           776:        chkbusy(cmdp);
        !           777:        m765sweep(uip, fdparm);
        !           778:        uip->d_drtab.dr_type |= OKTYPE;
        !           779:        openfre(cmdp);
        !           780:        splx(x);
        !           781:        return(0);
        !           782: }
        !           783: /****************************************************************************
        !           784:  *
        !           785:  *     get fd parameters 
        !           786:  *
        !           787:  ****************************************************************************/
        !           788: int
        !           789: fd_getparms(dev,cmdarg)
        !           790: dev_t  dev;            /* major, minor numbers */
        !           791: int    *cmdarg;
        !           792: {
        !           793:        struct disk_parms       *diskp = (struct disk_parms *)cmdarg;
        !           794:        register struct fddrtab *dr = &unit_info[UNIT(dev)].d_drtab;
        !           795: 
        !           796:        if(dr->dr_type & OKTYPE){
        !           797:                diskp->dp_type = DPT_FLOPPY;
        !           798:                diskp->dp_heads = 2;
        !           799:                diskp->dp_sectors = dr->dr_nsec;
        !           800:                diskp->dp_pstartsec = 0;
        !           801:                diskp->dp_cyls = dr->dr_ncyl;
        !           802:                diskp->dp_pnumsec = dr->p_nsec;
        !           803:                return(0);
        !           804:        }
        !           805:        return(ENXIO);
        !           806: }
        !           807: /****************************************************************************
        !           808:  *
        !           809:  *     format command
        !           810:  *
        !           811:  ****************************************************************************/
        !           812: fd_format(dev,cmdarg)
        !           813: dev_t  dev;            /* major, minor numbers */
        !           814: int    *cmdarg;
        !           815: 
        !           816: {
        !           817:        register struct buf     *bp;
        !           818:        register daddr_t        track;
        !           819:        union  io_arg           *varg;
        !           820:        u_short                 num_trks;
        !           821:        register struct fddrtab *dr = &unit_info[UNIT(dev)].d_drtab;
        !           822: 
        !           823:        if(!(dr->dr_type & OKTYPE))
        !           824:                return(EINVAL); 
        !           825:        varg = (union io_arg *)cmdarg;
        !           826:        num_trks = varg->ia_fmt.num_trks;
        !           827:        track = (daddr_t)(varg->ia_fmt.start_trk*dr->dr_nsec);
        !           828:        if((track + (num_trks*dr->dr_nsec))>dr->p_nsec)
        !           829:                return(EINVAL);
        !           830:        bp = geteblk(BLKSIZE);          /* get struct buf area */
        !           831:        while (num_trks>0) {
        !           832:                bp->b_flags &= ~B_DONE;
        !           833:                bp->b_dev = dev;
        !           834:                bp->b_error = 0; bp->b_resid = 0;
        !           835:                bp->b_flags = B_FORMAT; 
        !           836:                bp->b_bcount = dr->dr_nsec * FMTID;
        !           837:                bp->b_blkno = (daddr_t)((track << 9) / NBPSCTR);
        !           838:                if(makeidtbl(bp->b_un.b_addr,dr,
        !           839:                             varg->ia_fmt.start_trk++,varg->ia_fmt.intlv))
        !           840:                        return(EINVAL);
        !           841:                fdstrategy(bp);
        !           842:                biowait(bp);
        !           843:                if(bp->b_error)
        !           844:                        if((bp->b_error == (char)EBBHARD) || 
        !           845:                           (bp->b_error == (char)EBBSOFT))
        !           846:                                return(EIO);
        !           847:                        else
        !           848:                                return(bp->b_error);
        !           849:                num_trks--;
        !           850:                track += dr->dr_nsec;
        !           851:        }
        !           852:        brelse(bp);
        !           853:        return(0);
        !           854: }
        !           855: /****************************************************************************
        !           856:  *
        !           857:  *     make id table for format
        !           858:  *
        !           859:  ****************************************************************************/
        !           860: makeidtbl(tblpt,dr,track,intlv)
        !           861: struct fmttbl *tblpt;
        !           862: struct fddrtab *dr;
        !           863: unsigned short track;
        !           864: unsigned short intlv;
        !           865: {
        !           866:        register int    i,j,secno;
        !           867: 
        !           868:        if(intlv >= dr->dr_nsec)
        !           869:                return(1);
        !           870:        for(i=0; i<dr->dr_nsec; i++)
        !           871:                tblpt[i].sector = 0;
        !           872:        for(i=0,j=0,secno=1; i<dr->dr_nsec; i++){
        !           873:                tblpt[j].cyl = track >> 1;
        !           874:                tblpt[j].head = track & 1;
        !           875:                tblpt[j].sector = secno++;
        !           876:                tblpt[j].s_type = 2;
        !           877:                if((j+=intlv) < dr->dr_nsec)
        !           878:                        continue;
        !           879:                for(j-=dr->dr_nsec; j < dr->dr_nsec ; j++)
        !           880:                        if(!tblpt[j].sector)
        !           881:                                break;
        !           882:        }
        !           883:        return(0);
        !           884: }
        !           885: /*****************************************************************************
        !           886:  *
        !           887:  * TITLE:      fdintr
        !           888:  *
        !           889:  * ABSTRACT:   Handle interrupt.
        !           890:  *
        !           891:  *     Interrupt procedure for m765 driver.  Gets status of last
        !           892:  *     operation and performs service function according to the
        !           893:  *     type of interrupt.  If it was an operation complete interrupt,
        !           894:  *     switches on the current driver state and either declares the
        !           895:  *     operation done, or starts the next operation
        !           896:  *
        !           897:  ****************************************************************************/
        !           898: fdintr(ctrl)
        !           899: int    ctrl;
        !           900: {
        !           901:        extern                  int(m765intrsub)();
        !           902:        struct unit_info        *uip = ctrl_info[ctrl].b_uip;
        !           903:        struct unit_info        *wup = ctrl_info[ctrl].b_wup;
        !           904:        struct fdcmd            *cmdp = &ctrl_info[ctrl].b_cmd;
        !           905:        if(cmdp->c_stsflag & INTROUT)
        !           906:                untimeout(fdintr, ctrl);
        !           907:        cmdp->c_stsflag &= ~INTROUT;    
        !           908:        switch(cmdp->c_intr){
        !           909:        case RWFLAG:
        !           910:                rwintr(uip);
        !           911:                break;  
        !           912:        case SKFLAG:
        !           913:        case SKEFLAG|SKFLAG:
        !           914:        case RBFLAG:
        !           915:                timeout(m765intrsub, uip, SEEKWAIT);
        !           916:                break;
        !           917:        case WUPFLAG:
        !           918:                cmdp->c_intr &= ~WUPFLAG;
        !           919:                wakeup(wup);
        !           920:        }
        !           921:        return(0);
        !           922: }
        !           923: /*****************************************************************************
        !           924:  *
        !           925:  *     interrup subroutine (seek recalibrate)
        !           926:  *
        !           927:  *****************************************************************************/
        !           928: m765intrsub(uip)
        !           929: struct unit_info *uip;
        !           930: {
        !           931:        struct ctrl_info *cip = &ctrl_info[uip->dev->ctlr];
        !           932: 
        !           933:        if((cip->b_status = sis(uip))!=  ST0OK)
        !           934:                switch(uip->b_cmd->c_intr){
        !           935:                case SKFLAG:
        !           936:                        seekintr(uip);
        !           937:                        break;
        !           938:                case SKEFLAG|SKFLAG:
        !           939:                        seekintre(uip);
        !           940:                        break;
        !           941:                case RBFLAG:
        !           942:                        rbintr(uip);
        !           943:                }
        !           944: }
        !           945: /*****************************************************************************
        !           946:  *
        !           947:  *     read / write / format / verify interrupt routine
        !           948:  *
        !           949:  *****************************************************************************/
        !           950: rwintr(uip)
        !           951: struct unit_info *uip;
        !           952: {
        !           953:        int                     rsult[7];
        !           954:        register int            rtn, count;
        !           955:        struct ctrl_info        *cip = &ctrl_info[uip->dev->ctlr];
        !           956:        struct fdcmd            *cmdp = uip->b_cmd;
        !           957: 
        !           958:        cmdp->c_intr &= ~RWFLAG;
        !           959:        if((cip->b_buf->b_flags&(B_READ|B_VERIFY))!=(B_READ|B_VERIFY))
        !           960:                if(inb(VFOREG(uip->addr))&OPENBIT){
        !           961:                        if(cip->b_buf->b_flags&B_FORMAT){
        !           962:                                cip->b_status = TIMEOUT;
        !           963:                                intrerr0(uip);
        !           964:                        } else {
        !           965:                                if((inb(STSREG(uip->addr))&ST0OK)!=ST0OK)
        !           966:                                        printf("%s %d : %s\n",
        !           967:                                                fderr,
        !           968:                                                uip-unit_info,
        !           969:                                                fdmsg[DOORERR]);
        !           970:                                rstout(uip);
        !           971:                                specify(uip);
        !           972:                                cmdp->c_rbmtr &= RBRST;
        !           973:                                cmdp->c_intr |= SKEFLAG;
        !           974:                                if(cmdp->c_saddr > 2)
        !           975:                                        fdiseek(uip, cmdp->c_saddr-2);
        !           976:                                else
        !           977:                                        fdiseek(uip, cmdp->c_saddr+2);
        !           978:                        }
        !           979:                        return;
        !           980:                }
        !           981:        for( count = 0 ; count < 7 ; count++ ){
        !           982:                if(rtn = fdc_sts(FD_ISTS, uip)) /* status check */
        !           983:                        goto rwend;
        !           984:                rsult[count] = inb(DATAREG(uip->addr));
        !           985:        }
        !           986:        rtn = 0;
        !           987:        if(rsult[0]&0xc0){
        !           988:                rtn = cmdp->c_rwdata[0]<<8;
        !           989:                if(rsult[0]&0x80){ rtn |= FDCERR;   goto rwend; }
        !           990:                if(rsult[1]&0x80){ rtn |= NOREC;    goto rwend; }
        !           991:                if(rsult[1]&0x20){ rtn |= CRCERR;   goto rwend; }
        !           992:                if(rsult[1]&0x10){ rtn |= OVERRUN;  goto rwend; }
        !           993:                if(rsult[1]&0x04){ rtn |= NOREC;    goto rwend; }
        !           994:                if(rsult[1]&0x02){ rtn |= WTPRT;    goto rwend; }
        !           995:                if(rsult[1]&0x01){ rtn |= ADDRERR;  goto rwend; }
        !           996:                rtn |= FDCERR;
        !           997: rwend:         outb(0x0a, 0x06);
        !           998:        }
        !           999:        if(cip->b_status = rtn) {
        !          1000:                D(printf("\n->rwierr %x ", rtn));
        !          1001:                rwierr(uip);
        !          1002:        } else { /* write command */
        !          1003:                if(((cip->b_buf->b_flags&(B_FORMAT|B_READ|B_WRITE))==B_WRITE) 
        !          1004:                   && !(cip->b_buf->b_flags & B_VERIFY)) {
        !          1005:                        D(printf("->w/v "));
        !          1006:                        cip->b_buf->b_flags |= B_VERIFY;
        !          1007:                        rwcmdset(uip);
        !          1008:                        if(cip->b_status = outicmd(uip))
        !          1009:                                intrerr0(uip);
        !          1010:                        return;
        !          1011:                }
        !          1012:                /* clear retry count */
        !          1013:                if (cip->usebuf) {
        !          1014:                        bcopy(cip->b_vbuf, cip->b_xferaddr, cip->b_xferdma);
        !          1015:                        DD(printf("R(%x, %x, %x)\n",
        !          1016:                                cip->b_vbuf, cip->b_xferaddr, cip->b_xferdma));
        !          1017:                }
        !          1018:                cip->b_buf->b_flags &= ~B_VERIFY;
        !          1019:                cip->b_rwerr = cip->b_seekerr = cip->b_rberr = 0;
        !          1020:                cip->b_xfercount -= cip->b_xferdma;
        !          1021:                cip->b_xferaddr += cip->b_xferdma;
        !          1022:                cip->b_sector = cip->b_sector+(cip->b_xferdma>>9);
        !          1023:                D(printf("->done%s\n", cip->b_xfercount?"":"." ));
        !          1024:                /* next address (cyl,head,sec) */
        !          1025:                if((int)cip->b_xfercount>0)
        !          1026:                        m765iosub(uip);
        !          1027:                else
        !          1028:                        quechk(uip);
        !          1029:        }
        !          1030: }
        !          1031: /*****************************************************************************
        !          1032:  *
        !          1033:  *     read / write / format / verify error routine
        !          1034:  *
        !          1035:  *****************************************************************************/
        !          1036: rwierr(uip)
        !          1037: struct unit_info *uip;
        !          1038: {
        !          1039:        short                   status;
        !          1040:        struct ctrl_info        *cip = &ctrl_info[uip->dev->ctlr];
        !          1041:        struct  fdcmd           *cmdp = uip->b_cmd;
        !          1042: 
        !          1043:        D(printf("%x-%x-%x ", cip->b_rwerr&SRMASK, cip->b_rwerr&MRMASK, cip->b_rwerr&LRMASK));
        !          1044:        if((cip->b_buf->b_flags&(B_READ|B_VERIFY))==(B_READ|B_VERIFY)){
        !          1045:                if((cip->b_rwerr&SRMASK)<MEDIARD)
        !          1046:                        goto rwrtry;
        !          1047:                if((cip->b_rwerr&MRMASK)<MEDIASEEK)
        !          1048:                        goto rwseek;
        !          1049:                goto rwexit;
        !          1050:        } else
        !          1051:                if(cip->b_buf->b_flags&B_VERIFY){
        !          1052:                        cip->b_buf->b_flags &= ~B_VERIFY;
        !          1053:                        rwcmdset(uip);
        !          1054:                }
        !          1055: rwrtry:        status = cip->b_status;
        !          1056:        if((++cip->b_rwerr&SRMASK)<SRETRY)
        !          1057:                cip->b_status = outicmd(uip);
        !          1058:        else {
        !          1059: rwseek:                cip->b_rwerr = (cip->b_rwerr&RMRMASK)+MINC;
        !          1060:                if((cip->b_rwerr&MRMASK)<MRETRY){
        !          1061:                        cmdp->c_intr |= SKEFLAG;
        !          1062:                        if(cmdp->c_saddr > 2)
        !          1063:                                cip->b_status=fdiseek(uip,cmdp->c_saddr-2);
        !          1064:                        else
        !          1065:                                cip->b_status=fdiseek(uip,cmdp->c_saddr+2);
        !          1066:                } else {
        !          1067:                        cip->b_rwerr = (cip->b_rwerr&LRMASK)+LINC;
        !          1068:                        if((cip->b_rwerr&LRMASK)<LRETRY)
        !          1069:                                        cip->b_status=rbirate(uip);
        !          1070:                }
        !          1071:        }
        !          1072:        if(cip->b_status){
        !          1073:                D(printf("ERR->intrerr0 "));
        !          1074:                cip->b_status = status;
        !          1075: rwexit:                intrerr0(uip);
        !          1076:        }
        !          1077: }
        !          1078: /*****************************************************************************
        !          1079:  *
        !          1080:  *     recalibrate interrupt routine
        !          1081:  *
        !          1082:  *****************************************************************************/
        !          1083: rbintr(uip)
        !          1084: struct unit_info *uip;
        !          1085: {
        !          1086:        struct ctrl_info        *cip = &ctrl_info[uip->dev->ctlr];
        !          1087:        struct fdcmd            *cmdp = uip->b_cmd;
        !          1088: 
        !          1089:        cmdp->c_intr &= ~RBFLAG;
        !          1090:        if(cip->b_status) {
        !          1091:                if(++cip->b_rberr<SRETRY)
        !          1092:                        cip->b_status = rbirate(uip);
        !          1093:        } else {
        !          1094:                cmdp->c_rbmtr |= 1<<(RBSHIFT+uip->dev->slave);
        !          1095:                uip->b_seekaddr = 0;
        !          1096:                cip->b_rberr = 0;
        !          1097:                cip->b_status=fdiseek(uip, cmdp->c_saddr);
        !          1098:        }
        !          1099:        if(cip->b_status)
        !          1100:                intrerr0(uip);
        !          1101: }
        !          1102: /******************************************************************************
        !          1103:  *
        !          1104:  *     seek interrupt routine
        !          1105:  *
        !          1106:  *****************************************************************************/
        !          1107: seekintr(uip)
        !          1108: struct unit_info *uip;
        !          1109: {
        !          1110:        struct ctrl_info        *cip = &ctrl_info[uip->dev->ctlr];
        !          1111:        struct fdcmd            *cmdp = uip->b_cmd;
        !          1112: 
        !          1113:        cmdp->c_intr &= ~SKFLAG;
        !          1114:        if(cip->b_status)
        !          1115:                seekierr(uip, cmdp->c_saddr);
        !          1116:        else {
        !          1117:                uip->b_seekaddr = cmdp->c_saddr;
        !          1118:                cip->b_status = outicmd(uip);
        !          1119:        }
        !          1120:        if(cip->b_status)
        !          1121:                intrerr0(uip);
        !          1122:        else
        !          1123:                cip->b_seekerr = 0;
        !          1124: }
        !          1125: /*****************************************************************************
        !          1126:  *
        !          1127:  *     seek error retry interrupt routine
        !          1128:  *
        !          1129:  *****************************************************************************/
        !          1130: seekintre(uip)
        !          1131: struct unit_info *uip;
        !          1132: {
        !          1133:        register char           seekpoint;
        !          1134:        struct ctrl_info        *cip = &ctrl_info[uip->dev->ctlr];
        !          1135:        struct fdcmd            *cmdp = uip->b_cmd;
        !          1136: 
        !          1137:        cmdp->c_intr &= ~(SKEFLAG|SKFLAG);
        !          1138:        if(cmdp->c_saddr > 2)
        !          1139:                seekpoint = cmdp->c_saddr-2;
        !          1140:        else
        !          1141:                seekpoint = cmdp->c_saddr+2;
        !          1142:        if(cip->b_status)
        !          1143:                seekierr(uip, seekpoint);
        !          1144:        else {
        !          1145:                uip->b_seekaddr = seekpoint;
        !          1146:                cip->b_status = fdiseek(uip, cmdp->c_saddr);
        !          1147:        }
        !          1148:        if(cip->b_status)
        !          1149:                intrerr0(uip);
        !          1150:        else
        !          1151:                cip->b_seekerr = 0;
        !          1152: }
        !          1153: /*****************************************************************************
        !          1154:  *
        !          1155:  *     seek error routine
        !          1156:  *
        !          1157:  *****************************************************************************/
        !          1158: seekierr(uip, seekpoint)
        !          1159: struct unit_info *uip;
        !          1160: register char          seekpoint;
        !          1161: {
        !          1162:        struct ctrl_info *cip = &ctrl_info[uip->dev->ctlr];
        !          1163: 
        !          1164:        if((++cip->b_seekerr&SRMASK)<SRETRY)
        !          1165:                cip->b_status=fdiseek(uip, seekpoint);
        !          1166:        else {
        !          1167:                cip->b_seekerr = (cip->b_seekerr&MRMASK) + MINC;
        !          1168:                if((cip->b_seekerr&MRMASK)<MRETRY)
        !          1169:                        cip->b_status=rbirate(uip);
        !          1170:        }
        !          1171:        if(cip->b_status)
        !          1172:                intrerr0(uip);
        !          1173: }
        !          1174: /*****************************************************************************
        !          1175:  *
        !          1176:  * TITLE:      m765sweep
        !          1177:  *
        !          1178:  * ABSTRACT:   Perform an initialization sweep.  
        !          1179:  *
        !          1180:  **************************************************************************/
        !          1181: m765sweep(uip, cdr)
        !          1182: struct unit_info *uip;
        !          1183: register struct fddrtab  *cdr; /* device initialization data */
        !          1184: {
        !          1185:        register struct fddrtab *dr = &uip->d_drtab;
        !          1186: 
        !          1187:        dr->dr_ncyl = cdr->dr_ncyl;
        !          1188:        dr->dr_nsec = cdr->dr_nsec;
        !          1189:        dr->dr_spc  = cdr->dr_spc;
        !          1190:        dr->p_nsec  = cdr->p_nsec;
        !          1191:        dr->dr_type = cdr->dr_type;
        !          1192:        dr->dr_rwgpl= cdr->dr_rwgpl;
        !          1193:        dr->dr_fgpl = cdr->dr_fgpl;
        !          1194: }
        !          1195: /*****************************************************************************
        !          1196:  *
        !          1197:  *  TITLE:  m765disksort
        !          1198:  *
        !          1199:  *****************************************************************************/
        !          1200: fd_disksort(uip, bp)
        !          1201: struct unit_info *uip;         /*  Pointer to head of active queue     */
        !          1202: register struct buf *bp;       /*  Pointer to buffer to be inserted    */
        !          1203: {
        !          1204:        register struct buf *bp2; /*  Pointer to next buffer in queue   */
        !          1205:        register struct buf *bp1; /*  Pointer where to insert buffer    */
        !          1206: 
        !          1207:        if (!(bp1 = uip->av_forw)) {
        !          1208:                /* No other buffers to compare against */
        !          1209:                uip->av_forw = bp;
        !          1210:                bp->av_forw = 0;
        !          1211:                return;
        !          1212:        }
        !          1213:        bp2 = bp1->av_forw;
        !          1214:        while(bp2 && (relative(bp1->b_pfcent,bp->b_pfcent) >=
        !          1215:                      relative(bp1->b_pfcent,bp2->b_pfcent))) {
        !          1216:                bp1 = bp2;
        !          1217:                bp2 = bp1->av_forw;
        !          1218:        }
        !          1219:        bp1->av_forw = bp;
        !          1220:        bp->av_forw = bp2;
        !          1221: }
        !          1222: /*****************************************************************************
        !          1223:  *
        !          1224:  *     Set Interrupt error and FDC reset
        !          1225:  *
        !          1226:  *****************************************************************************/
        !          1227: intrerr0(uip)
        !          1228: struct unit_info *uip;
        !          1229: {
        !          1230:        struct buf              *bp; /* Pointer to next buffer in queue */
        !          1231:        int                     resid;
        !          1232:        struct ctrl_info        *cip = &ctrl_info[uip->dev->ctlr];
        !          1233:        struct  fdcmd           *cmdp = uip->b_cmd;
        !          1234:        register struct fddrtab *dr = &uip->d_drtab;
        !          1235: 
        !          1236:        if((cip->b_buf->b_flags&(B_READ|B_VERIFY))!=(B_READ|B_VERIFY)){
        !          1237:                resid = cip->b_xfercount = cip->b_xferdma-1-inb(DMACNT)*0x101;
        !          1238:                resid = (cip->b_sector + (resid>>9)) % dr->dr_spc;
        !          1239:                printf("%s %d : %s\n",
        !          1240:                        fderr,
        !          1241:                        uip->dev->slave,
        !          1242:                        fdmsg[cip->b_status&BYTEMASK]);
        !          1243:                printf("cylinder = %d  ",cmdp->c_saddr);
        !          1244:                printf("head = %d  sector = %d  byte/sec = %d\n",
        !          1245:                resid / dr->dr_nsec , (resid % dr->dr_nsec)+1 , 512);
        !          1246:        }
        !          1247:        cip->b_rwerr = cip->b_seekerr = cip->b_rberr = 0;
        !          1248:        cmdp->c_intr = CMDRST;
        !          1249:        if(((cip->b_buf->b_flags&(B_READ|B_VERIFY))!=(B_READ|B_VERIFY)) &&
        !          1250:           uip->dev->slave)
        !          1251:                dr->dr_type &= ~OKTYPE; 
        !          1252:        bp = cip->b_buf;
        !          1253:        bp->b_flags |= B_ERROR;
        !          1254:        switch(cip->b_status&BYTEMASK){
        !          1255:        case ADDRERR:
        !          1256:        case OVERRUN:
        !          1257:        case FDCERR:
        !          1258:        case TIMEOUT:
        !          1259:                bp->b_error = EIO;
        !          1260:                break;
        !          1261:        case WTPRT:
        !          1262: #ifdef MACH_KERNEL
        !          1263:                bp->b_error = ENXIO;
        !          1264: #else
        !          1265:                bp->b_error = ENODEV;
        !          1266: #endif
        !          1267:                break;
        !          1268:        case NOREC:
        !          1269:                bp->b_error = EBBHARD;
        !          1270:                break;
        !          1271:        case CRCERR:
        !          1272:                bp->b_error = EBBSOFT;
        !          1273:        }
        !          1274:        rstout(uip);
        !          1275:        specify(uip);
        !          1276:        cmdp->c_rbmtr &= RBRST;
        !          1277:        quechk(uip);
        !          1278: }
        !          1279: /*****************************************************************************
        !          1280:  *
        !          1281:  *     Next queue check routine
        !          1282:  *
        !          1283:  *****************************************************************************/
        !          1284: quechk(uip)
        !          1285: struct unit_info *uip;
        !          1286: {
        !          1287:        register struct buf     *bp = uip->av_forw;
        !          1288:        struct ctrl_info        *cip = &ctrl_info[uip->dev->ctlr];
        !          1289:        struct unit_info        *loop;
        !          1290:        struct fdcmd            *cmdp = uip->b_cmd;
        !          1291:        /* clear retry count */
        !          1292:        cip->b_rwerr = cip->b_seekerr = cip->b_rberr = 0;
        !          1293:        bp->b_resid = bp->b_resid + cip->b_xfercount;
        !          1294:        uip->av_forw=bp->av_forw;
        !          1295:        if (!uip->av_forw && uip->wakeme) {
        !          1296:                uip->wakeme = 0;
        !          1297:                wakeup(uip);
        !          1298:        }
        !          1299:        biodone(bp);
        !          1300:        loop = uip;
        !          1301:        do {
        !          1302:                loop=loop->b_unitf;
        !          1303:                if (loop->av_forw) {
        !          1304:                        m765io(loop);
        !          1305:                        return;
        !          1306:                }
        !          1307:        } while (loop!=uip);
        !          1308:        cip->b_uip = 0;
        !          1309:        cmdp->c_stsflag &= ~MTRFLAG;
        !          1310:        mtr_on(uip);
        !          1311:        cmdp->c_devflag &= ~STRCHK;
        !          1312:        if(cmdp->c_devflag & STRWAIT){
        !          1313:                cmdp->c_devflag &= ~STRWAIT;
        !          1314:                wakeup(&cmdp->c_devflag);
        !          1315:        }
        !          1316: }
        !          1317: fdprint(dev,str)
        !          1318: dev_t  dev;
        !          1319: char   *str;
        !          1320: {
        !          1321:        printf("floppy disk driver: %s on bad dev %d, partition %d\n",
        !          1322:                        str, UNIT(dev), 0);
        !          1323: }
        !          1324: fdsize()
        !          1325: {
        !          1326:        printf("fdsize()        -- not implemented\n");
        !          1327: }
        !          1328: fddump()
        !          1329: {
        !          1330:        printf("fddump()        -- not implemented\n");
        !          1331: }
        !          1332: /*****************************************************************************
        !          1333:  *
        !          1334:  *     fdc reset routine
        !          1335:  *
        !          1336:  *****************************************************************************/
        !          1337: rstout(uip)
        !          1338: struct unit_info *uip;
        !          1339: {
        !          1340:        register int    outd;
        !          1341: 
        !          1342:        outd = ((uip->b_cmd->c_rbmtr&MTRMASK)<<MTR_ON)|uip->dev->slave;
        !          1343:        outb(CTRLREG(uip->addr), outd);
        !          1344:        outd |= FDC_RST;
        !          1345:        outb(CTRLREG(uip->addr), outd);
        !          1346:        outd |= DMAREQ;
        !          1347:        outb(CTRLREG(uip->addr), outd);
        !          1348: }
        !          1349: /*****************************************************************************
        !          1350:  *
        !          1351:  *     specify command routine
        !          1352:  *
        !          1353:  *****************************************************************************/
        !          1354: specify(uip)
        !          1355: struct unit_info *uip;
        !          1356: {
        !          1357:        /* status check */
        !          1358:        if(fdc_sts(FD_OSTS, uip))
        !          1359:                return;
        !          1360:        /* Specify command */
        !          1361:        outb(DATAREG(uip->addr), SPCCMD);
        !          1362:        /* status check */
        !          1363:        if(fdc_sts(FD_OSTS, uip))
        !          1364:                return;
        !          1365:        /* Step rate,Head unload time */
        !          1366:        outb(DATAREG(uip->addr), SRTHUT);
        !          1367:        /* status check */
        !          1368:        if(fdc_sts(FD_OSTS, uip))
        !          1369:                return;
        !          1370:        /* Head load time,Non DMA Mode*/
        !          1371:        outb(DATAREG(uip->addr), HLTND);
        !          1372:        return;
        !          1373: }
        !          1374: /****************************************************************************
        !          1375:  *
        !          1376:  *     recalibrate command routine
        !          1377:  *
        !          1378:  ****************************************************************************/
        !          1379: rbrate(mtype,uip)
        !          1380: char    mtype;
        !          1381: struct unit_info *uip;
        !          1382: {
        !          1383:        register int    rtn = 1, rty_flg=2;
        !          1384:        spl_t           x;
        !          1385:        struct  fdcmd   *cmdp = uip->b_cmd;
        !          1386: 
        !          1387:        rbskrate(uip, mtype);                   /* set transfer rate */
        !          1388:        while((rty_flg--)&&rtn){
        !          1389:                if(rtn = fdc_sts(FD_OSTS, uip)) /* status check */
        !          1390:                        break;
        !          1391:                /*recalibrate command*/
        !          1392:                outb(DATAREG(uip->addr), RBCMD);
        !          1393:                if(rtn = fdc_sts(FD_OSTS, uip)) /* status check */
        !          1394:                        break;
        !          1395:                /* Device to wake up specified in open */
        !          1396:                cmdp->c_intr |= WUPFLAG;
        !          1397:                x = SPL();
        !          1398:                outb(DATAREG(uip->addr), uip->dev->slave);
        !          1399:                rtn = ERROR;
        !          1400:                while(rtn) {
        !          1401:                        uip->wakeme = 1;
        !          1402:                        sleep(uip, PZERO);
        !          1403:                        if((rtn = sis(uip)) == ST0OK)
        !          1404:                          /* Device to wake up specified in open */
        !          1405:                                cmdp->c_intr |= WUPFLAG;
        !          1406:                        else
        !          1407:                                break;
        !          1408:                }
        !          1409:                splx(x);
        !          1410:        }
        !          1411:        return(rtn);
        !          1412: }
        !          1413: /*****************************************************************************
        !          1414:  *
        !          1415:  *     seek command routine
        !          1416:  *
        !          1417:  ****************************************************************************/
        !          1418: fdseek(mtype, uip, cylno)
        !          1419: register char  mtype;
        !          1420: struct unit_info *uip;
        !          1421: register int   cylno;
        !          1422: {
        !          1423:        spl_t           x;
        !          1424:        int             rtn;
        !          1425:        struct  fdcmd   *cmdp = uip->b_cmd;
        !          1426: 
        !          1427:        rbskrate(uip, mtype);
        !          1428:        if(rtn = fdc_sts(FD_OSTS, uip))                 /* status check */
        !          1429:                return(rtn);
        !          1430:        outb(DATAREG(uip->addr), SEEKCMD);              /* seek command */
        !          1431:        if(rtn = fdc_sts(FD_OSTS, uip))                 /* status check */
        !          1432:                return(rtn);
        !          1433:        outb(DATAREG(uip->addr), uip->dev->slave);      /* drive number */
        !          1434:        if(rtn = fdc_sts(FD_OSTS, uip))                 /* status check */
        !          1435:                return(rtn);
        !          1436:        x = SPL();
        !          1437:        /* Device to wake up specified in open */
        !          1438:        cmdp->c_intr |= WUPFLAG;
        !          1439:        outb(DATAREG(uip->addr), cylno);                /* seek count */
        !          1440:        rtn = ERROR;
        !          1441:        while(rtn){     
        !          1442:                uip->wakeme = 1;
        !          1443:                sleep(uip, PZERO);
        !          1444:                if((rtn = sis(uip)) == ST0OK)
        !          1445:                  /* Device to wake up specified in open */
        !          1446:                        cmdp->c_intr |= WUPFLAG;
        !          1447:                else
        !          1448:                        break;
        !          1449:        }
        !          1450:        splx(x);
        !          1451:        return(rtn);
        !          1452: }
        !          1453: /*****************************************************************************
        !          1454:  *
        !          1455:  *     seek commnd routine(use interrupt)
        !          1456:  *
        !          1457:  *****************************************************************************/
        !          1458: fdiseek(uip, cylno) 
        !          1459: struct unit_info *uip;
        !          1460: int    cylno;
        !          1461: {
        !          1462:        register int    rtn;
        !          1463: 
        !          1464:        D(printf("SK %x ", cylno));
        !          1465:        rbskrate(uip, uip->d_drtab.dr_type);/* set transfer rate */
        !          1466:        if(rtn = fdc_sts(FD_OSTS, uip))         /* status check */
        !          1467:                goto fdiend;
        !          1468:        outb(DATAREG(uip->addr), SEEKCMD);      /* seek command */
        !          1469:        if(rtn = fdc_sts(FD_OSTS, uip))         /* status check */
        !          1470:                goto fdiend;
        !          1471:        outb(DATAREG(uip->addr), uip->dev->slave);      /* drive number */
        !          1472:        if(rtn = fdc_sts(FD_OSTS, uip))         /* status check */
        !          1473:                goto fdiend;
        !          1474:        uip->b_seekaddr = cylno;
        !          1475:        if(uip->d_drtab.dr_type&DOUBLE)
        !          1476:                cylno = cylno * 2;
        !          1477:        uip->b_cmd->c_intr |= SKFLAG;
        !          1478:        outb(DATAREG(uip->addr), cylno);        /* seek count */
        !          1479: fdiend:        
        !          1480:        if(rtn)
        !          1481:                rtn |= SEEKCMD<<8;
        !          1482:        return(rtn);
        !          1483: }
        !          1484: /*****************************************************************************
        !          1485:  *
        !          1486:  *     recalibrate command routine(use interrupt)
        !          1487:  *
        !          1488:  *****************************************************************************/
        !          1489: rbirate(uip)
        !          1490: struct unit_info *uip;
        !          1491: {
        !          1492:        register int    rtn;
        !          1493: 
        !          1494:        rbskrate(uip, uip->d_drtab.dr_type);/* set transfer rate */
        !          1495:        if(!(rtn = fdc_sts(FD_OSTS, uip))) {            /* status check */
        !          1496:                /* recalibrate command */
        !          1497:                outb(DATAREG(uip->addr), RBCMD);
        !          1498:                if(!(rtn = fdc_sts(FD_OSTS, uip))) {    /* status check */
        !          1499:                        uip->b_cmd->c_intr |= RBFLAG;
        !          1500:                        outb(DATAREG(uip->addr), uip->dev->slave);
        !          1501:                }
        !          1502:        }
        !          1503:        return(rtn ? rtn|RBCMD<<8 : 0);
        !          1504: }
        !          1505: /*****************************************************************************
        !          1506:  *
        !          1507:  *     read / write / format / verify command out routine(use interrupt)
        !          1508:  *
        !          1509:  *****************************************************************************/
        !          1510: outicmd(uip)
        !          1511: struct unit_info *uip;
        !          1512: {
        !          1513:        int                     rtn;
        !          1514:        register int            *data,cnt0,dmalen;
        !          1515:        register long           address;
        !          1516:        struct ctrl_info        *cip = &ctrl_info[uip->dev->ctlr];
        !          1517:        struct fdcmd            *cmdp = uip->b_cmd;
        !          1518:        spl_t                    x = splhi();
        !          1519: 
        !          1520:        outb(DMACMD1,DMADATA0); /* DMA #1 command register      */
        !          1521:        outb(DMAMSK1,DMADATA1); /* DMA #1 all mask register     */
        !          1522:        /* Perhaps outb(0x0a,0x02); might work better on line above? */
        !          1523:        switch(cmdp->c_rwdata[0]){
        !          1524:        case RDM:
        !          1525:                D(printf("RDM"));
        !          1526:                outb(DMABPFF,DMARD);
        !          1527:                outb(DMAMODE,DMARD);
        !          1528:                break;
        !          1529:        case WTM:
        !          1530:        case FMTM:
        !          1531:                D(printf("W"));
        !          1532:                outb(DMABPFF,DMAWT);
        !          1533:                outb(DMAMODE,DMAWT);
        !          1534:                break;
        !          1535:        case RDMV:
        !          1536:                D(printf("RDMV"));
        !          1537:                outb(DMABPFF,DMAVRF);
        !          1538:                outb(DMAMODE,DMAVRF);
        !          1539:        }
        !          1540:        /* get work buffer physical address */
        !          1541:        address = kvtophys(cip->b_xferaddr);
        !          1542:        dmalen = i386_trunc_page(address) + I386_PGBYTES - address;
        !          1543:        if ( (cip->b_rwerr&MRMASK) >= 0x10)
        !          1544:                dmalen = 0x200;
        !          1545:        if (dmalen<=cip->b_xferdma) 
        !          1546:                cip->b_xferdma = dmalen;
        !          1547:        else
        !          1548:                dmalen = cip->b_xferdma;
        !          1549:        if (address >= FdDmaThreshold) {
        !          1550:                DD(printf(">(%x[%x], %x[%x] L%x\n",
        !          1551:                        address, cip->b_pbuf,
        !          1552:                        cip->b_xferaddr, cip->b_vbuf, dmalen));
        !          1553:                if (!FdDmaEISA) {
        !          1554:                        cip->usebuf = 1;
        !          1555:                        address = (long)cip->b_pbuf;
        !          1556:                        if (cmdp->c_rwdata[0] == WTM || cmdp->c_rwdata[0] == FMTM) {
        !          1557:                                bcopy(cip->b_xferaddr, cip->b_vbuf, dmalen);
        !          1558:                                DD(printf("W(%x, %x, %x)\n",
        !          1559:                                        cip->b_xferaddr, cip->b_vbuf, dmalen));
        !          1560:                        }
        !          1561:                } else
        !          1562:                        cip->usebuf = 0;
        !          1563:        } else
        !          1564:                cip->usebuf = 0;
        !          1565:        D(printf(" %x L%x ", address, dmalen));
        !          1566:        /* set buffer address */
        !          1567:        outb(DMAADDR,(int)address&BYTEMASK);
        !          1568:        outb(DMAADDR,(((int)address>>8)&BYTEMASK));
        !          1569:        outb(DMAPAGE,(((int)address>>16)&BYTEMASK));
        !          1570:        if (FdDmaEISA)
        !          1571:                outb(FdDmaEISA+DMAPAGE-0x80,(((int)address>>24)&BYTEMASK));
        !          1572:        /* set transfer count */
        !          1573:        outb(DMACNT,(--dmalen)&BYTEMASK);
        !          1574:        outb(DMACNT,((dmalen>>8)&BYTEMASK));
        !          1575:        outb(DMAMSK,CHANNEL2);
        !          1576:        splx(x);
        !          1577:        trfrate(uip, uip->d_drtab.dr_type);     /* set transfer rate */
        !          1578:        data = &cmdp->c_rwdata[0];
        !          1579:        for(cnt0 = 0; cnt0<cmdp->c_dcount; cnt0++,data++){
        !          1580:                if(rtn = fdc_sts(FD_OSTS, uip)) /*status check*/
        !          1581:                        break;
        !          1582:                outb(DATAREG(uip->addr), *data);
        !          1583:        }
        !          1584:        if(!rtn){
        !          1585:                cmdp->c_intr |= RWFLAG;
        !          1586:                cmdp->c_stsflag |= INTROUT;
        !          1587:                cnt0 = ((cip->b_buf->b_flags&(B_READ|B_VERIFY)) ==
        !          1588:                        (B_READ|B_VERIFY))?TOUT:ITOUT;
        !          1589: #ifdef MACH_KERNEL
        !          1590:                timeout(fdintr,uip->dev->ctlr,cnt0);
        !          1591: #else  MACH_KERNEL
        !          1592:                cmdp->c_timeid = timeout(fdintr,uip->dev->ctlr,cnt0);
        !          1593: #endif MACH_KERNEL
        !          1594:        }
        !          1595:        return(rtn);
        !          1596: }
        !          1597: /*****************************************************************************
        !          1598:  *
        !          1599:  *     sense interrupt status routine
        !          1600:  *
        !          1601:  *****************************************************************************/
        !          1602: sis(uip)
        !          1603: struct unit_info *uip;
        !          1604: {
        !          1605:        register int    rtn, st0;
        !          1606: 
        !          1607:        if(rtn = fdc_sts(FD_OSTS, uip)) /* status check */
        !          1608:                return(rtn);
        !          1609:        outb(DATAREG(uip->addr), SISCMD);
        !          1610:        if(rtn = fdc_sts(FD_ISTS, uip)) /* status check */
        !          1611:                return(rtn);
        !          1612:        st0 = inb(DATAREG(uip->addr)) & ST0OK;  /* get st0 */
        !          1613:        if(rtn = fdc_sts(FD_ISTS, uip)) /* status check */
        !          1614:                return(rtn);
        !          1615:        inb(DATAREG(uip->addr));        /* get pcn */
        !          1616:        if (st0&(ST0AT|ST0IC))
        !          1617:                st0 = FDCERR;
        !          1618:        return(st0);
        !          1619: }
        !          1620: 
        !          1621: /*****************************************************************************
        !          1622:  *
        !          1623:  *     fdc status get routine
        !          1624:  *
        !          1625:  *****************************************************************************/
        !          1626: fdc_sts(mode, uip)
        !          1627: register int   mode;
        !          1628: struct unit_info *uip;
        !          1629: {
        !          1630:        register int    ind;
        !          1631:        int             cnt0 = STSCHKCNT;
        !          1632: 
        !          1633:        while(cnt0--)
        !          1634:                if(((ind=inb(STSREG(uip->addr))) & DATAOK) && 
        !          1635:                   ((ind & DTOCPU) == mode))
        !          1636:                        return(0);
        !          1637:        return(TIMEOUT);
        !          1638: }
        !          1639: /*****************************************************************************
        !          1640:  *
        !          1641:  *     motor on routine
        !          1642:  *
        !          1643:  *****************************************************************************/
        !          1644: mtr_on(uip)
        !          1645: struct unit_info *uip;
        !          1646: {
        !          1647:        extern          int(mtr_off)();
        !          1648:        extern          int(wakeup)();
        !          1649:        struct  fdcmd   *cmdp = uip->b_cmd;
        !          1650: 
        !          1651:        if(!(mtr_start(uip))){
        !          1652:                timeout(wakeup,&cmdp->c_stsflag,HZ);
        !          1653:                sleep(&cmdp->c_stsflag,PZERO);
        !          1654:        }
        !          1655:        cmdp->c_stsflag |= MTROFF;
        !          1656: #ifdef MACH_KERNEL
        !          1657:        timeout(mtr_off,uip,MTRSTOP);
        !          1658: #else  MACH_KERNEL
        !          1659:        cmdp->c_mtrid = timeout(mtr_off,uip,MTRSTOP);
        !          1660: #endif MACH_KERNEL
        !          1661: }
        !          1662: /*****************************************************************************
        !          1663:  *
        !          1664:  *     motor start routine
        !          1665:  *
        !          1666:  *****************************************************************************/
        !          1667: mtr_start(uip)
        !          1668: struct unit_info *uip;
        !          1669: {
        !          1670:        int             status;
        !          1671:        int             (mtr_off)();
        !          1672:        struct  fdcmd   *cmdp = uip->b_cmd;
        !          1673:        int             slave = uip->dev->slave;
        !          1674:        if(cmdp->c_stsflag & MTROFF){
        !          1675:                untimeout(mtr_off, uip);
        !          1676:                cmdp->c_stsflag &= ~MTROFF;
        !          1677:        }
        !          1678:        status = cmdp->c_rbmtr&(1<<slave);
        !          1679:        cmdp->c_rbmtr |= (1<<slave);
        !          1680:        outb(CTRLREG(uip->addr), ((cmdp->c_rbmtr&MTRMASK)<<MTR_ON)|
        !          1681:                                     FDC_RST|slave|DMAREQ);
        !          1682:        return(status);
        !          1683: }
        !          1684: /*****************************************************************************
        !          1685:  *
        !          1686:  *     motor off routine
        !          1687:  *
        !          1688:  *****************************************************************************/
        !          1689: mtr_off(uip)
        !          1690: struct unit_info *uip;
        !          1691: {
        !          1692:        struct  fdcmd   *cmdp = uip->b_cmd;
        !          1693: 
        !          1694:        cmdp->c_stsflag &= ~MTROFF;
        !          1695:        if(!(cmdp->c_stsflag&MTRFLAG)){
        !          1696:                cmdp->c_rbmtr &= MTRRST;
        !          1697:                outb(CTRLREG(uip->addr), FDC_RST | DMAREQ);
        !          1698:        }
        !          1699: }
        !          1700: 
        !          1701: #endif

unix.superglobalmegacorp.com

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