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

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:  *
1.1.1.4 ! root       36:  *     from: @(#)fd.c  7.3 (Berkeley) 5/25/91
        !            37:  *     fd.c,v 1.2 1993/05/22 08:02:14 cgd Exp
1.1       root       38:  */
                     39: 
                     40: /****************************************************************************/
                     41: /*                        standalone fd driver                               */
                     42: /****************************************************************************/
                     43: #include "param.h"
1.1.1.2   root       44: #include "disklabel.h"
1.1       root       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: 
1.1.1.2   root       55: extern struct disklabel disklabel;
                     56: 
1.1       root       57: struct fd_type {
                     58:        int     sectrac;                /* sectors per track         */
                     59:        int     secsize;                /* size code for sectors     */
                     60:        int     datalen;                /* data len when secsize = 0 */
                     61:        int     gap;                    /* gap len between sectors   */
                     62:        int     tracks;                 /* total num of tracks       */
                     63:        int     size;                   /* size of disk in sectors   */
                     64:        int     steptrac;               /* steps per cylinder        */
                     65:        int     trans;                  /* transfer speed code       */
                     66: };
                     67: 
1.1.1.3   root       68: struct fd_type fd_types[] = {
1.1       root       69:        { 18,2,0xFF,0x1B,80,2880,1,0 }, /* 1.44 meg HD 3.5in floppy    */
                     70:        { 15,2,0xFF,0x1B,80,2400,1,0 }, /* 1.2 meg HD floppy           */
1.1.1.3   root       71:        /* need 720K 3.5in here as well */
                     72: #ifdef noway
1.1       root       73:        { 9,2,0xFF,0x23,40,720,2,1 },   /* 360k floppy in 1.2meg drive */
                     74:        { 9,2,0xFF,0x2A,40,720,1,1 },   /* 360k floppy in DD drive     */
1.1.1.3   root       75: #endif
1.1       root       76: };
                     77: 
                     78: 
                     79: /* state needed for current transfer */
1.1.1.3   root       80: static int probetype;
1.1       root       81: static int fd_type;
                     82: static int fd_motor;
                     83: static int fd_retry;
                     84: static int fd_drive;
                     85: static int fd_status[7];
                     86: 
                     87: static int fdc = IO_FD1;       /* floppy disk base */
                     88: 
                     89: /* Make sure DMA buffer doesn't cross 64k boundary */
                     90: char bounce[FDBLK];
                     91: 
                     92: 
                     93: /****************************************************************************/
                     94: /*                               fdstrategy                                 */
                     95: /****************************************************************************/
                     96: int
                     97: fdstrategy(io,func)
                     98: register struct iob *io;
                     99: int func;
                    100: {
                    101:        char *address;
                    102:        long nblocks,blknum;
                    103:        int unit, iosize;
                    104: 
                    105: #ifdef FDDEBUG
                    106: printf("fdstrat ");
                    107: #endif
                    108:        unit = io->i_unit;
1.1.1.3   root      109:        /*fd_type = io->i_part;*/
1.1       root      110: 
                    111:        /*
                    112:         * Set up block calculations.
                    113:         */
                    114:         iosize = io->i_cc / FDBLK;
                    115:        blknum = (unsigned long) io->i_bn * DEV_BSIZE / FDBLK;
1.1.1.3   root      116:        nblocks = fd_types[fd_type].size /*  disklabel.d_secperunit */;
1.1       root      117:        if ((blknum + iosize > nblocks) || blknum < 0) {
1.1.1.3   root      118: #ifdef nope
1.1       root      119:                printf("bn = %d; sectors = %d; type = %d; fssize = %d ",
                    120:                        blknum, iosize, fd_type, nblocks);
                    121:                 printf("fdstrategy - I/O out of filesystem boundaries\n");
                    122: #endif
                    123:                return(-1);
                    124:        }
                    125: 
                    126:        address = io->i_ma;
                    127:         while (iosize > 0) {
1.1.1.2   root      128: /*printf("iosize %d ", iosize);*/
1.1       root      129:                 if (fdio(func, unit, blknum, address))
                    130:                         return(-1);
                    131:                iosize--;
                    132:                blknum++;
                    133:                 address += FDBLK;
                    134:         }
                    135:         return(io->i_cc);
                    136: }
                    137: 
1.1.1.3   root      138: int ccyl = -1;
                    139: 
1.1       root      140: int
                    141: fdio(func, unit, blknum, address)
                    142: int func,unit,blknum;
                    143: char *address;
                    144: {
1.1.1.3   root      145:        int i,j, cyl, sectrac,sec,head,numretry;
1.1       root      146:        struct fd_type *ft;
                    147: 
1.1.1.2   root      148: /*printf("fdio ");*/
1.1       root      149:        ft = &fd_types[fd_type];
                    150: 
1.1.1.3   root      151:        sectrac = ft->sectrac;
                    152:        cyl = blknum / (sectrac*2);
1.1       root      153:        numretry = NUMRETRY;
                    154: 
1.1.1.3   root      155:        if (func == F_WRITE)
                    156:                bcopy(address,bounce,FDBLK);
1.1       root      157: 
                    158: retry:
1.1.1.3   root      159:        if (ccyl != cyl) {
1.1       root      160:        out_fdc(15);    /* Seek function */
                    161:        out_fdc(unit);  /* Drive number */
                    162:        out_fdc(cyl);
                    163: 
                    164:        waitio();
1.1.1.3   root      165:        }
1.1       root      166: 
                    167:        out_fdc(0x8);
                    168:        i = in_fdc(); j = in_fdc();
                    169:        if (!(i&0x20) || (cyl != j)) {
                    170:                numretry--;
1.1.1.3   root      171:                ccyl = j;
1.1       root      172:                if (numretry) goto retry;
1.1.1.3   root      173: 
1.1       root      174:                printf("Seek error %d, req = %d, at = %d\n",i,cyl,j);
                    175:                printf("unit %d, type %d, sectrac %d, blknum %d\n",
                    176:                        unit,fd_type,sectrac,blknum);
1.1.1.3   root      177: 
1.1       root      178:                return -1;
                    179:        }
1.1.1.3   root      180:        ccyl = cyl;
1.1       root      181: 
                    182:        /* set up transfer */
                    183:        fd_dma(func == F_READ, bounce, FDBLK);
1.1.1.3   root      184:        sec = blknum %  (sectrac * 2) /*disklabel.d_secpercyl*/;
1.1       root      185:        head = sec / sectrac;
                    186:        sec = sec % sectrac + 1;
                    187: #ifdef FDDEBUG
                    188:        printf("sec %d hd %d cyl %d ", sec, head, cyl);
                    189: #endif
                    190: 
                    191:        if (func == F_READ)  out_fdc(0xE6);/* READ */
                    192:        else out_fdc(0xC5);             /* WRITE */
                    193:        out_fdc(head << 2 | fd_drive);  /* head & unit */
                    194:        out_fdc(cyl);                   /* track */
                    195:        out_fdc(head);
1.1.1.3   root      196:        out_fdc(sec);                   /* sector */
1.1       root      197:        out_fdc(ft->secsize);           /* sector size */
                    198:        out_fdc(sectrac);               /* sectors/track */
                    199:        out_fdc(ft->gap);               /* gap size */
                    200:        out_fdc(ft->datalen);           /* data length */
                    201: 
                    202:        waitio();
                    203: 
                    204:        for(i=0;i<7;i++) {
                    205:                fd_status[i] = in_fdc();
                    206:        }
                    207:        if (fd_status[0]&0xF8) {
                    208:                numretry--;
1.1.1.3   root      209: 
                    210:                if (!probetype)
                    211:                        printf("FD err %lx %lx %lx %lx %lx %lx %lx\n",
                    212:                        fd_status[0], fd_status[1], fd_status[2], fd_status[3],
                    213:                        fd_status[4], fd_status[5], fd_status[6] );
1.1.1.2   root      214:                if (numretry) goto retry;
1.1       root      215:                return -1;
                    216:        }
1.1.1.3   root      217:        if (func == F_READ)
                    218:                bcopy(bounce,address,FDBLK);
1.1       root      219:        return 0;
                    220: }
                    221: 
                    222: /****************************************************************************/
                    223: /*                             fdc in/out                                   */
                    224: /****************************************************************************/
                    225: int
                    226: in_fdc()
                    227: {
                    228:        int i;
                    229:        while ((i = inb(fdc+fdsts) & 192) != 192) if (i == 128) return -1;
                    230:        return inb(0x3f5);
                    231: }
                    232: 
                    233: dump_stat()
                    234: {
                    235:        int i;
                    236:        for(i=0;i<7;i++) {
                    237:                fd_status[i] = in_fdc();
                    238:                if (fd_status[i] < 0) break;
                    239:        }
                    240: #ifdef FDDEBUGx
                    241: printf("FD bad status :%lx %lx %lx %lx %lx %lx %lx\n",
                    242:        fd_status[0], fd_status[1], fd_status[2], fd_status[3],
                    243:        fd_status[4], fd_status[5], fd_status[6] );
                    244: #endif
                    245: }
                    246: 
                    247: set_intr()
                    248: {
                    249:        /* initialize 8259's */
                    250:        outb(0x20,0x11);
                    251:        outb(0x21,32);
                    252:        outb(0x21,4);
                    253:        outb(0x21,1);
                    254:        outb(0x21,0x0f); /* turn on int 6 */
                    255: 
                    256: /*
                    257:        outb(0xa0,0x11);
                    258:        outb(0xa1,40);
                    259:        outb(0xa1,2);
                    260:        outb(0xa1,1);
                    261:        outb(0xa1,0xff); */
                    262: 
                    263: }
                    264: 
                    265: 
                    266: 
                    267: waitio()
                    268: {
                    269: char c;
                    270: int n;
                    271: 
                    272:        do
                    273:                outb(0x20,0xc); /* read polled interrupt */
                    274:        while ((c=inb(0x20))&0x7f != 6); /* wait for int */
                    275:        outb(0x20,0x20);
                    276: }
                    277: 
                    278: out_fdc(x)
                    279: int x;
                    280: {
                    281:        int r;
                    282:        do {
                    283:                r = (inb(fdc+fdsts) & 192);
                    284:                if (r==128) break;
                    285:                if (r==192) {
                    286:                        dump_stat(); /* error: direction. eat up output */
                    287:                }
                    288:        } while (1);
                    289:        outb(0x3f5,x&0xFF);
                    290: }
                    291: 
                    292: 
                    293: /****************************************************************************/
                    294: /*                           fdopen/fdclose                                 */
                    295: /****************************************************************************/
                    296: fdopen(io)
                    297:        register struct iob *io;
                    298: {
                    299:        int unit, type, i;
                    300:        struct fd_type *ft;
1.1.1.3   root      301:        char buf[512];
1.1       root      302: 
                    303:        unit = io->i_unit;
1.1.1.3   root      304:        /* type = io->i_part; */
1.1       root      305:        io->i_boff = 0;         /* no disklabels -- tar/dump wont work */
                    306: #ifdef FDDEBUG
                    307:        printf("fdopen %d %d ", unit, type);
                    308: #endif
1.1.1.3   root      309:        ft = &fd_types[0];
1.1       root      310:        fd_drive = unit;
                    311: 
                    312:        set_intr(); /* init intr cont */
                    313: 
                    314:        /* Try a reset, keep motor on */
                    315:        outb(0x3f2,0);
                    316:        for(i=0; i < 100000; i++);
                    317:        outb(0x3f2,unit | (unit  ? 32 : 16) );
                    318:        for(i=0; i < 100000; i++);
                    319:        outb(0x3f2,unit | 0xC | (unit  ? 32 : 16) );
                    320:        outb(0x3f7,ft->trans);
                    321:        fd_motor = 1;
                    322: 
                    323:        waitio();
                    324: 
                    325:        out_fdc(3); /* specify command */
                    326:        out_fdc(0xDF);
                    327:        out_fdc(2);
                    328: 
                    329:        out_fdc(7);     /* Recalibrate Function */
                    330:        out_fdc(unit);
                    331: 
                    332:        waitio();
1.1.1.3   root      333:        probetype = 1;
                    334:        for (fd_type = 0; fd_type < sizeof(fd_types)/sizeof(fd_types[0]);
                    335:                fd_type++, ft++) {
                    336:                /*for(i=0; i < 100000; i++);
                    337:                outb(0x3f7,ft->trans);
                    338:                for(i=0; i < 100000; i++);*/
                    339:                if (fdio(F_READ, unit, ft->sectrac-1, buf) >= 0){
                    340:                        probetype = 0;
                    341:                        return(0);
                    342:                }
                    343:        }
                    344:        printf("failed fdopen");
                    345:        return(-1);
1.1       root      346: }
                    347: 
                    348: 
                    349: /****************************************************************************/
                    350: /*                                 fd_dma                                   */
                    351: /* set up DMA read/write operation and virtual address addr for nbytes      */
                    352: /****************************************************************************/
                    353: fd_dma(read,addr,nbytes)
                    354: int read;
                    355: unsigned long addr;
                    356: int nbytes;
                    357: {
                    358:        /* Set read/write bytes */
                    359:        if (read) {
                    360:                outb(0xC,0x46); outb(0xB,0x46);
                    361:        } else {
                    362:                outb(0xC,0x4A); outb(0xB,0x4A);
                    363:        }
                    364:        /* Send start address */
                    365:        outb(0x4,addr & 0xFF);
                    366:        outb(0x4,(addr>>8) & 0xFF);
                    367:        outb(0x81,(addr>>16) & 0xFF);
                    368:        /* Send count */
                    369:        nbytes--;
                    370:        outb(0x5,nbytes & 0xFF);
                    371:        outb(0x5,(nbytes>>8) & 0xFF);
                    372:        /* set channel 2 */
                    373:        outb(0x0A,2);
                    374: }
                    375: 

unix.superglobalmegacorp.com

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