From 92ed385a0941b92e9b58a7de7c9a323f50aebb88 Mon Sep 17 00:00:00 2001 From: "Rodney W. Grimes" Date: Thu, 23 Sep 1993 15:22:57 +0000 Subject: [PATCH] >From: bde@kralizec.zeta.org.au (Bruce Evans) Date: Thu, 16 Sep 93 01:35:10 +1000 Julian writes: >In fact DEVIDLE and FINDWORK ended up being basically equivalent. >the bit I wonder about, is the returning of 0.. What (other than >another request from somewhere else in the kernel) is going to start >work on the next item on the queue? I think removing FINDWORK would make things clearer. Nothing much is going to start work on the next item. However, it is pointless to continue processing the queue for the same unready drive. Aborting all reads and trying harder to perform all writes would be better. Julian writes. > no, actually it should be: > fdt = fd_data[FDUNIT(minor(dev))].ft; Fixed. From: bde@kralizec.zeta.org.au (Bruce Evans) Date: Thu, 16 Sep 93 22:56:01 +1000 The fd driver reported the wrong cylinder/head/sector numbers after an error (ST3 is only valid after a sense-drive command), and didn't report fs block numbers (diskerr was not used). There was an old problem with writes to block fd devices. Try this: 1. write protect floppy in fd0. 2. tar cf /dev/fd0a /dev/null. Repeat a few times. Later writes tend to terminate earlier. 3. un-write protect floppy. 4. repeat step 2. The writes tend to return 0, 2048, 4096, ... and then succeed. This was caused by a bug in vfs__bios.c. (The bug is fixed in NetBSD's vfs_bio.c.) fd.c sets bp->b_resid to nonzero after an error. vfs__bios.c was not initializing bp->b_resid. This causes some writes to terminate early (e.g., writes to block devices; see spec_write()). Related funnies: 1. Nothing tries to write the residual bytes. 2. The wd driver sets bp->b_resid to 0 after an error, so there's no way anything else could write the residual bytes. 3. I use the block fd device for tar because the raw device seemed to have more bugs long ago, and because it ought to be able to handle buffering more transparently (I don't want to have to know the device size). But spec_write() always uses the size BLKDEV_IOSIZE == 2048 which is too small. For disks it should use the size of one track (rounded down to meet the next track boundary or the i/o size). Here it would help if the DIOCGPART ioctl worked. But DIOCGPART is not implemented for floppies, and the disk size is ignored except for partitions of type FS_BSDFFS. Bruce --- sys/dev/fdc/fdc.c | 17 +++++++++-------- sys/i386/isa/fd.c | 17 +++++++++-------- sys/isa/fd.c | 17 +++++++++-------- 3 files changed, 27 insertions(+), 24 deletions(-) diff --git a/sys/dev/fdc/fdc.c b/sys/dev/fdc/fdc.c index bd43a2d1c4c0..c287ef185074 100644 --- a/sys/dev/fdc/fdc.c +++ b/sys/dev/fdc/fdc.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)fd.c 7.4 (Berkeley) 5/25/91 - * $Id$ + * $Id: fd.c,v 1.5 1993/09/15 23:27:45 rgrimes Exp $ * */ @@ -51,6 +51,7 @@ #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" @@ -871,13 +872,13 @@ retrier(fdcu) break; default: { - printf("fd%d: hard error (ST0 %b ", - fdc->fdu, fdc->status[0], NE7_ST0BITS); + diskerr(bp, "fd", "hard error", LOG_PRINTF, + fdc->fd->skip, (struct disklabel *)NULL); + 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(" ST3 %b ", fdc->status[3], NE7_ST3BITS); 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; @@ -885,11 +886,11 @@ retrier(fdcu) 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. */ - return(0); + return(1); } fdc->retry++; return(1); @@ -926,7 +927,7 @@ int flag; 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; diff --git a/sys/i386/isa/fd.c b/sys/i386/isa/fd.c index bd43a2d1c4c0..c287ef185074 100644 --- a/sys/i386/isa/fd.c +++ b/sys/i386/isa/fd.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)fd.c 7.4 (Berkeley) 5/25/91 - * $Id$ + * $Id: fd.c,v 1.5 1993/09/15 23:27:45 rgrimes Exp $ * */ @@ -51,6 +51,7 @@ #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" @@ -871,13 +872,13 @@ retrier(fdcu) break; default: { - printf("fd%d: hard error (ST0 %b ", - fdc->fdu, fdc->status[0], NE7_ST0BITS); + diskerr(bp, "fd", "hard error", LOG_PRINTF, + fdc->fd->skip, (struct disklabel *)NULL); + 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(" ST3 %b ", fdc->status[3], NE7_ST3BITS); 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; @@ -885,11 +886,11 @@ retrier(fdcu) 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. */ - return(0); + return(1); } fdc->retry++; return(1); @@ -926,7 +927,7 @@ int flag; 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; diff --git a/sys/isa/fd.c b/sys/isa/fd.c index bd43a2d1c4c0..c287ef185074 100644 --- a/sys/isa/fd.c +++ b/sys/isa/fd.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)fd.c 7.4 (Berkeley) 5/25/91 - * $Id$ + * $Id: fd.c,v 1.5 1993/09/15 23:27:45 rgrimes Exp $ * */ @@ -51,6 +51,7 @@ #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" @@ -871,13 +872,13 @@ retrier(fdcu) break; default: { - printf("fd%d: hard error (ST0 %b ", - fdc->fdu, fdc->status[0], NE7_ST0BITS); + diskerr(bp, "fd", "hard error", LOG_PRINTF, + fdc->fd->skip, (struct disklabel *)NULL); + 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(" ST3 %b ", fdc->status[3], NE7_ST3BITS); 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; @@ -885,11 +886,11 @@ retrier(fdcu) 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. */ - return(0); + return(1); } fdc->retry++; return(1); @@ -926,7 +927,7 @@ int flag; 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;