hcj@lzaz.ATT.COM (HC Johnson) (01/08/89)
I just made a major discovery. My floppy drives (with a disk in them) are spinning all the time I run Minix. Properly, until I do a floppy disk operation in Minix. This can be days at a time. The problem is that floppy_task starts by resetting the controller with the line: dmawdat(FDC_CS, IRUPT, FDC_DELAY); /* reset controller */ This turn ON the motor_on line, and spins all motors even if the drive is not selected. In the simplest case, this command is not needed as the only way to boot Minix is via TOS or to boot a floppy. I give you here my local version of stfloppy.c. It contains 3 changes: 1. a define to do away with the reset controller 2. a define to add a bit to the minor number to indicate 10 spt floppies. This is cruder than a previous posting but much simpler. 3. a define to do read after write. (maybe I wouldn't have needed this if my drives hadn't cooked for weeks). Howard Johnson ATT-BL lzaz!hcj =======cdiff of kernel/stfloppy================= *** stfloppy.c Thu Jan 7 21:53:55 1989 --- /mnt/kernel/stfloppy.c Thu Oct 29 15:49:46 1988 *************** *** 27,40 **** * using DMA the interrupt is signalled to the floppy task. */ - /* HCJ: I have made three changes to this file. They are separated - * with separate defines. You may take all or part. - */ - - #define NO_FLOPPY_INIT /* dont do init to floppy, it turns the motors on */ - #define RD_AFTER_WT /* always read after write. off: you'll be sorry */ - #define TWISTER /* inode specifies 9 and 10 spt */ - #include "../h/const.h" #include "../h/type.h" #include "../h/callnr.h" --- 27,32 ---- *************** *** 49,55 **** #include "stdma.h" #include "stsound.h" - #define ASSERT(x) if (!(x)) panic("fd: ASSERT(x) failed",NO_NUM); #define TRACE(x) /* x */ #define DEBUG(x) x --- 41,46 ---- *************** *** 64,73 **** #define NR_TYPES 2 /* number of diskette/drive combinations */ #define MAX_ERRORS 10 /* how often to try rd/wt before quitting */ - #ifdef TWISTER - #define NR_ALT_SECTS 10 /* 10 spt on twisted format */ - #endif - /* return values of xfer_ok(): */ #define X_OK 0 #define X_AGAIN 1 --- 55,60 ---- *************** *** 94,112 **** int x_count; /* bytes still to transfer */ int x_errors; /* errors on current sector */ int x_cmd; /* controller command */ - #ifdef TWISTER - int x_spt; /* sectors per track */ - #endif } xfer; #define DRIVE(d) ((d) & 0x07) ! #define DTYPE(d) (((d) >> 3) & 0x1) ! #ifdef TWISTER ! #define TWIST(d) (((d) >> 4) & 0x1) ! /* ! * minor: twisted<<4 | dtype<<3 | partition ! */ ! #endif FORWARD int fdcint(); --- 81,90 ---- int x_count; /* bytes still to transfer */ int x_errors; /* errors on current sector */ int x_cmd; /* controller command */ } xfer; #define DRIVE(d) ((d) & 0x07) ! #define DTYPE(d) (((d) >> 3) & 0x1F) FORWARD int fdcint(); *************** *** 122,137 **** * It waits for a message, carries it out, and sends a reply. */ TRACE(printf("fd: task started\n")); - #ifndef NO_FLOPPY_INIT dmagrab(FLOPPY, fdcint); dmawdat(FDC_CS, IRUPT, FDC_DELAY); /* reset controller */ dmafree(FLOPPY); - #endif - - #ifndef RD_AFTER_WT - #define do_wtrd(x) do_rdwt(x) - #endif - for (drive = 0; drive < NR_DRIVES; drive++) curcyl[drive] = -1; /* uncalibrated */ while (TRUE) { --- 100,108 ---- *************** *** 143,150 **** /* Now carry out the work. */ switch (mess.m_type) { ! case DISK_READ: r = do_rdwt(&mess); break; ! case DISK_WRITE: r = do_wtrd(&mess); break; default: r = EINVAL; break; } --- 114,121 ---- /* Now carry out the work. */ switch (mess.m_type) { ! case DISK_READ: ! case DISK_WRITE: r = do_rdwt(&mess); break; default: r = EINVAL; break; } *************** *** 157,237 **** } ! #ifdef RD_AFTER_WT ! PRIVATE char lbuffer[SECTOR_SIZE * 2]; /* used for read after write */ ! ! /*===========================================================================* ! * do_wtrd * ! *===========================================================================*/ ! PRIVATE int do_wtrd(mp) register message *mp; { register struct proc *rp; register struct xfer *xp; register nbytes; - - int Device; - int lbytes; - int r,rw; - char * address; - long position; - int xfer_size; - int retry = 5; - - lbytes = mp->COUNT; - if ((mp->POSITION % SECTOR_SIZE) != 0) - return(EINVAL); - if ((lbytes % SECTOR_SIZE) != 0) - return(EINVAL); - - Device = mp->DEVICE; - position = mp->POSITION; - address = mp->ADDRESS; - - xfer_size = (lbytes > SECTOR_SIZE)?sizeof(lbuffer):SECTOR_SIZE; - while(lbytes) { - if(lbytes < xfer_size) - xfer_size = lbytes; - mp->COUNT = xfer_size; - /* first time ADDRESS, POSITION, m_type are correct */ - if((rw=do_rdwt(mp)) < 0) - return(rw); /* it failed */ - mp->COUNT = xfer_size; - mp->ADDRESS = lbuffer; - mp->POSITION = position; - mp->m_type = DISK_READ; - mp->DEVICE = Device; - if((r=do_rdwt(mp)) < 0) { - printf("Read after write failed device=%x err cod=%d sz=%d pos=%ld\n", - mp->DEVICE,r,position); - mp->ADDRESS = address; - mp->m_type = DISK_WRITE; - if(--retry) - continue; /* try again */ - return(r); /* it failed */ - } - address += xfer_size; - position += xfer_size; - lbytes -= xfer_size; - - mp->ADDRESS = address; - mp->POSITION = position; - mp->m_type = DISK_WRITE; - mp->DEVICE = Device; - } - return(rw); - } - #endif - - /*===========================================================================* - * do_rdwt * - *===========================================================================*/ - PRIVATE int do_rdwt(mp) - register message *mp; - { - register struct proc *rp; - register struct xfer *xp; - register nbytes; extern phys_bytes umap(); xp = &xfer; --- 128,142 ---- } ! /*===========================================================================* ! * do_rdwt * ! *===========================================================================*/ ! PRIVATE int do_rdwt(mp) register message *mp; { register struct proc *rp; register struct xfer *xp; register nbytes; extern phys_bytes umap(); xp = &xfer; *************** *** 241,249 **** return(EIO); if (DTYPE(xp->x_drive) >= NR_TYPES) return(EIO); - #ifdef TWISTER - xp->x_spt = TWIST(xp->x_drive)==1?NR_ALT_SECTS:NR_SECTORS; - #endif nbytes = mp->COUNT; xp->x_count = nbytes; if ((mp->POSITION % SECTOR_SIZE) != 0) --- 146,151 ---- *************** *** 284,292 **** xp = &xfer; d = DTYPE(xp->x_drive); ! #ifdef TWISTER ! cylinder = xp->x_secnum / xp->x_spt; ! #endif head = cylinder % nr_heads[d]; cylinder = cylinder / nr_heads[d]; if (cylinder >= NR_CYLINDERS) --- 186,192 ---- xp = &xfer; d = DTYPE(xp->x_drive); ! cylinder = xp->x_secnum / NR_SECTORS; head = cylinder % nr_heads[d]; cylinder = cylinder / nr_heads[d]; if (cylinder >= NR_CYLINDERS) *************** *** 330,352 **** return(1); } - - #ifndef TWISTER TRACE(printf("fd%d: %s: secnum=%d,cylinder=%d,sector=%d,head=%d\n", xp->x_drive, xp->x_rw == DISK_READ ? "read" : "write", xp->x_secnum, cylinder, sector, head)); sector = xp->x_secnum % NR_SECTORS; sector++; /* start numbering at 1 */ - /* The drive is now on the proper cylinder. Read or write 1 block. */ - #else /* TWISTER */ - sector = xp->x_secnum % xp->x_spt; - sector++; /* start numbering at 1 */ - - TRACE(printf("fd%d: %s: secnum=%d,cylinder=%d,spt=%d,sector=%d,head=%d\n", - xp->x_drive, xp->x_rw == DISK_READ ? "read" : "write", - xp->x_secnum, cylinder, xp->x_spt, sector, head)); - #endif dmawdat(FDC_SR, sector, FDC_DELAY); dmaaddr(xp->x_address); /* DMA address setup */ --- 230,243 ---- return(1); } TRACE(printf("fd%d: %s: secnum=%d,cylinder=%d,sector=%d,head=%d\n", xp->x_drive, xp->x_rw == DISK_READ ? "read" : "write", xp->x_secnum, cylinder, sector, head)); + + /* The drive is now on the proper cylinder. Read or write 1 block. */ sector = xp->x_secnum % NR_SECTORS; sector++; /* start numbering at 1 */ dmawdat(FDC_SR, sector, FDC_DELAY); dmaaddr(xp->x_address); /* DMA address setup */
ast@cs.vu.nl (Andy Tanenbaum) (01/09/89)
In article <357@lzaz.ATT.COM> hcj@lzaz.ATT.COM (HC Johnson) writes: >I just made a major discovery. My floppy drives (with a disk in them) are >spinning all the time I run Minix. Properly, until I do a floppy disk >operation in Minix. This can be days at a time. Is this also true on the PC? My machine has a fan that makes so much noise that I can't tell when the drives are on or off. The light certainly goes out, but that doesn't mean anything. Andy Tanenbaum (ast@cs.vu.nl)