| plan 9 kernel history: overview | file list | diff list |
1992/1217/pc/devfloppy.c (diff list | history)
| 1992/1216/sys/src/9/pc/devfloppy.c:13,24 – 1992/1217/sys/src/9/pc/devfloppy.c:13,28 (short | long | prev | next) | ||
| 1991/0727 | typedef struct Controller Controller; | |
| 1991/0802 | typedef struct Type Type; | |
| 1991/0727 | ||
| 1992/1016 |
| |
| 1992/1217 | #define DPRINT if(floppydebug)kprint | |
| 1992/1016 | int floppydebug; | |
| 1992/0901 | ||
| 1991/0924 | /* bits in the registers */ | |
| 1991/0727 | enum { | |
| 1992/1217 | /* status registers a & b */ Psra= 0x3f0, Psrb= 0x3f1, | |
| 1991/0924 | /* digital output register */ Pdor= 0x3f2, Fintena= 0x8, /* enable floppy interrupt */ | |
| 1992/1216/sys/src/9/pc/devfloppy.c:212,217 – 1992/1217/sys/src/9/pc/devfloppy.c:216,228 | ||
| 1991/0802 | }; | |
| 1991/0811 | #define NFDIR 2 /* directory entries/drive */ | |
| 1991/0731 | ||
| 1992/1217 | static void fldump(void) { DPRINT("sra %ux srb %ux dor %ux msr %ux dir %ux\n", inb(Psra), inb(Psrb), inb(Pdor), inb(Pmsr), inb(Pdir)); } | |
| 1992/1006 | /* * set floppy drive to its default type */ | |
| 1992/1216/sys/src/9/pc/devfloppy.c:380,386 – 1992/1217/sys/src/9/pc/devfloppy.c:391,397 | ||
| 1992/1013 | * * if the read fails, cycle through the possible floppy * density till one works or we've cycled through all | |
| 1992/1217 | * possibilities for this drive. | |
| 1991/0925 | */ static void changed(Chan *c, Drive *dp) | |
| 1992/1216/sys/src/9/pc/devfloppy.c:392,398 – 1992/1217/sys/src/9/pc/devfloppy.c:403,410 | ||
| 1992/1013 | * if floppy has changed or first time through */ if((inb(Pdir)&Fchange) || dp->vers == 0){ | |
| 1992/1216 |
| |
| 1992/1217 | DPRINT("changed\n"); fldump(); | |
| 1991/0925 | dp->vers++; | |
| 1992/1013 | setdef(dp); start = dp->t; | |
| 1992/1216/sys/src/9/pc/devfloppy.c:408,416 – 1992/1217/sys/src/9/pc/devfloppy.c:420,429 | ||
| 1992/1013 | } floppydir[NFDIR*dp->dev].length = dp->t->cap; | |
| 1992/1216 | floppyon(dp); | |
| 1992/1217 | DPRINT("changed: trying %s\n", dp->t->name); fldump(); | |
| 1992/1013 | if(dp->t == start) nexterror(); | |
| 1992/1016 |
| |
| 1992/1013 | } floppyxfer(dp, Fread, dp->cache, 0, dp->t->tsize); poperror(); | |
| 1992/1216/sys/src/9/pc/devfloppy.c:594,602 – 1992/1217/sys/src/9/pc/devfloppy.c:607,620 | ||
| 1991/0924 | alreadyon = fl.motor & MOTORBIT(dp->dev); fl.motor |= MOTORBIT(dp->dev); outb(Pdor, fl.motor | Fintena | Fena | dp->dev); | |
| 1991/0921 |
| |
| 1992/1217 | if(!alreadyon){ /* wait for drive to spin up */ | |
| 1991/0921 | tsleep(&dp->r, return0, 0, 750); | |
| 1991/0924 | ||
| 1992/1217 | /* clear any pending interrupts */ floppysense(); } | |
| 1992/1003 | /* set transfer rate */ if(fl.rate != dp->t->rate){ fl.rate = dp->t->rate; | |
| 1992/1216/sys/src/9/pc/devfloppy.c:646,655 – 1992/1217/sys/src/9/pc/devfloppy.c:664,675 | ||
| 1992/1016 | fl.nstat = 0; | |
| 1991/0924 | for(i = 0; i < fl.ncmd; i++){ for(tries = 0; ; tries++){ | |
| 1992/1120 |
| |
| 1992/1016 |
| |
| 1991/0924 |
| |
| 1992/1217 | if(tries > 1000){ DPRINT("cmd %ux can't be sent (%d)\n", fl.cmd[0], i); fldump(); /* empty fifo, might have been a bad command */ floppyresult(); | |
| 1991/0924 | return -1; } if((inb(Pmsr)&(Ffrom|Fready)) == Fready) | |
| 1992/1216/sys/src/9/pc/devfloppy.c:673,681 – 1992/1217/sys/src/9/pc/devfloppy.c:693,705 | ||
| 1991/0924 | int i, s; int tries; | |
| 1991/0727 | ||
| 1992/1217 | /* get the result of the operation */ | |
| 1991/0924 | for(i = 0; i < sizeof(fl.stat); i++){ | |
| 1992/1217 | /* wait for status byte */ | |
| 1991/0924 | for(tries = 0; ; tries++){ if(tries > 1000){ | |
| 1992/1217 | DPRINT("floppyresult: %d stats\n", i); fldump(); | |
| 1991/0924 | fl.confused = 1; return -1; } | |
| 1992/1216/sys/src/9/pc/devfloppy.c:682,688 – 1992/1217/sys/src/9/pc/devfloppy.c:706,712 | ||
| 1991/0924 | s = inb(Pmsr)&(Ffrom|Fready); if(s == Fready){ fl.nstat = i; | |
| 1992/1217 | return fl.nstat; | |
| 1991/0924 | } if(s == (Ffrom|Fready)) break; | |
| 1992/1216/sys/src/9/pc/devfloppy.c:689,696 – 1992/1217/sys/src/9/pc/devfloppy.c:713,720 | ||
| 1991/0924 | } fl.stat[i] = inb(Pdata); | |
| 1991/0727 | } | |
| 1991/0924 |
| |
| 1992/1217 | fl.nstat = sizeof(fl.stat); return fl.nstat; | |
| 1991/0727 | } | |
| 1991/0731 | /* | |
| 1992/1216/sys/src/9/pc/devfloppy.c:732,737 – 1992/1217/sys/src/9/pc/devfloppy.c:756,762 | ||
| 1991/0727 | return -1; | |
| 1991/0924 | if(floppyresult() < 2){ | |
| 1992/0901 | DPRINT("can't read sense response\n"); | |
| 1992/1217 | fldump(); | |
| 1991/0924 | fl.confused = 1; | |
| 1991/0727 | return -1; } | |
| 1992/1216/sys/src/9/pc/devfloppy.c:746,757 – 1992/1217/sys/src/9/pc/devfloppy.c:771,785 | ||
| 1991/0924 | } | |
| 1991/0731 | /* | |
| 1991/0924 |
| |
| 1992/1217 | * Wait for a floppy interrupt. If none occurs in 5 seconds, we * may have missed one. This only happens on some portables which * do power management behind our backs. Call the interrupt * routine to try to clear any conditions. | |
| 1991/0731 | */ | |
| 1991/0924 | static void floppywait(void) | |
| 1991/0731 | { | |
| 1991/0924 |
| |
| 1992/1217 | tsleep(&fl.r, cmddone, 0, 5000); | |
| 1992/1216 | if(!cmddone(0)) floppyintr(0); | |
| 1991/0731 | } | |
| 1992/1216/sys/src/9/pc/devfloppy.c:765,771 – 1992/1217/sys/src/9/pc/devfloppy.c:793,798 | ||
| 1991/0924 | dp->ccyl = -1; | |
| 1992/1016 | dp->cyl = -1; | |
| 1991/0727 | ||
| 1992/1216 |
| |
| 1991/0924 | fl.ncmd = 0; fl.cmd[fl.ncmd++] = Frecal; fl.cmd[fl.ncmd++] = dp->dev; | |
| 1992/1216/sys/src/9/pc/devfloppy.c:807,828 – 1992/1217/sys/src/9/pc/devfloppy.c:834,864 | ||
| 1991/0924 | * reset the controller if it's confused | |
| 1991/0727 | */ | |
| 1991/0924 | if(fl.confused){ | |
| 1992/1216 |
| |
| 1992/1217 | DPRINT("floppyrevive in\n"); fldump(); | |
| 1991/0727 | /* reset controller and turn all motors off */ splhi(); | |
| 1992/1217 | fl.ncmd = 1; | |
| 1991/0924 | fl.cmd[0] = 0; outb(Pdor, 0); | |
| 1991/0727 | delay(1); | |
| 1991/0924 | outb(Pdor, Fintena|Fena); | |
| 1991/0727 | spllo(); | |
| 1991/0924 |
| |
| 1991/0727 |
| |
| 1991/0924 | fl.motor = 0; | |
| 1992/1217 | floppywait(); /* mark all drives in an unknown state */ for(dp = fl.d; dp < &fl.d[conf.nfloppy]; dp++) dp->confused = 1; /* set rate to a known value */ | |
| 1991/0925 | outb(Pdsr, 0); | |
| 1992/1216 | fl.rate = 0; | |
| 1992/1217 | DPRINT("floppyrevive out\n"); fldump(); | |
| 1991/0727 | } } | |
| 1992/1216/sys/src/9/pc/devfloppy.c:839,845 – 1992/1217/sys/src/9/pc/devfloppy.c:875,880 | ||
| 1992/1003 | return dp->tcyl; | |
| 1992/1016 | dp->cyl = -1; | |
| 1991/0727 | ||
| 1992/1016 |
| |
| 1991/0924 | fl.ncmd = 0; fl.cmd[fl.ncmd++] = Fseek; fl.cmd[fl.ncmd++] = (dp->thead<<2) | dp->dev; | |
| 1992/1216/sys/src/9/pc/devfloppy.c:890,898 – 1992/1217/sys/src/9/pc/devfloppy.c:925,930 | ||
| 1992/1016 | dp->confused = 1; | |
| 1992/0114 | error(Eio); | |
| 1992/1016 | } | |
| 1991/0925 | ||
| 1992/1016 |
| |
| 1992/0901 |
| |
| 1991/0727 | /* | |
| 1991/0731 | * set up the dma (dp->len may be trimmed) | |