Annotation of Gnu-Mach/chips/fdc_82077_hdw.c, revision 1.1.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.