Annotation of Gnu-Mach/chips/fdc_82077_hdw.c, revision 1.1

1.1     ! root        1: /* 
        !             2:  * Mach Operating System
        !             3:  * Copyright (c) 1992 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:  *     File: fdi_82077_hdw.c
        !            28:  *     Author: Alessandro Forin, Carnegie Mellon University
        !            29:  *     Date:   1/92
        !            30:  *
        !            31:  *     Driver for the Intel 82077 Floppy Disk Controller.
        !            32:  */
        !            33: 
        !            34: #include <fd.h>
        !            35: #if    NFD > 0
        !            36: 
        !            37: #include <mach/std_types.h>
        !            38: #include <machine/machspl.h>
        !            39: #include <chips/busses.h>
        !            40: 
        !            41: #include <chips/fdc_82077.h>
        !            42: #include <platforms.h>
        !            43: 
        !            44: /* ---- */
        !            45: #include <device/param.h>
        !            46: #include <device/io_req.h>
        !            47: #include <device/device_types.h>
        !            48: #include <device/disk_status.h>
        !            49: #define        UNITNO(d)       ((d)>>5)
        !            50: #define        SLAVENO(d)      (((d)>>3)&0x3)
        !            51: #define        PARAMNO(d)      ((d)&0x7)
        !            52: /* ---- */
        !            53: 
        !            54: #ifdef MAXINE
        !            55: 
        !            56: /* we can only take one */
        !            57: #define        MAX_DRIVES              1
        !            58: 
        !            59: #define        my_fdc_type     fdc_82077aa
        !            60: #define        the_fdc_type    fd->fdc_type
        !            61: /* later: #define the_fdc_type my_fdc_type */
        !            62: 
        !            63: /* Registers are read/written as words, byte 0 */
        !            64: /* padding is to x40 boundaries */
        !            65: typedef struct {
        !            66:        volatile unsigned int   fd_sra;         /* r:  status register A */
        !            67:        int pad0[15];
        !            68:        volatile unsigned int   fd_srb;         /* r:  status register B */
        !            69:        int pad1[15];
        !            70:        volatile unsigned int   fd_dor;         /* rw: digital output reg */
        !            71:        int pad2[15];
        !            72:        volatile unsigned int   fd_tdr;         /* rw: tape drive register */
        !            73:        int pad3[15];
        !            74:        volatile unsigned int   fd_msr;         /* r:  main status register */
        !            75: /*#define                      fd_dsr  fd_msr; /* w:  data rate select reg */
        !            76:        int pad4[15];
        !            77:        volatile unsigned int   fd_data;        /* rw: fifo */
        !            78:        int pad5[15];
        !            79:        volatile unsigned int   fd_xxx;         /* --reserved-- */
        !            80:        int pad6[15];
        !            81:        volatile unsigned int   fd_dir;         /* r:  digital input reg */
        !            82: /*#define                      fd_ccr  fd_dir; /* w:  config control reg */
        !            83: } fd_padded_regmap_t;
        !            84: 
        !            85: #define        machdep_reset_8272a(f,r)
        !            86: 
        !            87: #else  /* MAXINE */
        !            88: 
        !            89: /* Pick your chip and padding */
        !            90: #define        my_fdc_type             fdc_8272a
        !            91: #define the_fdc_type           my_fdc_type
        !            92: 
        !            93: #define        fd_padded_regmap_t      fd_8272a_regmap_t
        !            94: 
        !            95: #define        machdep_reset_8272a(f,r)        1
        !            96: 
        !            97: #endif /* MAXINE */
        !            98: 
        !            99: 
        !           100: #ifndef        MAX_DRIVES
        !           101: #define        MAX_DRIVES      DRIVES_PER_FDC
        !           102: #endif
        !           103: 
        !           104: /*
        !           105:  * Autoconf info
        !           106:  */
        !           107: 
        !           108: static vm_offset_t fd_std[NFD] = { 0 };
        !           109: static struct bus_device *fd_info[NFD];
        !           110: static struct bus_ctlr  *fd_minfo[NFD];
        !           111: static int fd_probe(), fd_slave(), fd_go();
        !           112: static void fd_attach();
        !           113: 
        !           114: struct bus_driver fd_driver =
        !           115:        { fd_probe, fd_slave, fd_attach, fd_go, fd_std, "fd", fd_info,
        !           116:          "fdc", fd_minfo, /*BUS_INTR_B4_PROBE*/};
        !           117: 
        !           118: /*
        !           119:  * Externally visible functions
        !           120:  */
        !           121: int    fd_intr();                                      /* kernel */
        !           122: 
        !           123: /*
        !           124:  * Media table
        !           125:  *
        !           126:  *      Cyls,Sec,spc,part,Mtype,RWFpl,FGpl
        !           127:  */
        !           128: typedef struct {
        !           129:        unsigned char   d_cylperunit;
        !           130:        unsigned char   d_secpercyl;
        !           131:        unsigned short  d_secperunit;
        !           132:        unsigned char   d_secpertrk;
        !           133:        unsigned char   d_gpl;
        !           134:        unsigned char   d_fgpl;
        !           135:        unsigned char   d_xfer_rate;
        !           136: } fd_params_t;
        !           137: 
        !           138: fd_params_t fd_params[8] = {
        !           139:        {80, 18, 1440,  9, 0x2a, 0x50, FD_DSR_DD_250},  /* [0] 3.50" 720  Kb  */
        !           140:        {80, 36, 2880, 18, 0x1b, 0x6c, FD_DSR_DD_500},  /* [1] 3.50" 1.44 Meg */
        !           141:        {40, 18,  720,  9, 0x2a, 0x50, FD_DSR_DD_250},  /* [2] 5.25" 360  Kb  */
        !           142:        {80, 30, 2400, 15, 0x1b, 0x54, FD_DSR_DD_500},  /* [3] 5.25" 1.20 Meg */
        !           143: };
        !           144: 
        !           145: /*
        !           146:  * Software status of chip
        !           147:  */
        !           148: struct fd_softc {
        !           149:        fd_padded_regmap_t      *regs;
        !           150:        char                    fdc_type;
        !           151:        char                    fdc_mode;
        !           152:        char                    messed_up;
        !           153:        char                    slave_active;
        !           154:        struct slave_t {
        !           155:                io_req_t        ior;
        !           156:                decl_simple_lock_data(,slave_lock)
        !           157: 
        !           158:                /* status at end of last command */
        !           159:                unsigned char   st0;
        !           160:                unsigned char   st1;
        !           161:                unsigned char   st2;
        !           162:                unsigned char   c;
        !           163:                unsigned char   h;
        !           164:                unsigned char   r;
        !           165:                unsigned char   n;
        !           166:                unsigned char   st3;
        !           167:                /* ... */
        !           168:                unsigned char   medium_status;
        !           169: #              define  ST_MEDIUM_PRESENT       1
        !           170: #              define  ST_MEDIUM_KNOWN         2
        !           171:                char            last_command;
        !           172:                char            bytes_expected;
        !           173:                fd_params_t     *params;
        !           174: 
        !           175:        } slave_status[DRIVES_PER_FDC];
        !           176: } fd_softc_data[NFD];
        !           177: 
        !           178: typedef struct fd_softc        *fd_softc_t;
        !           179: 
        !           180: fd_softc_t     fd_softc[NFD];
        !           181: 
        !           182: static char *chip_names[4] = { "8272-A", "82072", "82077-AA", 0 };
        !           183: static char *mode_names[4] = { "PC AT", "PS/2", "Model 30", 0 };
        !           184: 
        !           185: /*
        !           186:  * Probe chip to see if it is there
        !           187:  */
        !           188: static fd_probe (reg, ctlr)
        !           189:        vm_offset_t     reg;
        !           190:        struct bus_ctlr *ctlr;
        !           191: {
        !           192:        int             unit = ctlr->unit;
        !           193:        fd_softc_t      fd;
        !           194:        fd_padded_regmap_t      *regs;
        !           195: 
        !           196:        /*
        !           197:         * See if we are here
        !           198:         */
        !           199:        if (check_memory(reg, 0)) {
        !           200:                /* no rides today */
        !           201:                return 0;
        !           202:        }
        !           203: 
        !           204:        fd = &fd_softc_data[unit];
        !           205:        fd_softc[unit] = fd;
        !           206: 
        !           207:        regs = (fd_padded_regmap_t *)reg;
        !           208:        fd->regs = regs;
        !           209:        fd->fdc_type = my_fdc_type;
        !           210: 
        !           211:        fd_reset(fd);
        !           212: 
        !           213:        if (the_fdc_type == fdc_82077aa) {
        !           214:                /* See if properly functioning */
        !           215:                unsigned char   temp = FD_CMD_VERSION;
        !           216:                if (!fd_go(fd, 0, &temp, 1, 1))
        !           217:                        return 0;       /* total brxage */
        !           218:                if (!fd_get_result(fd, &temp, 1, FALSE))
        !           219:                        return 0;       /* partial brxage */
        !           220:                if (temp != FD_VERSION_82077AA)
        !           221:                        printf( "{ %s x%x } ",
        !           222:                                "Accepting non-82077aa version id",
        !           223:                                temp);
        !           224:        }
        !           225: 
        !           226:        printf("%s%d: %s chip controller",
        !           227:                ctlr->name, ctlr->unit, chip_names[fd->fdc_type]);
        !           228:        if (the_fdc_type == fdc_82077aa)
        !           229:                printf(" in %s mode", mode_names[fd->fdc_mode]);
        !           230:        printf(".\n");
        !           231: 
        !           232:        return 1;
        !           233: }
        !           234: 
        !           235: /* See if we like this slave */
        !           236: static fd_slave(ui, reg)
        !           237:        struct bus_device       *ui;
        !           238:        vm_offset_t             reg;
        !           239: {
        !           240:        int                     slave = ui->slave;
        !           241:        fd_softc_t              fd;
        !           242:        unsigned char           sns[2];
        !           243: 
        !           244:        if (slave >= MAX_DRIVES) return 0;
        !           245: 
        !           246:        fd = fd_softc[ui->ctlr];
        !           247: 
        !           248:        sns[0] = FD_CMD_SENSE_DRIVE_STATUS;
        !           249:        sns[1] = slave & 0x3;
        !           250:        if (the_fdc_type == fdc_82072)
        !           251:                sns[1] |= FD_CMD_SDS_NO_MOT;
        !           252:        if (!fd_go(fd, slave, sns, 2, 1)) return 0;
        !           253:        if (!fd_get_result(fd, sns, 1, FALSE)) return 0;
        !           254: 
        !           255:        fd->slave_status[slave].st3 = sns[0];
        !           256: 
        !           257:        return 1;
        !           258: }
        !           259: 
        !           260: static void
        !           261: fd_attach (ui)
        !           262:        struct bus_device *ui;
        !           263: {
        !           264:        /* Attach a slave */
        !           265: }
        !           266: 
        !           267: static boolean_t
        !           268: fd_go(fd, slave, cmd, cmdlen, reply_count)
        !           269:        fd_softc_t      fd;
        !           270:        unsigned char   cmd[];
        !           271: {
        !           272: 
        !           273:        /* XXX check who active, enque ifnot */
        !           274: 
        !           275:        fd->slave_active = slave;
        !           276:        fd->slave_status[slave].bytes_expected = reply_count;
        !           277:        fd->slave_status[slave].last_command = *cmd;
        !           278:        return fd_command(fd, cmd, cmdlen);
        !           279: }
        !           280: 
        !           281: fd_intr (unit, spllevel)
        !           282: {
        !           283:        fd_softc_t      fd;
        !           284:        fd_padded_regmap_t *regs;
        !           285:        unsigned char   msr;
        !           286:        register struct slave_t *slv;
        !           287: 
        !           288: 
        !           289:        splx(spllevel);
        !           290: 
        !           291:        fd = fd_softc[unit];
        !           292:        regs = fd->regs;
        !           293: 
        !           294:        /* did polling see a media change */
        !           295:        /* busy bit in msr sez ifasync or not */
        !           296: 
        !           297:        msr = regs->fd_msr;
        !           298:        if ((msr & (FD_MSR_RQM|FD_MSR_DIO)) == (FD_MSR_RQM|FD_MSR_DIO)) {
        !           299: 
        !           300:                /* result phase */
        !           301: *(unsigned int *)0xbc040100 &= ~0x00600000;
        !           302: 
        !           303:                slv = &fd->slave_status[fd->slave_active];
        !           304:                fd_get_result(fd, &slv->st0, slv->bytes_expected, FALSE);
        !           305:                fd_start(fd, fd->slave_active, TRUE);
        !           306:                return;
        !           307:        }
        !           308:        /* async interrupt, either seek complete or media change */
        !           309:        while (1) {
        !           310:                unsigned char   st[2];
        !           311:                register int    slave, m;
        !           312: 
        !           313:                *st = FD_CMD_SENSE_INT_STATUS;
        !           314:                fd_command(fd, st, 1);
        !           315: 
        !           316:                fd_get_result(fd, st, 2, FALSE);
        !           317: 
        !           318:                slave = *st & FD_ST0_DS;
        !           319:                slv = &fd->slave_status[slave];
        !           320:                slv->c = st[1];
        !           321: 
        !           322:                switch (*st & FD_ST0_IC_MASK) {
        !           323: 
        !           324:                    case FD_ST0_IC_OK:
        !           325: /* we get an FD_ST0_SE for RECALIBRATE. Wait for it or discard ? */
        !           326: 
        !           327:                    case FD_ST0_IC_AT:
        !           328: 
        !           329:                    case FD_ST0_IC_BAD_CMD:
        !           330:                        return;
        !           331: 
        !           332:                    case FD_ST0_IC_AT_POLL:
        !           333:                        m = slv->medium_status;
        !           334:                        if (m & ST_MEDIUM_PRESENT)
        !           335:                                m &= ~ST_MEDIUM_PRESENT;
        !           336:                        else
        !           337:                                m |= ST_MEDIUM_PRESENT;
        !           338:                        slv->medium_status = m;
        !           339:                }
        !           340:        }
        !           341: }
        !           342: 
        !           343: /*
        !           344:  * Non-interface functions and utilities
        !           345:  */
        !           346: 
        !           347: fd_reset(fd)
        !           348:        fd_softc_t      fd;
        !           349: {
        !           350:        register        fd_padded_regmap_t      *regs;
        !           351: 
        !           352:        regs = fd->regs;
        !           353: 
        !           354:        /*
        !           355:         * Reset the chip
        !           356:         */
        !           357:        if (the_fdc_type == fdc_82072)
        !           358:                /* Fix if your box uses an external PLL */
        !           359:                regs->fd_dsr = FD_DSR_RESET | FD_DSR_EPLL;
        !           360:        else if (the_fdc_type == fdc_82077aa)
        !           361:                regs->fd_dor = 0;
        !           362:        else
        !           363:                machdep_reset_8272a(fd, regs);
        !           364: 
        !           365:        delay(5);       /* 4usecs in specs */
        !           366: 
        !           367:        /*
        !           368:         * Be smart with the smart ones
        !           369:         */
        !           370:        if (the_fdc_type == fdc_82077aa) {
        !           371: 
        !           372:                /*
        !           373:                 * See in which mood we are (it cannot be changed)
        !           374:                 */
        !           375:                int     temp;
        !           376: 
        !           377:                /* Take chip out of hw reset */
        !           378:                regs->fd_dor = FD_DOR_ENABLE | FD_DOR_DMA_GATE;
        !           379:                delay(10);
        !           380: 
        !           381:                /* what do we readback from the DIR register as datarate ? */
        !           382:                regs->fd_ccr = FD_DSR_SD_125;
        !           383:                delay(10);
        !           384: 
        !           385:                temp = regs->fd_dir;
        !           386:                if ((temp & 0x7) == FD_DSR_SD_125)
        !           387:                        fd->fdc_mode = mod30_mode;
        !           388:                else if ((temp & (FD_DIR_ones | FD_DIR_DR_MASK_PS2)) ==
        !           389:                         ((FD_DSR_SD_125 << FD_DIR_DR_SHIFT_PS2) | FD_DIR_ones))
        !           390:                        fd->fdc_mode = ps2_mode;
        !           391:                else
        !           392:                        /* this assumes tri-stated bits 1&2 read the same */
        !           393:                        fd->fdc_mode = at_mode;
        !           394: 
        !           395:        }
        !           396: 
        !           397:        /*
        !           398:         * Send at least 4 sense interrupt cmds, one per slave
        !           399:         */
        !           400:        {
        !           401: 
        !           402:                unsigned char   sns, st[2];
        !           403:                int             i, nloops;
        !           404: 
        !           405:                sns = FD_CMD_SENSE_INT_STATUS;
        !           406:                i   = nloops = 0;
        !           407: 
        !           408:                do {
        !           409:                        nloops++;
        !           410: 
        !           411:                        (void) fd_command(fd, &sns, 1);
        !           412: 
        !           413:                        st[0] = 0; /* in case bad status */
        !           414:                        (void) fd_get_result(fd, st, 2, TRUE);
        !           415: 
        !           416:                        if ((st[0] & FD_ST0_IC_MASK) == FD_ST0_IC_AT_POLL) {
        !           417:                                register int    slave;
        !           418: 
        !           419:                                slave = st[0] & FD_ST0_DS;
        !           420:                                fd->slave_status[slave].st0 = st[0];
        !           421:                                fd->slave_status[slave].c   = st[1];
        !           422:                                i++;
        !           423:                        }
        !           424:                } while ( (nloops < 30) &&
        !           425:                          ((i < 4) || (st[0] != FD_ST0_IC_BAD_CMD)) );
        !           426: 
        !           427:                /* sanity check */
        !           428:                if (nloops == 30) {
        !           429:                        (void) fd_messed_up(fd);
        !           430:                        return;
        !           431:                }
        !           432:        }
        !           433: 
        !           434:        /*
        !           435:         * Install current parameters
        !           436:         */
        !           437:        if (the_fdc_type != fdc_8272a) {
        !           438: 
        !           439:                unsigned char   cnf[4];
        !           440: 
        !           441:                /* send configure command to turn polling off */
        !           442:                cnf[0] = FD_CMD_CONFIGURE;
        !           443:                cnf[1] = 0x60; /* moff 110 */
        !           444:                cnf[2] = 0x48; /* eis, poll, thr=8 */
        !           445:                cnf[3] = 0;
        !           446:                if (!fd_command(fd, cnf, 4))
        !           447:                        return;
        !           448:                /* no status */
        !           449:        }
        !           450: 
        !           451:        /*
        !           452:         * Send specify to select defaults
        !           453:         */
        !           454:        {
        !           455:                unsigned char   sfy[3];
        !           456: 
        !           457:                sfy[0] = FD_CMD_SPECIFY;
        !           458: #if 0
        !           459:                sfy[1] = (12 << 4) | 7; /* step 4, hut 112us @500 */
        !           460:                sfy[2] = 2 << 1; /* hlt 29us @500 */
        !           461: #else
        !           462:                sfy[1] = (13 << 4) | 15;
        !           463:                sfy[2] = 1 << 1;
        !           464: #endif
        !           465:                (void) fd_command(fd, sfy, 3);
        !           466:                /* no status */
        !           467:        }
        !           468: }
        !           469: 
        !           470: #define        FD_MAX_WAIT     1000
        !           471: 
        !           472: boolean_t
        !           473: fd_command(fd, cmd, cmd_len)
        !           474:        fd_softc_t      fd;
        !           475:        char            *cmd;
        !           476: {
        !           477:        register fd_padded_regmap_t     *regs;
        !           478: 
        !           479:        regs = fd->regs;
        !           480: 
        !           481:        while (cmd_len > 0) {
        !           482:                register int i, s;
        !           483: 
        !           484:                /* there might be long delays, so we pay this price */
        !           485:                s = splhigh();
        !           486:                for (i = 0; i < FD_MAX_WAIT; i++)
        !           487:                        if ((regs->fd_msr & (FD_MSR_RQM|FD_MSR_DIO)) ==
        !           488:                            FD_MSR_RQM)
        !           489:                                break;
        !           490:                        else
        !           491:                                delay(10);
        !           492:                if (i == FD_MAX_WAIT) {
        !           493:                        splx(s);
        !           494:                        return fd_messed_up(fd);
        !           495:                }
        !           496:                regs->fd_data = *cmd++;
        !           497:                splx(s);
        !           498:                if (--cmd_len) delay(12);
        !           499:        }
        !           500: 
        !           501:        return TRUE;
        !           502: }
        !           503: 
        !           504: boolean_t
        !           505: fd_get_result(fd, st, st_len, ignore_errors)
        !           506:        fd_softc_t      fd;
        !           507:        char            *st;
        !           508: {
        !           509:        register fd_padded_regmap_t     *regs;
        !           510: 
        !           511:        regs = fd->regs;
        !           512: 
        !           513:        while (st_len > 0) {
        !           514:                register int i, s;
        !           515: 
        !           516:                /* there might be long delays, so we pay this price */
        !           517:                s = splhigh();
        !           518:                for (i = 0; i < FD_MAX_WAIT; i++)
        !           519:                        if ((regs->fd_msr & (FD_MSR_RQM|FD_MSR_DIO)) ==
        !           520:                            (FD_MSR_RQM|FD_MSR_DIO))
        !           521:                                break;
        !           522:                        else
        !           523:                                delay(10);
        !           524:                if (i == FD_MAX_WAIT) {
        !           525:                        splx(s);
        !           526:                        return (ignore_errors) ? FALSE : fd_messed_up(fd);
        !           527:                }
        !           528:                *st++ = regs->fd_data;
        !           529:                splx(s);
        !           530:                st_len--;
        !           531:        }
        !           532: 
        !           533:        return TRUE;
        !           534: }
        !           535: 
        !           536: 
        !           537: boolean_t
        !           538: fd_messed_up(fd)
        !           539:        fd_softc_t      fd;
        !           540: {
        !           541:        fd->messed_up++;
        !           542:        printf("fd%d: messed up, disabling.\n", fd - fd_softc_data);
        !           543:        /* here code to 
        !           544:                ior->error = ..;
        !           545:                restart
        !           546:         */
        !           547:        return FALSE;
        !           548: }
        !           549: 
        !           550: /*
        !           551:  * Debugging aids
        !           552:  */
        !           553: 
        !           554: fd_state(unit)
        !           555: {
        !           556:        fd_softc_t      fd = fd_softc[unit];
        !           557:        fd_padded_regmap_t      *regs;
        !           558: 
        !           559:        if (!fd || !fd->regs) return 0;
        !           560:        regs = fd->regs;
        !           561:        if (the_fdc_type == fdc_8272a)
        !           562:                printf("msr %x\n", regs->fd_msr);
        !           563:        else
        !           564:                printf("sra %x srb %x dor %x tdr %x msr %x dir %x\n",
        !           565:                        regs->fd_sra, regs->fd_srb, regs->fd_dor,
        !           566:                        regs->fd_tdr, regs->fd_msr, regs->fd_dir);
        !           567: }
        !           568: 
        !           569: #endif
        !           570: 
        !           571: /*   to be moved in separate file, or the above modified to live with scsi */
        !           572: 
        !           573: fd_open(dev, mode, ior)
        !           574:        int             dev;
        !           575:        dev_mode_t      mode;
        !           576:        io_req_t        ior;
        !           577: {
        !           578:        unsigned char   cmd[2];
        !           579:        fd_softc_t      fd;
        !           580:        int             slave;
        !           581: 
        !           582:        fd = fd_softc[UNITNO(dev)];
        !           583:        slave = SLAVENO(dev);
        !           584: 
        !           585:        /* XXX find out what medium we have, automagically XXX */
        !           586:        /* fornow, set params depending on minor */
        !           587:        fd->slave_status[slave].params = &fd_params[PARAMNO(dev)];
        !           588: 
        !           589:        /* XXXYYYXXXYYY SEND CONFIGURE if params changed */
        !           590: 
        !           591:        /* Turn motor on */
        !           592:        if (the_fdc_type == fdc_82072) {
        !           593: 
        !           594:                cmd[0] = FD_CMD_MOTOR_ON_OFF | FD_CMD_MOT_ON |
        !           595:                         ((slave << FD_CMD_MOT_DS_SHIFT) & FD_CMD_MOT_DS);
        !           596:                (void) fd_go(fd, slave, cmd, 1, 0);
        !           597:                /* no status */
        !           598: 
        !           599:        } else if (the_fdc_type == fdc_82077aa) {
        !           600: 
        !           601:                fd->regs->fd_dor |= ((1<<slave)<<4);
        !           602:        }
        !           603: 
        !           604:        /* recalibrate to track 0 */
        !           605:        cmd[0] = FD_CMD_RECALIBRATE;
        !           606:        cmd[1] = slave;
        !           607:        if (!fd_go(fd, slave, cmd, 2, 0))
        !           608:                return D_DEVICE_DOWN;
        !           609:        /* will generate a completion interrupt */
        !           610: 
        !           611:        /* if not writeable return D_READ_ONLY ? */
        !           612: 
        !           613:        return D_SUCCESS;
        !           614: }
        !           615: 
        !           616: fd_close(dev)
        !           617:        int             dev;
        !           618: {
        !           619:         fd_softc_t      fd;
        !           620:        register int    slave;
        !           621:        unsigned char   cmd[2];
        !           622: 
        !           623:         slave = SLAVENO(dev);
        !           624:         fd = fd_softc[UNITNO(dev)];
        !           625: 
        !           626:        /* do not delete media info, do that iff interrupt sez changed */
        !           627: 
        !           628:        /* Turn motor off */
        !           629:        if (the_fdc_type == fdc_82072) {
        !           630: 
        !           631:                cmd[0] = FD_CMD_MOTOR_ON_OFF |
        !           632:                         ((slave << FD_CMD_MOT_DS_SHIFT) & FD_CMD_MOT_DS);
        !           633:                (void) fd_go(fd, 0, cmd, 1, 0);
        !           634:                /* no status */
        !           635: 
        !           636:        } else if (the_fdc_type == fdc_82077aa) {
        !           637: 
        !           638:                fd->regs->fd_dor &= ~((1<<slave)<<4);
        !           639:        }
        !           640:        return D_SUCCESS;
        !           641: }
        !           642: 
        !           643: fd_strategy(ior)
        !           644:        io_req_t        ior;
        !           645: {
        !           646: #if 0
        !           647:        if (ior->io_op & IO_READ)
        !           648:                bzero(ior->io_data, ior->io_count);
        !           649:        iodone(ior);
        !           650: #else
        !           651:        struct slave_t  *slv;
        !           652:         fd_softc_t      fd;
        !           653:        unsigned int    i, rec, max, dev;
        !           654:        fd_params_t     *params;
        !           655: 
        !           656:        /* readonly */
        !           657: 
        !           658:        dev = ior->io_unit;
        !           659: 
        !           660:        /* only one partition */
        !           661:        fd = fd_softc[UNITNO(dev)];
        !           662:        slv = &fd->slave_status[SLAVENO(dev)];
        !           663:        params = slv->params;
        !           664:        max = params->d_secperunit;
        !           665:        rec = ior->io_recnum;
        !           666:        i = btodb(ior->io_count + DEV_BSIZE - 1);
        !           667:        if (((rec + i) > max) || (ior->io_count < 0)) {
        !           668:                ior->io_error = D_INVALID_SIZE;
        !           669:                ior->io_op |= IO_ERROR;
        !           670:                ior->io_residual = ior->io_count;
        !           671:                iodone(ior);
        !           672:                return;
        !           673:        }
        !           674: 
        !           675:        ior->io_residual = rec / params->d_secpercyl;
        !           676: 
        !           677:        /*
        !           678:         * Enqueue operation 
        !           679:         */
        !           680:        i = splbio();
        !           681:        simple_lock(&slv->slave_lock);
        !           682:        if (slv->ior) {
        !           683:                disksort(slv->ior, ior);
        !           684:                simple_unlock(&slv->slave_lock);
        !           685:        } else {
        !           686:                ior->io_next = 0;
        !           687:                slv->ior = ior;
        !           688:                simple_unlock(&slv->slave_lock);
        !           689:                fd_start(fd, SLAVENO(dev), FALSE);
        !           690:        }
        !           691:        splx(i);
        !           692: #endif
        !           693: }
        !           694: 
        !           695: fd_start(fd, slave, done)
        !           696:        boolean_t       done;
        !           697:         fd_softc_t      fd;
        !           698: {
        !           699:        register io_req_t       ior;
        !           700:        struct slave_t  *slv;
        !           701: 
        !           702:        slv = &fd->slave_status[slave];
        !           703:        if ((ior = slv->ior) == 0)
        !           704:                return;
        !           705: 
        !           706:        if (done) {
        !           707:                /* .. errors .. */
        !           708:                /* .. partial xfers .. */
        !           709: 
        !           710:                /* dequeue next one */
        !           711:                {
        !           712:                        io_req_t        next;
        !           713: 
        !           714:                        simple_lock(&slv->target_lock);
        !           715:                        next = ior->io_next;
        !           716:                        slv->ior = next;
        !           717:                        simple_unlock(&slv->target_lock);
        !           718: 
        !           719:                        iodone(ior);
        !           720:                        if (next == 0)
        !           721:                                return;
        !           722: 
        !           723:                        ior = next;
        !           724:                }
        !           725:        }
        !           726: 
        !           727: #ifdef no_eis
        !           728:        if (slv->c != ior->io_residual) SEEK_it;
        !           729: #endif
        !           730: 
        !           731: /*     setup dma       */
        !           732: #if 1
        !           733:        if (ior->io_op & IO_READ)       /* like SCSI */
        !           734: #else
        !           735:        if ((ior->io_op & IO_READ) == 0)
        !           736: #endif
        !           737:        {
        !           738:                *(unsigned int *)0xbc040100 |= 0x00200000 | 0x00400000;
        !           739:        } else {
        !           740:                *(unsigned int *)0xbc040100 &= ~0x00400000;
        !           741:                *(unsigned int *)0xbc040100 |= 0x00200000;
        !           742:        }
        !           743:        *(unsigned int *)0xbc040070 = (((unsigned int)kvtophys(ior->io_data))>>2)<<5;
        !           744:        *(unsigned int *)0xbc0401a0 = 13;
        !           745: 
        !           746: #ifdef no_eis
        !           747:        if (slv->c == ior->io_residual) {
        !           748: #else
        !           749:        {
        !           750: #endif
        !           751:                unsigned char   cmd[9];
        !           752:                unsigned char   head, sec;
        !           753:                fd_params_t     *params;
        !           754: 
        !           755:                params = slv->params;
        !           756: 
        !           757:                fd->regs->fd_dsr = params->d_xfer_rate;
        !           758: 
        !           759:                sec = ior->io_recnum % params->d_secpercyl;
        !           760:                head = sec / params->d_secpertrk;
        !           761:                sec = (sec % params->d_secpertrk);
        !           762: 
        !           763:                cmd[0] = (ior->io_op & IO_READ) ?
        !           764:                                FD_CMD_MT | FD_CMD_MFM | FD_CMD_READ_DATA :
        !           765:                                FD_CMD_MT | FD_CMD_MFM | FD_CMD_WRITE_DATA;
        !           766:                cmd[1] = (head << 2) | slave;
        !           767:                cmd[2] = ior->io_residual;
        !           768:                cmd[3] = head;
        !           769:                cmd[4] = sec + 1;       /* 0 starts at 1 :-) */
        !           770:                cmd[5] = 0x2;           /* 512 byte sectors */
        !           771:                cmd[6] = params->d_secpertrk;
        !           772:                cmd[7] = params->d_gpl;
        !           773:                cmd[8] = 0xff;
        !           774: 
        !           775:                fd_go( fd, slave, cmd, 9, 7);
        !           776: 
        !           777:        }
        !           778: }
        !           779: 
        !           780: extern minphys();
        !           781: 
        !           782: fd_read(dev, ior)
        !           783:        int             dev;
        !           784:        io_req_t        ior;
        !           785: {
        !           786:        return block_io(fd_strategy, minphys, ior);
        !           787: }
        !           788: 
        !           789: int fdc_write_enable = 1;
        !           790: 
        !           791: fd_write(dev, ior)
        !           792:        int             dev;
        !           793:        io_req_t        ior;
        !           794: {
        !           795: /*     check if writeable */
        !           796: 
        !           797: if (fdc_write_enable)
        !           798:        return block_io(fd_strategy, minphys, ior);
        !           799: else return D_SUCCESS;
        !           800: }
        !           801: 
        !           802: fd_set_status(dev, flavor, status, status_count)
        !           803:        int             dev;
        !           804:        int             flavor;
        !           805:        dev_status_t    status;
        !           806:        unsigned int    *status_count;
        !           807: {
        !           808:        printf("fdc_set_status(%x, %x, %x, %x)", dev, flavor, status, status_count);
        !           809:        return D_SUCCESS;
        !           810: }
        !           811: 
        !           812: fd_get_status(dev, flavor, status, status_count)
        !           813:        int             dev;
        !           814:        int             flavor;
        !           815:        dev_status_t    status;
        !           816:        unsigned int    status_count;
        !           817: {
        !           818:        printf("fdc_get_status(%x, %x, %x, %x)", dev, flavor, status, status_count);
        !           819:        return D_SUCCESS;
        !           820: }
        !           821: 

unix.superglobalmegacorp.com

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