Added following formats (derived from MSDOS fdformat):
[unix-history] / sys / i386 / isa / fd.c
index 914d562..c459669 100644 (file)
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *     @(#)fd.c        7.4 (Berkeley) 5/25/91
+ *     from:   @(#)fd.c        7.4 (Berkeley) 5/25/91
+ *     $Id: fd.c,v 1.13 1993/12/16 04:28:42 ache Exp $
  *
  *
- * PATCHES MAGIC                LEVEL   PATCH THAT GOT US HERE
- * --------------------         -----   ----------------------
- * CURRENT PATCH LEVEL:         1       00153
- * --------------------         -----   ----------------------
- *
- * 20 Apr 93   Julian Elischer         Heavily re worked, see notes below
- * 
- * Largely rewritten to handle multiple controllers and drives
- * By Julian Elischer, Sun Apr  4 16:34:33 WST 1993
- */
-char   rev[] = "$Revision: 1.3 $";
-/*
- * $Header: /a/cvs/386BSD/src/sys/i386/isa/fd.c,v 1.3 1993/08/12 09:21:20 rgrimes Exp $
- */
-/*
- * $Log: fd.c,v $
- * Revision 1.3  1993/08/12  09:21:20  rgrimes
- * Fixed poor timeout code in out_fdc.  The timeout counter was not being
- * reinitialized between while loops.  Added comments about what was going
- * on in the out_fdc routine.
- *
- * out_fdc now returns if the direction bit is not set in time instead of
- * trying to wait for MRQ to get cleared.
- *
- * Revision 1.2  1993/07/15  17:53:04  davidg
- * Modified attach printf's so that the output is compatible with the "new"
- * way of doing things. There still remain several drivers that need to
- * be updated.  Also added a compile-time option to pccons to switch the
- * control and caps-lock keys (REVERSE_CAPS_CTRL) - added for my personal
- * sanity.
- *
- * Revision 1.1.1.1  1993/06/12  14:58:02  rgrimes
- * Initial import, 0.1 + pk 0.2.4-B1
- *
- * Revision 1.10  93/04/13  16:53:29  root
- * make sure turning off a drive motor doesn't deselect another
- * drive active at the time.
- * Also added a pointer from the fd_data to it's fd_type.
- * 
- * Revision 1.9  93/04/13  15:31:02  root
- * make all seeks go through DOSEEK state so are sure of being done right.
- * 
- * Revision 1.8  93/04/12  21:20:13  root
- * only check if old fd is the one we are working on if there IS
- * an old fd pointer. (in fdstate())
- * 
- * Revision 1.7  93/04/11  17:05:35  root
- * cleanup timeouts etc.
- * also fix bug to select teh correct drive when running > 1 drive
- * at a time.
- * 
- * Revision 1.6  93/04/05  00:48:45  root
- * change a timeout and add version to banner message
- * 
- * Revision 1.5  93/04/04  16:39:08  root
- * first working version.. some floppy controllers don't seem to
- * like 2 int. status inquiries in a row.
- * 
  */
 
 #include "fd.h"
  */
 
 #include "fd.h"
@@ -102,12 +45,14 @@ char       rev[] = "$Revision: 1.3 $";
 #include "param.h"
 #include "dkbad.h"
 #include "systm.h"
 #include "param.h"
 #include "dkbad.h"
 #include "systm.h"
+#include "kernel.h"
 #include "conf.h"
 #include "file.h"
 #include "ioctl.h"
 #include "disklabel.h"
 #include "buf.h"
 #include "uio.h"
 #include "conf.h"
 #include "file.h"
 #include "ioctl.h"
 #include "disklabel.h"
 #include "buf.h"
 #include "uio.h"
+#include "syslog.h"
 #include "i386/isa/isa.h"
 #include "i386/isa/isa_device.h"
 #include "i386/isa/fdreg.h"
 #include "i386/isa/isa.h"
 #include "i386/isa/isa_device.h"
 #include "i386/isa/fdreg.h"
@@ -116,12 +61,11 @@ char       rev[] = "$Revision: 1.3 $";
 #undef NFD
 #define NFD 2
 
 #undef NFD
 #define NFD 2
 
-#define        FDUNIT(s)       ((s>>3)&1)
-#define        FDTYPE(s)       ((s)&7)
+#define FDUNIT(s)       (((s)>>6)&03)
+#define FDTYPE(s)       ((s)&077)
 
 #define b_cylin b_resid
 #define FDBLK 512
 
 #define b_cylin b_resid
 #define FDBLK 512
-#define NUMTYPES 4
 
 struct fd_type {
        int     sectrac;                /* sectors per track         */
 
 struct fd_type {
        int     sectrac;                /* sectors per track         */
@@ -135,12 +79,31 @@ struct fd_type {
        int     heads;                  /* number of heads           */
 };
 
        int     heads;                  /* number of heads           */
 };
 
+#define NUMTYPES 9
+
+/* This defines must match fd_types */
+#define FD_1440         0
+#define FD_1200         1
+#define FD_360in1200    2
+#define FD_360          3
+#define FD_720in1440    4
+#define FD_720in1200 FD_720in1440
+#define FD_1720in1440   5
+#define FD_800in1200    6
+#define FD_1440in1200   7
+#define FD_1460in1200   8
+
 struct fd_type fd_types[NUMTYPES] =
 {
 struct fd_type fd_types[NUMTYPES] =
 {
-       { 18,2,0xFF,0x1B,80,2880,1,0,2 }, /* 1.44 meg HD 3.5in floppy    */
-       { 15,2,0xFF,0x1B,80,2400,1,0,2 }, /* 1.2 meg HD floppy           */
-       { 9,2,0xFF,0x23,40,720,2,1,2 }, /* 360k floppy in 1.2meg drive */
-       { 9,2,0xFF,0x2A,40,720,1,1,2 }, /* 360k floppy in DD drive     */
+       { 18,2,0xFF,0x1B,80,2880,1,0,2 }, /* 1.44M in HD 3.5in  drive */
+       { 15,2,0xFF,0x1B,80,2400,1,0,2 }, /*  1.2M in HD 5.25in drive */
+       { 9,2,0xFF,0x23,40,720,2,1,2 },   /*  360K in HD 5.25in drive */
+       { 9,2,0xFF,0x2A,40,720,1,1,2 },   /*  360K in DD 5.25in drive */
+       { 9,2,0xFF,0x20,80,1440,1,1,2 },  /*  720K in HD 3.5in  drive */
+       { 21,2,0xFF,0x0C,82,3444,1,0,2 }, /* 1.72M in HD 3.5in  drive */
+       { 10,2,0xFF,0x2E,80,1600,1,1,2 }, /*  800K in HD 5.25in drive */
+       { 18,2,0xFF,0x02,80,2880,1,0,2 }, /* 1.44M in HD 5.25in drive */
+       { 18,2,0xFF,0x02,82,2952,1,0,2 }, /* 1.46M in HD 5.25in drive */
 };
 
 #define DRVS_PER_CTLR 2
 };
 
 #define DRVS_PER_CTLR 2
@@ -231,18 +194,20 @@ char *fdstates[] =
 int    fd_debug = 1;
 #define TRACE0(arg) if(fd_debug) printf(arg)
 #define TRACE1(arg1,arg2) if(fd_debug) printf(arg1,arg2)
 int    fd_debug = 1;
 #define TRACE0(arg) if(fd_debug) printf(arg)
 #define TRACE1(arg1,arg2) if(fd_debug) printf(arg1,arg2)
-#else  DEBUG
+#else /* DEBUG */
 #define TRACE0(arg)
 #define TRACE1(arg1,arg2)
 #define TRACE0(arg)
 #define TRACE1(arg1,arg2)
-#endif DEBUG
+#endif /* DEBUG */
 
 
-extern int hz;
-/* state needed for current transfer */
+static void fdstart(fdcu_t);
+void fdintr(fdcu_t);
+static void fd_turnoff(caddr_t, int);
 
 /****************************************************************************/
 /*                      autoconfiguration stuff                             */
 /****************************************************************************/
 
 /****************************************************************************/
 /*                      autoconfiguration stuff                             */
 /****************************************************************************/
-int fdprobe(), fdattach(), fd_turnoff();
+static int fdprobe(struct isa_device *);
+static int fdattach(struct isa_device *);
 
 struct isa_driver fddriver = {
        fdprobe, fdattach, "fd",
 
 struct isa_driver fddriver = {
        fdprobe, fdattach, "fd",
@@ -251,8 +216,9 @@ struct      isa_driver fddriver = {
 /*
  * probe for existance of controller
  */
 /*
  * probe for existance of controller
  */
+int
 fdprobe(dev)
 fdprobe(dev)
-struct isa_device *dev;
+       struct isa_device *dev;
 {
        fdcu_t  fdcu = dev->id_unit;
        if(fdc_data[fdcu].flags & FDC_ATTACHED)
 {
        fdcu_t  fdcu = dev->id_unit;
        if(fdc_data[fdcu].flags & FDC_ATTACHED)
@@ -263,6 +229,12 @@ struct isa_device *dev;
 
        fdc_data[fdcu].baseport = dev->id_iobase;
 
 
        fdc_data[fdcu].baseport = dev->id_iobase;
 
+       /* First - lets reset the floppy controller */
+
+       outb(dev->id_iobase+fdout,0);
+       DELAY(100);
+       outb(dev->id_iobase+fdout,FDO_FRST);
+
        /* see if it can handle a command */
        if (out_fdc(fdcu,NE7CMD_SPECIFY) < 0)
        {
        /* see if it can handle a command */
        if (out_fdc(fdcu,NE7CMD_SPECIFY) < 0)
        {
@@ -276,8 +248,9 @@ struct isa_device *dev;
 /*
  * wire controller into system, look for floppy units
  */
 /*
  * wire controller into system, look for floppy units
  */
+int
 fdattach(dev)
 fdattach(dev)
-struct isa_device *dev;
+       struct isa_device *dev;
 {
        unsigned fdt,st0, cyl;
        int     hdr;
 {
        unsigned fdt,st0, cyl;
        int     hdr;
@@ -328,30 +301,38 @@ struct isa_device *dev;
                fd_data[fdu].fdsu = fdsu;
                printf("fd%d: unit %d type ", fdcu, fdu);
                
                fd_data[fdu].fdsu = fdsu;
                printf("fd%d: unit %d type ", fdcu, fdu);
                
-               if ((fdt & 0xf0) == RTCFDT_12M) {
+               switch (fdt & 0xf0) {
+               case RTCFDT_12M:
                        printf("1.2MB 5.25in\n");
                        printf("1.2MB 5.25in\n");
-                       fd_data[fdu].type = 1;
-                       fd_data[fdu].ft = fd_types + 1;
-                       
-               }
-               if ((fdt & 0xf0) == RTCFDT_144M) {
+                       fd_data[fdu].type = FD_1200;
+                       break;
+               case RTCFDT_144M:
                        printf("1.44MB 3.5in\n");
                        printf("1.44MB 3.5in\n");
-                       fd_data[fdu].type = 0;
-                       fd_data[fdu].ft = fd_types + 0;
+                       fd_data[fdu].type = FD_1440;
+                       break;
+               case RTCFDT_360K:
+                       printf("360K 5.25in\n");
+                       fd_data[fdu].type = FD_360;
+                       break;
+               default:
+                       printf("unknown\n");
+                       fd_data[fdu].type = NO_TYPE;
+                       break;
                }
 
                fdt <<= 4;
                }
 
                fdt <<= 4;
-               fd_turnoff(fdu);
+               fd_turnoff((caddr_t)fdu, 0);
                hdr = 1;
        }
 
        /* Set transfer to 500kbps */
        outb(fdc->baseport+fdctl,0); /*XXX*/
                hdr = 1;
        }
 
        /* Set transfer to 500kbps */
        outb(fdc->baseport+fdctl,0); /*XXX*/
+       return 1;
 }
 
 int
 fdsize(dev)
 }
 
 int
 fdsize(dev)
-dev_t  dev;
+       dev_t   dev;
 {
        return(0);
 }
 {
        return(0);
 }
@@ -359,8 +340,7 @@ dev_t       dev;
 /****************************************************************************/
 /*                               fdstrategy                                 */
 /****************************************************************************/
 /****************************************************************************/
 /*                               fdstrategy                                 */
 /****************************************************************************/
-fdstrategy(bp)
-       register struct buf *bp;        /* IO operation to perform */
+void fdstrategy(struct buf *bp)
 {
        register struct buf *dp,*dp0,*dp1;
        long nblocks,blknum;
 {
        register struct buf *dp,*dp0,*dp1;
        long nblocks,blknum;
@@ -415,6 +395,7 @@ bad:
 /*                            motor control stuff                           */
 /*             remember to not deselect the drive we're working on         */
 /****************************************************************************/
 /*                            motor control stuff                           */
 /*             remember to not deselect the drive we're working on         */
 /****************************************************************************/
+void
 set_motor(fdcu, fdu, reset)
        fdcu_t fdcu;
        fdu_t fdu;
 set_motor(fdcu, fdu, reset)
        fdcu_t fdcu;
        fdu_t fdu;
@@ -445,9 +426,10 @@ set_motor(fdcu, fdu, reset)
                | (m1 ? FDO_MOEN1 : 0)));
 }
 
                | (m1 ? FDO_MOEN1 : 0)));
 }
 
-fd_turnoff(fdu)
-       fdu_t fdu;
+static void
+fd_turnoff(caddr_t arg1, int arg2)
 {
 {
+       fdu_t fdu = (fdu_t)arg1;
        int     s;
 
        fd_p fd = fd_data + fdu;
        int     s;
 
        fd_p fd = fd_data + fdu;
@@ -457,9 +439,10 @@ fd_turnoff(fdu)
        splx(s);
 }
 
        splx(s);
 }
 
-fd_motor_on(fdu)
-       fdu_t fdu;
+void
+fd_motor_on(caddr_t arg1, int arg2)
 {
 {
+       fdu_t fdu = (fdu_t)arg1;
        int     s;
 
        fd_p fd = fd_data + fdu;
        int     s;
 
        fd_p fd = fd_data + fdu;
@@ -472,6 +455,9 @@ fd_motor_on(fdu)
        splx(s);
 }
 
        splx(s);
 }
 
+static void fd_turnon1(fdu_t);
+
+void
 fd_turnon(fdu) 
        fdu_t fdu;
 {
 fd_turnon(fdu) 
        fdu_t fdu;
 {
@@ -480,12 +466,12 @@ fd_turnon(fdu)
        {
                fd_turnon1(fdu);
                fd->flags |= FD_MOTOR_WAIT;
        {
                fd_turnon1(fdu);
                fd->flags |= FD_MOTOR_WAIT;
-               timeout(fd_motor_on,fdu,hz); /* in 1 sec its ok */
+               timeout(fd_motor_on, (caddr_t)fdu, hz); /* in 1 sec its ok */
        }
 }
 
        }
 }
 
-fd_turnon1(fdu) 
-       fdu_t fdu;
+static void
+fd_turnon1(fdu_t fdu) 
 {
        fd_p fd = fd_data + fdu;
        fd->flags |= FD_MOTOR;
 {
        fd_p fd = fd_data + fdu;
        fd->flags |= FD_MOTOR;
@@ -515,6 +501,7 @@ in_fdc(fdcu)
 #endif
 }
 
 #endif
 }
 
+int
 out_fdc(fdcu, x)
        fdcu_t fdcu;
        int x;
 out_fdc(fdcu, x)
        fdcu_t fdcu;
        int x;
@@ -541,24 +528,55 @@ out_fdc(fdcu, x)
 /****************************************************************************/
 /*                           fdopen/fdclose                                 */
 /****************************************************************************/
 /****************************************************************************/
 /*                           fdopen/fdclose                                 */
 /****************************************************************************/
+int
 Fdopen(dev, flags)
        dev_t   dev;
        int     flags;
 {
        fdu_t fdu = FDUNIT(minor(dev));
 Fdopen(dev, flags)
        dev_t   dev;
        int     flags;
 {
        fdu_t fdu = FDUNIT(minor(dev));
-       /*int type = FDTYPE(minor(dev));*/
+       int type = FDTYPE(minor(dev));
        int s;
 
        /* check bounds */
        int s;
 
        /* check bounds */
-       if (fdu >= NFD || fd_data[fdu].type == NO_TYPE) return(ENXIO);
-       /*if (type >= NUMTYPES) return(ENXIO);*/
+       if (fdu >= NFD || fd_data[fdu].fdc == NULL
+               || fd_data[fdu].type == NO_TYPE) return(ENXIO);
+       if (type > NUMTYPES) return(ENXIO);
+       if (type == 0)
+               type = fd_data[fdu].type;
+       else {
+               type--;
+               if (type != fd_data[fdu].type) {
+                       switch (fd_data[fdu].type) {
+                       case FD_360:
+                               return(ENXIO);
+                       case FD_1200:
+                               if (   type != FD_720in1200
+                                   && type != FD_360in1200
+                                   && type != FD_800in1200
+                                   && type != FD_1440in1200
+                                   && type != FD_1460in1200
+                                  )
+                                       return(ENXIO);
+                               break;
+                       case FD_1440:
+                               if (   type != FD_1720in1440
+                                   && type != FD_720in1440
+                                  )
+                                       return(ENXIO);
+                               break;
+                       }
+               }
+       }
+       fd_data[fdu].ft = fd_types + type;
        fd_data[fdu].flags |= FD_OPEN;
 
        return 0;
 }
 
        fd_data[fdu].flags |= FD_OPEN;
 
        return 0;
 }
 
+int
 fdclose(dev, flags)
        dev_t dev;
 fdclose(dev, flags)
        dev_t dev;
+       int flags;
 {
        fdu_t fdu = FDUNIT(minor(dev));
        fd_data[fdu].flags &= ~FD_OPEN;
 {
        fdu_t fdu = FDUNIT(minor(dev));
        fd_data[fdu].flags &= ~FD_OPEN;
@@ -575,6 +593,7 @@ fdclose(dev, flags)
 * If the controller is already busy, we need do nothing, as it *
 * will pick up our work when the present work completes                *
 \***************************************************************/
 * If the controller is already busy, we need do nothing, as it *
 * will pick up our work when the present work completes                *
 \***************************************************************/
+static void
 fdstart(fdcu)
        fdcu_t fdcu;
 {
 fdstart(fdcu)
        fdcu_t fdcu;
 {
@@ -590,9 +609,10 @@ fdstart(fdcu)
        splx(s);
 }
 
        splx(s);
 }
 
-fd_timeout(fdcu)
-       fdcu_t fdcu;
+static void
+fd_timeout(caddr_t arg1, int arg2)
 {
 {
+       fdcu_t fdcu = (fdcu_t)arg1;
        fdu_t fdu = fdc_data[fdcu].fdu;
        int st0, st3, cyl;
        struct buf *dp,*bp;
        fdu_t fdu = fdc_data[fdcu].fdu;
        int st0, st3, cyl;
        struct buf *dp,*bp;
@@ -636,9 +656,10 @@ fd_timeout(fdcu)
 }
 
 /* just ensure it has the right spl */
 }
 
 /* just ensure it has the right spl */
-fd_pseudointr(fdcu)
-       fdcu_t fdcu;
+static void
+fd_pseudointr(caddr_t arg1, int arg2)
 {
 {
+       fdcu_t fdcu = (fdcu_t)arg1;
        int     s;
        s = splbio();
        fdintr(fdcu);
        int     s;
        s = splbio();
        fdintr(fdcu);
@@ -650,22 +671,24 @@ fd_pseudointr(fdcu)
 * keep calling the state machine until it returns a 0                  *
 * ALWAYS called at SPLBIO                                              *
 \***********************************************************************/
 * keep calling the state machine until it returns a 0                  *
 * ALWAYS called at SPLBIO                                              *
 \***********************************************************************/
-fdintr(fdcu)
-       fdcu_t fdcu;
+void
+fdintr(fdcu_t fdcu)
 {
        fdc_p fdc = fdc_data + fdcu;
 {
        fdc_p fdc = fdc_data + fdcu;
-       while(fdstate(fdcu, fdc));
+       while(fdstate(fdcu, fdc))
+         ;
 }
 
 /***********************************************************************\
 * The controller state machine.                                                *
 * if it returns a non zero value, it should be called again immediatly *
 \***********************************************************************/
 }
 
 /***********************************************************************\
 * The controller state machine.                                                *
 * if it returns a non zero value, it should be called again immediatly *
 \***********************************************************************/
-int fdstate(fdcu, fdc)
+int
+fdstate(fdcu, fdc)
        fdcu_t fdcu;
        fdc_p fdc;
 {
        fdcu_t fdcu;
        fdc_p fdc;
 {
-       int read,head,trac,sec,i,s,sectrac,cyl,st0;
+       int read, head, trac, sec = 0, i = 0, s, sectrac, cyl, st0;
        unsigned long blknum;
        fdu_t fdu = fdc->fdu;
        fd_p fd;
        unsigned long blknum;
        fdu_t fdu = fdc->fdu;
        fd_p fd;
@@ -701,7 +724,7 @@ int fdstate(fdcu, fdc)
        TRACE1("[%s]",fdstates[fdc->state]);
        TRACE1("(0x%x)",fd->flags);
        untimeout(fd_turnoff, fdu);
        TRACE1("[%s]",fdstates[fdc->state]);
        TRACE1("(0x%x)",fd->flags);
        untimeout(fd_turnoff, fdu);
-       timeout(fd_turnoff,fdu,4 * hz);
+       timeout(fd_turnoff, (caddr_t)fdu, 4 * hz);
        switch (fdc->state)
        {
        case DEVIDLE:
        switch (fdc->state)
        {
        case DEVIDLE:
@@ -745,12 +768,12 @@ int fdstate(fdcu, fdc)
                out_fdc(fdcu,bp->b_cylin * fd->ft->steptrac);
                fd->track = -2;
                fdc->state = SEEKWAIT;
                out_fdc(fdcu,bp->b_cylin * fd->ft->steptrac);
                fd->track = -2;
                fdc->state = SEEKWAIT;
-               timeout(fd_timeout,fdcu,2 * hz);
+               timeout(fd_timeout, (caddr_t)fdcu, 2 * hz);
                return(0);      /* will return later */
        case SEEKWAIT:
                untimeout(fd_timeout,fdcu);
                /* allow heads to settle */
                return(0);      /* will return later */
        case SEEKWAIT:
                untimeout(fd_timeout,fdcu);
                /* allow heads to settle */
-               timeout(fd_pseudointr,fdcu,hz/50);
+               timeout(fd_pseudointr, (caddr_t)fdcu, hz / 50);
                fdc->state = SEEKCOMPLETE;
                return(0);      /* will return later */
                break;
                fdc->state = SEEKCOMPLETE;
                return(0);      /* will return later */
                break;
@@ -799,7 +822,7 @@ int fdstate(fdcu, fdc)
                out_fdc(fdcu,fd->ft->gap);              /* gap size */
                out_fdc(fdcu,fd->ft->datalen);          /* data length */
                fdc->state = IOCOMPLETE;
                out_fdc(fdcu,fd->ft->gap);              /* gap size */
                out_fdc(fdcu,fd->ft->datalen);          /* data length */
                fdc->state = IOCOMPLETE;
-               timeout(fd_timeout,fdcu,2 * hz);
+               timeout(fd_timeout, (caddr_t)fdcu, 2 * hz);
                return(0);      /* will return later */
        case IOCOMPLETE: /* IO DONE, post-analyze */
                untimeout(fd_timeout,fdcu);
                return(0);      /* will return later */
        case IOCOMPLETE: /* IO DONE, post-analyze */
                untimeout(fd_timeout,fdcu);
@@ -856,7 +879,7 @@ int fdstate(fdcu, fdc)
                return(0);      /* will return later */
        case RECALWAIT:
                /* allow heads to settle */
                return(0);      /* will return later */
        case RECALWAIT:
                /* allow heads to settle */
-               timeout(fd_pseudointr,fdcu,hz/30);
+               timeout(fd_pseudointr, (caddr_t)fdcu, hz / 30);
                fdc->state = RECALCOMPLETE;
                return(0);      /* will return later */
        case RECALCOMPLETE:
                fdc->state = RECALCOMPLETE;
                return(0);      /* will return later */
        case RECALCOMPLETE:
@@ -904,6 +927,7 @@ int fdstate(fdcu, fdc)
        return(1); /* Come back immediatly to new state */
 }
 
        return(1); /* Come back immediatly to new state */
 }
 
+int
 retrier(fdcu)
        fdcu_t fdcu;
 {
 retrier(fdcu)
        fdcu_t fdcu;
 {
@@ -928,13 +952,17 @@ retrier(fdcu)
                break;
        default:
                {
                break;
        default:
                {
-                       printf("fd%d: hard error (ST0 %b ",
-                                fdc->fdu, fdc->status[0], NE7_ST0BITS);
+                       dev_t sav_b_dev = bp->b_dev;
+                       /* Trick diskerr */
+                       bp->b_dev = makedev(major(bp->b_dev), (FDUNIT(minor(bp->b_dev))<<3)|3);
+                       diskerr(bp, "fd", "hard error", LOG_PRINTF,
+                               fdc->fd->skip, (struct disklabel *)NULL);
+                       bp->b_dev = sav_b_dev;
+                       printf(" (ST0 %b ", fdc->status[0], NE7_ST0BITS);
                        printf(" ST1 %b ", fdc->status[1], NE7_ST1BITS);
                        printf(" ST2 %b ", fdc->status[2], NE7_ST2BITS);
                        printf(" ST1 %b ", fdc->status[1], NE7_ST1BITS);
                        printf(" ST2 %b ", fdc->status[2], NE7_ST2BITS);
-                       printf(" ST3 %b ", fdc->status[3], NE7_ST3BITS);
                        printf("cyl %d hd %d sec %d)\n",
                        printf("cyl %d hd %d sec %d)\n",
-                                fdc->status[4], fdc->status[5], fdc->status[6]);
+                              fdc->status[3], fdc->status[4], fdc->status[5]);
                }
                bp->b_flags |= B_ERROR;
                bp->b_error = EIO;
                }
                bp->b_flags |= B_ERROR;
                bp->b_error = EIO;
@@ -942,11 +970,11 @@ retrier(fdcu)
                dp->b_actf = bp->av_forw;
                fdc->fd->skip = 0;
                biodone(bp);
                dp->b_actf = bp->av_forw;
                fdc->fd->skip = 0;
                biodone(bp);
-               fdc->state = DEVIDLE;
+               fdc->state = FINDWORK;
                fdc->fd = (fd_p) 0;
                fdc->fdu = -1;
                /* XXX abort current command, if any.  */
                fdc->fd = (fd_p) 0;
                fdc->fdu = -1;
                /* XXX abort current command, if any.  */
-               return(0);
+               return(1);
        }
        fdc->retry++;
        return(1);
        }
        fdc->retry++;
        return(1);
@@ -983,7 +1011,7 @@ int flag;
         bzero(buffer, sizeof (buffer));
         dl = (struct disklabel *)buffer;
         dl->d_secsize = FDBLK;
         bzero(buffer, sizeof (buffer));
         dl = (struct disklabel *)buffer;
         dl->d_secsize = FDBLK;
-        fdt = &fd_types[FDUNIT(minor(dev))];
+        fdt = fd_data[FDUNIT(minor(dev))].ft;
         dl->d_secpercyl = fdt->size / fdt->tracks;
         dl->d_type = DTYPE_FLOPPY;
 
         dl->d_secpercyl = fdt->size / fdt->tracks;
         dl->d_type = DTYPE_FLOPPY;