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

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

unix.superglobalmegacorp.com

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