Annotation of lucent/sys/src/boot/pc/floppy.c, revision 1.1.1.1

1.1       root        1: #include <u.h>
                      2: 
                      3: #include       "lib.h"
                      4: #include       "mem.h"
                      5: #include       "dat.h"
                      6: #include       "fns.h"
                      7: #include       "io.h"
                      8: #include       "ureg.h"
                      9: 
                     10: #define DPRINT if(0)print
                     11: 
                     12: typedef        struct Drive    Drive;
                     13: typedef        struct Floppy   Floppy;
                     14: typedef struct Type    Type;
                     15: 
                     16: enum
                     17: {
                     18:        Pdor=           0x3f2,  /* motor port */
                     19:         Fintena=        0x8,   /* enable floppy interrupt */
                     20:         Fena=           0x4,   /* 0 == reset controller */
                     21: 
                     22:        Pmsr=           0x3f4,  /* controller main status port */
                     23:         Fready=         0x80,  /* ready to be touched */
                     24:         Ffrom=          0x40,  /* data from controller */
                     25:         Fbusy=          0x10,  /* operation not over */
                     26: 
                     27:        Pdata=          0x3f5,  /* controller data port */
                     28:         Frecal=         0x7,   /* recalibrate cmd */
                     29:         Fseek=          0xf,   /* seek cmd */
                     30:         Fsense=         0x8,   /* sense cmd */
                     31:         Fread=          0x66,  /* read cmd */
                     32:         Fwrite=         0x45,  /* write cmd */
                     33:         Fmulti=         0x80,  /* or'd with Fread or Fwrite for multi-head */
                     34: 
                     35:        /* digital input register */
                     36:        Pdir=           0x3F7,  /* disk changed port (read only) */
                     37:        Pdsr=           0x3F7,  /* data rate select port (write only) */
                     38:        Fchange=        0x80,   /* disk has changed */
                     39: 
                     40:        DMAmode0=       0xb,
                     41:        DMAmode1=       0xc,
                     42:        DMAaddr=        0x4,
                     43:        DMAtop=         0x81,
                     44:        DMAinit=        0xa,
                     45:        DMAcount=       0x5,
                     46: 
                     47:        Maxfloppy=      4,      /* floppies/controller */
                     48: 
                     49:        /* sector size encodings */
                     50:        S128=           0,
                     51:        S256=           1,
                     52:        S512=           2,
                     53:        S1024=          3,
                     54: 
                     55:        /* status 0 byte */
                     56:        Drivemask=      3<<0,
                     57:        Seekend=        1<<5,
                     58:        Codemask=       (3<<6)|(3<<3),
                     59: };
                     60: 
                     61: #define MOTORBIT(i)    (1<<((i)+4))
                     62: 
                     63: /*
                     64:  *  types of drive (from PC equipment byte)
                     65:  */
                     66: enum
                     67: {
                     68:        Tnone=          0,
                     69:        T360kb=         1,
                     70:        T1200kb=        2,
                     71:        T720kb=         3,
                     72:        T1440kb=        4,
                     73: };
                     74: 
                     75: /*
                     76:  *  floppy types (all MFM encoding)
                     77:  */
                     78: struct Type
                     79: {
                     80:        char    *name;
                     81:        int     dt;             /* compatible drive type */
                     82:        int     bytes;          /* bytes/sector */
                     83:        int     sectors;        /* sectors/track */
                     84:        int     heads;          /* number of heads */
                     85:        int     steps;          /* steps per cylinder */
                     86:        int     tracks;         /* tracks/disk */
                     87:        int     gpl;            /* intersector gap length for read/write */     
                     88:        int     fgpl;           /* intersector gap length for format */
                     89:        int     rate;           /* rate code */
                     90: 
                     91:        /*
                     92:         *  these depend on previous entries and are set filled in
                     93:         *  by floppyinit
                     94:         */
                     95:        int     bcode;          /* coded version of bytes for the controller */
                     96:        long    cap;            /* drive capacity in bytes */
                     97:        long    tsize;          /* track size in bytes */
                     98: };
                     99: Type floppytype[] =
                    100: {
                    101:  { "3½HD",    T1440kb, 512, 18, 2, 1, 80, 0x1B, 0x54, 0, },
                    102:  { "3½DD",    T1440kb, 512,  9, 2, 1, 80, 0x1B, 0x54, 2, },
                    103:  { "3½DD",    T720kb,  512,  9, 2, 1, 80, 0x1B, 0x54, 2, },
                    104:  { "5¼HD",    T1200kb, 512, 15, 2, 1, 80, 0x2A, 0x50, 0, },
                    105:  { "5¼DD",    T1200kb, 512,  9, 2, 2, 40, 0x2A, 0x50, 1, },
                    106:  { "5¼DD",    T360kb,  512,  9, 2, 1, 40, 0x2A, 0x50, 2, },
                    107: };
                    108: #define NTYPES (sizeof(floppytype)/sizeof(Type))
                    109: 
                    110: /*
                    111:  *  bytes per sector encoding for the controller.
                    112:  *  - index for b2c is is (bytes per sector/128).
                    113:  *  - index for c2b is code from b2c
                    114:  */
                    115: static int b2c[] =
                    116: {
                    117: [1]    0,
                    118: [2]    1,
                    119: [4]    2,
                    120: [8]    3,
                    121: };
                    122: static int c2b[] =
                    123: {
                    124:        128,
                    125:        256,
                    126:        512,
                    127:        1024,
                    128: };
                    129: 
                    130: /*
                    131:  *  a floppy drive
                    132:  */
                    133: struct Drive
                    134: {
                    135:        Type    *t;
                    136:        int     dt;
                    137:        int     dev;
                    138: 
                    139:        ulong   lasttouched;    /* time last touched */
                    140:        int     cyl;            /* current cylinder */
                    141:        int     confused;       /* needs to be recalibrated (or worse) */
                    142:        long    offset;         /* current offset */
                    143: 
                    144:        int     tcyl;           /* target cylinder */
                    145:        int     thead;          /* target head */
                    146:        int     tsec;           /* target sector */
                    147:        long    len;
                    148:        int     maxtries;
                    149: };
                    150: 
                    151: /*
                    152:  *  NEC PD765A controller for 4 floppys
                    153:  */
                    154: struct Floppy
                    155: {
                    156:        Drive   d[Maxfloppy];   /* the floppy drives */
                    157:        int     rw;             /* true if a read or write in progress */
                    158:        int     seek;           /* one bit for each seek in progress */
                    159:        uchar   stat[8];        /* status of an operation */
                    160:        int     intr;
                    161:        int     confused;
                    162:        int     motor;
                    163:        Drive   *selected;
                    164:        int     rate;
                    165: 
                    166:        int     cdev;
                    167:        uchar   *ccache;        /* cylinder cache */
                    168:        int     ccyl;
                    169:        int     chead;
                    170: };
                    171: 
                    172: Floppy fl;
                    173: 
                    174: static void    floppyalarm(Alarm*);
                    175: static int     floppysend(int);
                    176: static int     floppyrcv(void);
                    177: static int     floppyrdstat(int);
                    178: static void    floppypos(Drive*, long);
                    179: static void    floppywait(char*);
                    180: static int     floppysense(Drive*);
                    181: static int     floppyrecal(Drive*);
                    182: static void    floppyon(Drive*);
                    183: static long    floppyxfer(Drive*, int, void*, long);
                    184: static void    floppyrevive(void);
                    185: static void    floppystop(Drive*);
                    186: 
                    187: static void
                    188: timedsleep(int ms)
                    189: {
                    190:        ulong end;
                    191: 
                    192:        end = m->ticks + 1 + MS2TK(ms);
                    193:        while(m->ticks < end)
                    194:                ;
                    195: }
                    196: 
                    197: /*
                    198:  *  set floppy drive to its default type
                    199:  */
                    200: static void
                    201: setdef(Drive *dp)
                    202: {
                    203:        Type *t;
                    204: 
                    205:        for(t = floppytype; t < &floppytype[NTYPES]; t++)
                    206:                if(dp->dt == t->dt){
                    207:                        dp->t = t;
                    208:                        break;
                    209:                }
                    210: }
                    211: 
                    212: static void
                    213: floppyintr(Ureg*, void*)
                    214: {
                    215:        fl.intr = 1;
                    216: }
                    217: 
                    218: int
                    219: floppyinit(void)
                    220: {
                    221:        Drive *dp;
                    222:        uchar equip;
                    223:        int mask;
                    224:        Type *t;
                    225:        char debstr[256];
                    226: 
                    227:        setvec(Floppyvec, floppyintr, 0);
                    228: 
                    229:        /* reset the interface chip */
                    230:        sprint(debstr, "resetting floppy interface\n");
                    231:        delay(50);
                    232:        outb(Pdor, 0);
                    233:        delay(50);
                    234:        outb(Pdor, Fintena | Fena);
                    235:        delay(50);
                    236:        sprint(debstr, "floppy interface reset\n");
                    237: 
                    238:        /*
                    239:         *  init dependent parameters
                    240:         */
                    241:        for(t = floppytype; t < &floppytype[NTYPES]; t++){
                    242:                t->cap = t->bytes * t->heads * t->sectors * t->tracks;
                    243:                t->bcode = b2c[t->bytes/128];
                    244:                t->tsize = t->bytes * t->sectors;
                    245:        }
                    246: 
                    247:        /*
                    248:         *  init drive parameters
                    249:         */
                    250:        for(dp = fl.d; dp < &fl.d[Maxfloppy]; dp++){
                    251:                dp->cyl = -1;
                    252:                dp->dev = dp - fl.d;
                    253:                dp->maxtries = 1;
                    254:        }
                    255: 
                    256:        /*
                    257:         *  read nvram for types of floppies 0 & 1
                    258:         */
                    259:        mask = 0;
                    260:        equip = nvramread(0x10);
                    261:        if(Maxfloppy > 0 && (fl.d[0].dt = ((equip>>4) & 0xF))){
                    262:                setdef(&fl.d[0]);
                    263:                mask |= 0x01;
                    264:        }
                    265:        if(Maxfloppy > 1 && (fl.d[1].dt = (equip & 0xF))){
                    266:                setdef(&fl.d[1]);
                    267:                mask |= 0x02;
                    268:        }
                    269: 
                    270:        fl.rate = -1;
                    271:        fl.motor = 0;
                    272:        fl.confused = 1;
                    273:        fl.ccyl = -1;
                    274:        fl.chead = -1;
                    275:        fl.cdev = -1;
                    276:        fl.ccache = (uchar*)ialloc(18*2*512, 1);
                    277: 
                    278:        /* to turn the motor off when inactive */
                    279:        alarm(5*1000, floppyalarm, (void *)0);
                    280: 
                    281:        return mask;
                    282: }
                    283: 
                    284: static void
                    285: floppyon(Drive *dp)
                    286: {
                    287:        int alreadyon;
                    288:        int tries;
                    289: 
                    290:        if(fl.confused)
                    291:                floppyrevive();
                    292: 
                    293:        alreadyon = fl.motor & MOTORBIT(dp->dev);
                    294:        fl.motor |= MOTORBIT(dp->dev);
                    295:        outb(Pdor, fl.motor | Fintena | Fena | dp->dev);
                    296: 
                    297:        /* get motor going */
                    298:        if(!alreadyon)
                    299:                timedsleep(750);
                    300: 
                    301:        /* set transfer rate */
                    302:        if(fl.rate != dp->t->rate){
                    303:                fl.rate = dp->t->rate;
                    304:                outb(Pdsr, fl.rate);
                    305:        }
                    306: 
                    307:        /* get drive to a known cylinder */
                    308:        if(dp->confused)
                    309:                for(tries = 0; tries < 4; tries++)
                    310:                        if(floppyrecal(dp) >= 0)
                    311:                                break;
                    312: 
                    313:        dp->lasttouched = m->ticks;
                    314:        fl.selected = dp;
                    315: }
                    316: 
                    317: static void
                    318: floppyrevive(void)
                    319: {
                    320:        Drive *dp;
                    321: 
                    322:        /*
                    323:         *  reset the controller if it's confused
                    324:         */
                    325:        if(fl.confused){
                    326:                /* reset controller and turn all motors off */
                    327:                fl.intr = 0;
                    328:                splhi();
                    329:                outb(Pdor, 0);
                    330:                delay(1);
                    331:                outb(Pdor, Fintena|Fena);
                    332:                spllo();
                    333:                for(dp = fl.d; dp < &fl.d[Maxfloppy]; dp++)
                    334:                        dp->confused = 1;
                    335:                fl.motor = 0;
                    336:                floppywait("revive");
                    337:                fl.confused = 0;
                    338:                outb(Pdsr, 0);
                    339:        }
                    340: }
                    341: 
                    342: static void
                    343: floppystop(Drive *dp)
                    344: {
                    345:        fl.motor &= ~MOTORBIT(dp->dev);
                    346:        outb(Pdor, fl.motor | Fintena | Fena | dp->dev);
                    347:        fl.selected = dp;
                    348: }
                    349: 
                    350: static void
                    351: floppyalarm(Alarm* a)
                    352: {
                    353:        Drive *dp;
                    354: 
                    355:        for(dp = fl.d; dp < &fl.d[Maxfloppy]; dp++){
                    356:                if((fl.motor&MOTORBIT(dp->dev)) && TK2SEC(m->ticks - dp->lasttouched) > 5)
                    357:                        floppystop(dp);
                    358:        }
                    359: 
                    360:        alarm(5*1000, floppyalarm, 0);
                    361:        cancel(a);
                    362: }
                    363: 
                    364: static int
                    365: floppysend(int data)
                    366: {
                    367:        int tries;
                    368:        uchar c;
                    369: 
                    370:        for(tries = 0; tries < 100; tries++){
                    371:                /*
                    372:                 *  see if its ready for data
                    373:                 */
                    374:                c = inb(Pmsr);
                    375:                if((c&(Ffrom|Fready)) != Fready)
                    376:                        continue;
                    377: 
                    378:                /*
                    379:                 *  send the data
                    380:                 */
                    381:                outb(Pdata, data);
                    382:                return 0;
                    383:        }
                    384:        return -1;
                    385: }
                    386: 
                    387: static int
                    388: floppyrcv(void)
                    389: {
                    390:        int tries;
                    391:        uchar c;
                    392: 
                    393:        for(tries = 0; tries < 100; tries++){
                    394:                /*
                    395:                 *  see if its ready for data
                    396:                 */
                    397:                c = inb(Pmsr);
                    398:                if((c&(Ffrom|Fready)) != (Ffrom|Fready))
                    399:                        continue;
                    400: 
                    401:                /*
                    402:                 *  get data
                    403:                 */
                    404:                return inb(Pdata)&0xff;
                    405:        }
                    406:        DPRINT("floppyrcv returns -1 status = %lux\n", c);
                    407:        return -1;
                    408: }
                    409: 
                    410: static int
                    411: floppyrdstat(int n)
                    412: {
                    413:        int i;
                    414:        int c;
                    415: 
                    416:        for(i = 0; i < n; i++){
                    417:                c = floppyrcv();
                    418:                if(c < 0)
                    419:                        return -1;
                    420:                fl.stat[i] = c;
                    421:        }
                    422:        return 0;
                    423: }
                    424: 
                    425: static void
                    426: floppypos(Drive *dp, long off)
                    427: {
                    428:        int lsec;
                    429:        int cyl;
                    430: 
                    431:        lsec = off/dp->t->bytes;
                    432:        dp->tcyl = lsec/(dp->t->sectors*dp->t->heads);
                    433:        dp->tsec = (lsec % dp->t->sectors) + 1;
                    434:        dp->thead = (lsec/dp->t->sectors) % dp->t->heads;
                    435: 
                    436:        /*
                    437:         *  can't read across cylinder boundaries.
                    438:         *  if so, decrement the bytes to be read.
                    439:         */
                    440:        lsec = (off+dp->len)/dp->t->bytes;
                    441:        cyl = lsec/(dp->t->sectors*dp->t->heads);
                    442:        if(cyl != dp->tcyl){
                    443:                dp->len -= (lsec % dp->t->sectors)*dp->t->bytes;
                    444:                dp->len -= ((lsec/dp->t->sectors) % dp->t->heads)*dp->t->bytes
                    445:                                *dp->t->sectors;
                    446:        }
                    447: 
                    448:        dp->lasttouched = m->ticks;     
                    449:        fl.intr = 0;
                    450: }
                    451: 
                    452: static void
                    453: floppywait(char *cmd)
                    454: {
                    455:        ulong start;
                    456: 
                    457:        for(start = m->ticks; TK2SEC(m->ticks - start) < 1 && fl.intr == 0;)
                    458:                ;
                    459:        if(TK2SEC(m->ticks - start) >= 1)
                    460:                DPRINT("floppy timed out, cmd=%s\n", cmd);
                    461:        fl.intr = 0;
                    462: }
                    463: 
                    464: static int
                    465: floppysense(Drive *dp)
                    466: {
                    467:        /*
                    468:         *  ask for floppy status
                    469:         */
                    470:        if(floppysend(Fsense) < 0){
                    471:                fl.confused = 1;
                    472:                return -1;
                    473:        }
                    474:        if(floppyrdstat(2) < 0){
                    475:                fl.confused = 1;
                    476:                dp->confused = 1;
                    477:                return -1;
                    478:        }
                    479: 
                    480:        /*
                    481:         *  make sure it's the right drive
                    482:         */
                    483:        if((fl.stat[0] & Drivemask) != dp->dev){
                    484:                DPRINT("sense failed, %lux %lux\n", fl.stat[0], fl.stat[1]);
                    485:                dp->confused = 1;
                    486:                return -1;
                    487:        }
                    488:        return 0;
                    489: }
                    490: 
                    491: static int
                    492: floppyrecal(Drive *dp)
                    493: {
                    494:        fl.intr = 0;
                    495:        if(floppysend(Frecal) < 0
                    496:        || floppysend(dp - fl.d) < 0){
                    497:                DPRINT("recalibrate rejected\n");
                    498:                fl.confused = 0;
                    499:                return -1;
                    500:        }
                    501:        floppywait("recal");
                    502: 
                    503:        /*
                    504:         *  get return values
                    505:         */
                    506:        if(floppysense(dp) < 0)
                    507:                return -1;
                    508: 
                    509:        /*
                    510:         *  see what cylinder we got to
                    511:         */
                    512:        dp->tcyl = 0;
                    513:        dp->cyl = fl.stat[1]/dp->t->steps;
                    514:        if(dp->cyl != dp->tcyl){
                    515:                DPRINT("recalibrate went to wrong cylinder %d\n", dp->cyl);
                    516:                dp->confused = 1;
                    517:                return -1;
                    518:        }
                    519: 
                    520:        dp->confused = 0;
                    521:        return 0;
                    522: }
                    523: 
                    524: long
                    525: floppyseek(int dev, long off)
                    526: {
                    527:        Drive *dp;
                    528: 
                    529:        dp = &fl.d[dev];
                    530:        floppyon(dp);
                    531:        floppypos(dp, off);
                    532:        if(dp->cyl == dp->tcyl){
                    533:                dp->offset = off;
                    534:                return off;
                    535:        }
                    536: 
                    537:        /*
                    538:         *  tell floppy to seek
                    539:         */
                    540:        if(floppysend(Fseek) < 0
                    541:        || floppysend((dp->thead<<2) | dp->dev) < 0
                    542:        || floppysend(dp->tcyl * dp->t->steps) < 0){
                    543:                DPRINT("seek cmd failed\n");
                    544:                fl.confused = 1;
                    545:                return -1;
                    546:        }
                    547: 
                    548:        /*
                    549:         *  wait for interrupt
                    550:         */
                    551:        floppywait("seek");
                    552: 
                    553:        /*
                    554:         *  get floppy status
                    555:         */
                    556:        if(floppysense(dp) < 0)
                    557:                return -1;
                    558: 
                    559:        /*
                    560:         *  see if it worked
                    561:         */
                    562:        if((fl.stat[0] & (Codemask|Seekend)) != Seekend){
                    563:                DPRINT("seek failed\n");
                    564:                dp->confused = 1;
                    565:                return -1;
                    566:        }
                    567: 
                    568:        /*
                    569:         *  see what cylinder we got to
                    570:         */
                    571:        dp->cyl = fl.stat[1]/dp->t->steps;
                    572:        if(dp->cyl != dp->tcyl){
                    573:                DPRINT("seek went to wrong cylinder %d instead of %d\n",
                    574:                        dp->cyl, dp->tcyl);
                    575:                dp->confused = 1;
                    576:                return -1;
                    577:        }
                    578: 
                    579:        dp->offset = off;
                    580:        DPRINT("seek to %d succeeded\n", dp->offset);
                    581:        return dp->offset;
                    582: }
                    583: 
                    584: static long
                    585: floppyxfer(Drive *dp, int cmd, void *a, long n)
                    586: {
                    587:        ulong addr;
                    588:        long offset;
                    589: 
                    590:        addr = (ulong)a;
                    591: 
                    592:        /*
                    593:         *  dma can't cross 64 k boundaries
                    594:         */
                    595:        if((addr & 0xffff0000) != ((addr+n) & 0xffff0000))
                    596:                n -= (addr+n)&0xffff;
                    597: 
                    598:        dp->len = n;
                    599:        if(floppyseek(dp->dev, dp->offset) < 0){
                    600:                DPRINT("xfer seek failed\n");
                    601:                return -1;
                    602:        }
                    603: 
                    604:        DPRINT("floppy %d tcyl %d, thead %d, tsec %d, addr %lux, n %d\n",
                    605:                dp->dev, dp->tcyl, dp->thead, dp->tsec, addr, n);/**/
                    606: 
                    607:        /*
                    608:         *  set up the dma
                    609:         */
                    610:        outb(DMAmode1, cmd==Fread ? 0x46 : 0x4a);
                    611:        outb(DMAmode0, cmd==Fread ? 0x46 : 0x4a);
                    612:        outb(DMAaddr, addr);
                    613:        outb(DMAaddr, addr>>8);
                    614:        outb(DMAtop, addr>>16);
                    615:        outb(DMAcount, n-1);
                    616:        outb(DMAcount, (n-1)>>8);
                    617:        outb(DMAinit, 2);
                    618: 
                    619:        /*
                    620:         *  tell floppy to go
                    621:         */
                    622:        cmd = cmd | (dp->t->heads > 1 ? Fmulti : 0);
                    623:        if(floppysend(cmd) < 0
                    624:        || floppysend((dp->thead<<2) | dp->dev) < 0
                    625:        || floppysend(dp->tcyl * dp->t->steps) < 0
                    626:        || floppysend(dp->thead) < 0
                    627:        || floppysend(dp->tsec) < 0
                    628:        || floppysend(dp->t->bcode) < 0
                    629:        || floppysend(dp->t->sectors) < 0
                    630:        || floppysend(dp->t->gpl) < 0
                    631:        || floppysend(0xFF) < 0){
                    632:                DPRINT("xfer cmd failed\n");
                    633:                fl.confused = 1;
                    634:                return -1;
                    635:        }
                    636: 
                    637:        floppywait("xfer");
                    638: 
                    639:        /*
                    640:         *  get status
                    641:         */
                    642:        if(floppyrdstat(7) < 0){
                    643:                DPRINT("xfer status failed\n");
                    644:                fl.confused = 1;
                    645:                return -1;
                    646:        }
                    647: 
                    648:        if((fl.stat[0] & Codemask)!=0 || fl.stat[1] || fl.stat[2]){
                    649:                DPRINT("xfer failed %lux %lux %lux\n", fl.stat[0],
                    650:                        fl.stat[1], fl.stat[2]);
                    651:                dp->confused = 1;
                    652:                return -1;
                    653:        }
                    654: 
                    655:        offset = (fl.stat[3]/dp->t->steps) * dp->t->heads + fl.stat[4];
                    656:        offset = offset*dp->t->sectors + fl.stat[5] - 1;
                    657:        offset = offset * c2b[fl.stat[6]];
                    658:        if(offset != dp->offset+n){
                    659:                DPRINT("new offset %d instead of %d\n", offset, dp->offset+dp->len);
                    660:                dp->confused = 1;
                    661:                return -1;/**/
                    662:        }
                    663:        dp->offset += dp->len;
                    664:        return dp->len;
                    665: }
                    666: 
                    667: long
                    668: floppyread(int dev, void *a, long n)
                    669: {
                    670:        Drive *dp;
                    671:        long rv, i, nn, offset, sec;
                    672:        uchar *aa;
                    673:        int tries;
                    674: 
                    675:        dp = &fl.d[dev];
                    676: 
                    677:        dp->len = n;
                    678:        floppypos(dp, dp->offset);
                    679:        offset = dp->offset;
                    680:        sec = dp->tsec + dp->t->sectors*dp->thead;
                    681:        n = dp->len;
                    682:        if(fl.ccyl==dp->tcyl && fl.cdev==dev)
                    683:                goto out;
                    684: 
                    685:        fl.ccyl = -1;
                    686:        fl.cdev = dev;
                    687:        aa = fl.ccache;
                    688:        nn = dp->t->bytes*dp->t->sectors*dp->t->heads;
                    689:        dp->offset = dp->tcyl*nn;
                    690:        for(rv = 0; rv < nn; rv += i){
                    691:                i = 0;
                    692:                for(tries = 0; tries < dp->maxtries; tries++){
                    693:                        i = floppyxfer(dp, Fread, aa+rv, nn-rv);
                    694:                        if(i > 0)
                    695:                                break;
                    696:                }
                    697:                if(tries == dp->maxtries)
                    698:                        break;
                    699:        }
                    700:        if(rv != nn){
                    701:                dp->confused = 1;
                    702:                return -1;
                    703:        }
                    704:        fl.ccyl = dp->tcyl;
                    705: out:
                    706:        memmove(a, fl.ccache + dp->t->bytes*(sec-1), n);
                    707:        dp->offset = offset + n;
                    708:        dp->maxtries = 3;
                    709:        return n;
                    710: }

unix.superglobalmegacorp.com

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