Annotation of Net2/arch/i386/stand/fd.c, revision 1.1.1.1

1.1       root        1: /*-
                      2:  * Copyright (c) 1990 The Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * This code is derived from software contributed to Berkeley by
                      6:  * Don Ahn.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  * 3. All advertising materials mentioning features or use of this software
                     17:  *    must display the following acknowledgement:
                     18:  *     This product includes software developed by the University of
                     19:  *     California, Berkeley and its contributors.
                     20:  * 4. Neither the name of the University nor the names of its contributors
                     21:  *    may be used to endorse or promote products derived from this software
                     22:  *    without specific prior written permission.
                     23:  *
                     24:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     25:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     26:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     27:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     28:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     29:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     30:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     31:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     32:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     33:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     34:  * SUCH DAMAGE.
                     35:  *
                     36:  *     @(#)fd.c        7.3 (Berkeley) 5/25/91
                     37:  */
                     38: 
                     39: /****************************************************************************/
                     40: /*                        standalone fd driver                               */
                     41: /****************************************************************************/
                     42: #include "param.h"
                     43: #include "dkbad.h"
                     44: #include "i386/isa/disk.h"
                     45: #include "i386/isa/fdreg.h"
                     46: #include "i386/isa/isa.h"
                     47: #include "saio.h"
                     48: 
                     49: #define NUMRETRY 10
                     50: /*#define FDDEBUG*/
                     51: 
                     52: #define NFD 2
                     53: #define FDBLK 512
                     54: #define NUMTYPES 4
                     55: 
                     56: struct fd_type {
                     57:        int     sectrac;                /* sectors per track         */
                     58:        int     secsize;                /* size code for sectors     */
                     59:        int     datalen;                /* data len when secsize = 0 */
                     60:        int     gap;                    /* gap len between sectors   */
                     61:        int     tracks;                 /* total num of tracks       */
                     62:        int     size;                   /* size of disk in sectors   */
                     63:        int     steptrac;               /* steps per cylinder        */
                     64:        int     trans;                  /* transfer speed code       */
                     65: };
                     66: 
                     67: struct fd_type fd_types[NUMTYPES] = {
                     68:        { 18,2,0xFF,0x1B,80,2880,1,0 }, /* 1.44 meg HD 3.5in floppy    */
                     69:        { 15,2,0xFF,0x1B,80,2400,1,0 }, /* 1.2 meg HD floppy           */
                     70:        { 9,2,0xFF,0x23,40,720,2,1 },   /* 360k floppy in 1.2meg drive */
                     71:        { 9,2,0xFF,0x2A,40,720,1,1 },   /* 360k floppy in DD drive     */
                     72: };
                     73: 
                     74: 
                     75: /* state needed for current transfer */
                     76: static int fd_type;
                     77: static int fd_motor;
                     78: static int fd_retry;
                     79: static int fd_drive;
                     80: static int fd_status[7];
                     81: 
                     82: static int fdc = IO_FD1;       /* floppy disk base */
                     83: 
                     84: /* Make sure DMA buffer doesn't cross 64k boundary */
                     85: char bounce[FDBLK];
                     86: 
                     87: 
                     88: /****************************************************************************/
                     89: /*                               fdstrategy                                 */
                     90: /****************************************************************************/
                     91: int
                     92: fdstrategy(io,func)
                     93: register struct iob *io;
                     94: int func;
                     95: {
                     96:        char *address;
                     97:        long nblocks,blknum;
                     98:        int unit, iosize;
                     99: 
                    100: #ifdef FDDEBUG
                    101: printf("fdstrat ");
                    102: #endif
                    103:        unit = io->i_unit;
                    104:        fd_type = io->i_part;
                    105: 
                    106:        /*
                    107:         * Set up block calculations.
                    108:         */
                    109:         iosize = io->i_cc / FDBLK;
                    110:        blknum = (unsigned long) io->i_bn * DEV_BSIZE / FDBLK;
                    111:        nblocks = fd_types[fd_type].size;
                    112:        if ((blknum + iosize > nblocks) || blknum < 0) {
                    113: #ifndef SMALL
                    114:                printf("bn = %d; sectors = %d; type = %d; fssize = %d ",
                    115:                        blknum, iosize, fd_type, nblocks);
                    116:                 printf("fdstrategy - I/O out of filesystem boundaries\n");
                    117: #endif
                    118:                return(-1);
                    119:        }
                    120: 
                    121:        address = io->i_ma;
                    122:         while (iosize > 0) {
                    123:                 if (fdio(func, unit, blknum, address))
                    124:                         return(-1);
                    125:                iosize--;
                    126:                blknum++;
                    127:                 address += FDBLK;
                    128:         }
                    129:         return(io->i_cc);
                    130: }
                    131: 
                    132: int
                    133: fdio(func, unit, blknum, address)
                    134: int func,unit,blknum;
                    135: char *address;
                    136: {
                    137:        int i,j,cyl,sectrac,sec,head,numretry;
                    138:        struct fd_type *ft;
                    139: 
                    140:        ft = &fd_types[fd_type];
                    141: #ifdef FDDEBUG
                    142: printf("fdio ");
                    143: #endif
                    144: 
                    145:        sectrac = ft->sectrac;
                    146:        cyl = blknum / (2 * sectrac);
                    147:        numretry = NUMRETRY;
                    148: 
                    149:        if (func == F_WRITE) bcopy(address,bounce,FDBLK);
                    150: 
                    151: retry:
                    152:        out_fdc(15);    /* Seek function */
                    153:        out_fdc(unit);  /* Drive number */
                    154:        out_fdc(cyl);
                    155: 
                    156:        waitio();
                    157: 
                    158:        out_fdc(0x8);
                    159:        i = in_fdc(); j = in_fdc();
                    160:        if (!(i&0x20) || (cyl != j)) {
                    161:                numretry--;
                    162:                if (numretry) goto retry;
                    163: #ifndef SMALL
                    164:                printf("Seek error %d, req = %d, at = %d\n",i,cyl,j);
                    165:                printf("unit %d, type %d, sectrac %d, blknum %d\n",
                    166:                        unit,fd_type,sectrac,blknum);
                    167: #endif
                    168:                return -1;
                    169:        }
                    170: 
                    171:        /* set up transfer */
                    172:        fd_dma(func == F_READ, bounce, FDBLK);
                    173:        sec = blknum %  (sectrac * 2);
                    174:        head = sec / sectrac;
                    175:        sec = sec % sectrac + 1;
                    176: #ifdef FDDEBUG
                    177:        printf("sec %d hd %d cyl %d ", sec, head, cyl);
                    178: #endif
                    179: 
                    180:        if (func == F_READ)  out_fdc(0xE6);/* READ */
                    181:        else out_fdc(0xC5);             /* WRITE */
                    182:        out_fdc(head << 2 | fd_drive);  /* head & unit */
                    183:        out_fdc(cyl);                   /* track */
                    184:        out_fdc(head);
                    185:        out_fdc(sec);                   /* sector XXX +1? */
                    186:        out_fdc(ft->secsize);           /* sector size */
                    187:        out_fdc(sectrac);               /* sectors/track */
                    188:        out_fdc(ft->gap);               /* gap size */
                    189:        out_fdc(ft->datalen);           /* data length */
                    190: 
                    191:        waitio();
                    192: 
                    193:        for(i=0;i<7;i++) {
                    194:                fd_status[i] = in_fdc();
                    195:        }
                    196:        if (fd_status[0]&0xF8) {
                    197:                numretry--;
                    198:                if (numretry) goto retry;
                    199: #ifndef SMALL
                    200:                printf("FD err %lx %lx %lx %lx %lx %lx %lx\n",
                    201:                fd_status[0], fd_status[1], fd_status[2], fd_status[3],
                    202:                fd_status[4], fd_status[5], fd_status[6] );
                    203: #endif
                    204:                return -1;
                    205:        }
                    206:        if (func == F_READ) bcopy(bounce,address,FDBLK);
                    207:        return 0;
                    208: }
                    209: 
                    210: /****************************************************************************/
                    211: /*                             fdc in/out                                   */
                    212: /****************************************************************************/
                    213: int
                    214: in_fdc()
                    215: {
                    216:        int i;
                    217:        while ((i = inb(fdc+fdsts) & 192) != 192) if (i == 128) return -1;
                    218:        return inb(0x3f5);
                    219: }
                    220: 
                    221: dump_stat()
                    222: {
                    223:        int i;
                    224:        for(i=0;i<7;i++) {
                    225:                fd_status[i] = in_fdc();
                    226:                if (fd_status[i] < 0) break;
                    227:        }
                    228: #ifdef FDDEBUGx
                    229: printf("FD bad status :%lx %lx %lx %lx %lx %lx %lx\n",
                    230:        fd_status[0], fd_status[1], fd_status[2], fd_status[3],
                    231:        fd_status[4], fd_status[5], fd_status[6] );
                    232: #endif
                    233: }
                    234: 
                    235: set_intr()
                    236: {
                    237:        /* initialize 8259's */
                    238:        outb(0x20,0x11);
                    239:        outb(0x21,32);
                    240:        outb(0x21,4);
                    241:        outb(0x21,1);
                    242:        outb(0x21,0x0f); /* turn on int 6 */
                    243: 
                    244: /*
                    245:        outb(0xa0,0x11);
                    246:        outb(0xa1,40);
                    247:        outb(0xa1,2);
                    248:        outb(0xa1,1);
                    249:        outb(0xa1,0xff); */
                    250: 
                    251: }
                    252: 
                    253: 
                    254: 
                    255: waitio()
                    256: {
                    257: char c;
                    258: int n;
                    259: 
                    260:        do
                    261:                outb(0x20,0xc); /* read polled interrupt */
                    262:        while ((c=inb(0x20))&0x7f != 6); /* wait for int */
                    263:        outb(0x20,0x20);
                    264: }
                    265: 
                    266: out_fdc(x)
                    267: int x;
                    268: {
                    269:        int r;
                    270:        do {
                    271:                r = (inb(fdc+fdsts) & 192);
                    272:                if (r==128) break;
                    273:                if (r==192) {
                    274:                        dump_stat(); /* error: direction. eat up output */
                    275:                }
                    276:        } while (1);
                    277:        outb(0x3f5,x&0xFF);
                    278: }
                    279: 
                    280: 
                    281: /****************************************************************************/
                    282: /*                           fdopen/fdclose                                 */
                    283: /****************************************************************************/
                    284: fdopen(io)
                    285:        register struct iob *io;
                    286: {
                    287:        int unit, type, i;
                    288:        struct fd_type *ft;
                    289: 
                    290:        unit = io->i_unit;
                    291:        type = io->i_part;
                    292:        io->i_boff = 0;         /* no disklabels -- tar/dump wont work */
                    293: #ifdef FDDEBUG
                    294:        printf("fdopen %d %d ", unit, type);
                    295: #endif
                    296:        ft = &fd_types[type];
                    297:        fd_drive = unit;
                    298: 
                    299:        set_intr(); /* init intr cont */
                    300: 
                    301:        /* Try a reset, keep motor on */
                    302:        outb(0x3f2,0);
                    303:        for(i=0; i < 100000; i++);
                    304:        outb(0x3f2,unit | (unit  ? 32 : 16) );
                    305:        for(i=0; i < 100000; i++);
                    306:        outb(0x3f2,unit | 0xC | (unit  ? 32 : 16) );
                    307:        outb(0x3f7,ft->trans);
                    308:        fd_motor = 1;
                    309: 
                    310:        waitio();
                    311: 
                    312:        out_fdc(3); /* specify command */
                    313:        out_fdc(0xDF);
                    314:        out_fdc(2);
                    315: 
                    316:        out_fdc(7);     /* Recalibrate Function */
                    317:        out_fdc(unit);
                    318: 
                    319:        waitio();
                    320:        return(0);
                    321: }
                    322: 
                    323: 
                    324: /****************************************************************************/
                    325: /*                                 fd_dma                                   */
                    326: /* set up DMA read/write operation and virtual address addr for nbytes      */
                    327: /****************************************************************************/
                    328: fd_dma(read,addr,nbytes)
                    329: int read;
                    330: unsigned long addr;
                    331: int nbytes;
                    332: {
                    333:        /* Set read/write bytes */
                    334:        if (read) {
                    335:                outb(0xC,0x46); outb(0xB,0x46);
                    336:        } else {
                    337:                outb(0xC,0x4A); outb(0xB,0x4A);
                    338:        }
                    339:        /* Send start address */
                    340:        outb(0x4,addr & 0xFF);
                    341:        outb(0x4,(addr>>8) & 0xFF);
                    342:        outb(0x81,(addr>>16) & 0xFF);
                    343:        /* Send count */
                    344:        nbytes--;
                    345:        outb(0x5,nbytes & 0xFF);
                    346:        outb(0x5,(nbytes>>8) & 0xFF);
                    347:        /* set channel 2 */
                    348:        outb(0x0A,2);
                    349: }
                    350: 

unix.superglobalmegacorp.com

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