Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/ata remove the workaround for Seagate 'mod15write' b...



details:   https://anonhg.NetBSD.org/src/rev/a06d92c76c68
branches:  trunk
changeset: 823469:a06d92c76c68
user:      jdolecek <jdolecek%NetBSD.org@localhost>
date:      Mon Apr 24 09:42:52 2017 +0000

description:
remove the workaround for Seagate 'mod15write' bug, now driver only prints
error on boog; unfortunately the code actually doesn't work, and there is
little point trying to fix

diffstat:

 sys/dev/ata/wd.c |  117 +++---------------------------------------------------
 1 files changed, 8 insertions(+), 109 deletions(-)

diffs (156 lines):

diff -r cfce1844a940 -r a06d92c76c68 sys/dev/ata/wd.c
--- a/sys/dev/ata/wd.c  Mon Apr 24 09:42:19 2017 +0000
+++ b/sys/dev/ata/wd.c  Mon Apr 24 09:42:52 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: wd.c,v 1.428 2017/03/05 23:07:12 mlelstv Exp $ */
+/*     $NetBSD: wd.c,v 1.429 2017/04/24 09:42:52 jdolecek Exp $ */
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -54,7 +54,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428 2017/03/05 23:07:12 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.429 2017/04/24 09:42:52 jdolecek Exp $");
 
 #include "opt_ata.h"
 
@@ -344,6 +344,10 @@
                char sbuf[sizeof(WD_QUIRK_FMT) + 64];
                snprintb(sbuf, sizeof(sbuf), WD_QUIRK_FMT, wd->sc_quirks);
                aprint_normal_dev(self, "quirks %s\n", sbuf);
+
+               if (wd->sc_quirks & WD_QUIRK_SPLIT_MOD15_WRITE) {
+                       aprint_error_dev(self, "drive corrupts write transfers with certain controllers, consider replacing\n");
+               }
        }
 
        if ((wd->sc_params.atap_multi & 0xff) > 1) {
@@ -647,110 +651,10 @@
        }
 }
 
-static void
-wd_split_mod15_write(struct buf *bp)
-{
-       struct buf *obp = bp->b_private;
-       struct wd_softc *sc =
-           device_lookup_private(&wd_cd, DISKUNIT(obp->b_dev));
-       int s;
-
-       if (__predict_false(bp->b_error != 0)) {
-               /*
-                * Propagate the error.  If this was the first half of
-                * the original transfer, make sure to account for that
-                * in the residual.
-                */
-               if (bp->b_data == obp->b_data)
-                       bp->b_resid += bp->b_bcount;
-               goto done;
-       }
-
-       /*
-        * If this was the second half of the transfer, we're all done!
-        */
-       if (bp->b_data != obp->b_data)
-               goto done;
-
-       /*
-        * Advance the pointer to the second half and issue that command
-        * using the same opening.
-        */
-       bp->b_flags = obp->b_flags;
-       bp->b_oflags = obp->b_oflags;
-       bp->b_cflags = obp->b_cflags;
-       bp->b_data = (char *)bp->b_data + bp->b_bcount;
-       bp->b_blkno += (bp->b_bcount / DEV_BSIZE);
-       bp->b_rawblkno += (bp->b_bcount / sc->sc_blksize);
-       s = splbio();
-       wdstart1(sc, bp);
-       splx(s);
-       return;
-
- done:
-       obp->b_error = bp->b_error;
-       obp->b_resid = bp->b_resid;
-       s = splbio();
-       putiobuf(bp);
-       biodone(obp);
-       sc->openings++;
-       splx(s);
-       /* wddone() will call wdstart() */
-}
-
 void
 wdstart1(struct wd_softc *wd, struct buf *bp)
 {
 
-       /*
-        * Deal with the "split mod15 write" quirk.  We just divide the
-        * transfer in two, doing the first half and then then second half
-        * with the same command opening.
-        *
-        * Note we MUST do this here, because we can't let insertion
-        * into the bufq cause the transfers to be re-merged.
-        */
-       if (__predict_false((wd->sc_quirks & WD_QUIRK_SPLIT_MOD15_WRITE) != 0 &&
-                           (bp->b_flags & B_READ) == 0 &&
-                           bp->b_bcount > 512 &&
-                           ((bp->b_bcount / 512) % 15) == 1)) {
-               struct buf *nbp;
-
-               /* already at splbio */
-               nbp = getiobuf(NULL, false);
-               if (__predict_false(nbp == NULL)) {
-                       /* No memory -- fail the iop. */
-                       bp->b_error = ENOMEM;
-                       bp->b_resid = bp->b_bcount;
-                       biodone(bp);
-                       wd->openings++;
-                       return;
-               }
-
-               nbp->b_error = 0;
-               nbp->b_proc = bp->b_proc;
-               nbp->b_dev = bp->b_dev;
-
-               nbp->b_bcount = bp->b_bcount / 2;
-               nbp->b_bufsize = bp->b_bcount / 2;
-               nbp->b_data = bp->b_data;
-
-               nbp->b_blkno = bp->b_blkno;
-               nbp->b_rawblkno = bp->b_rawblkno;
-
-               nbp->b_flags = bp->b_flags;
-               nbp->b_oflags = bp->b_oflags;
-               nbp->b_cflags = bp->b_cflags;
-               nbp->b_iodone = wd_split_mod15_write;
-
-               /* Put ptr to orig buf in b_private and use new buf */
-               nbp->b_private = bp;
-
-               BIO_COPYPRIO(nbp, bp);
-
-               bp = nbp;
-       }
-
        wd->sc_wdc_bio.blkno = bp->b_rawblkno;
        wd->sc_wdc_bio.bcount = bp->b_bcount;
        wd->sc_wdc_bio.databuf = bp->b_data;
@@ -882,13 +786,8 @@
        disk_unbusy(&wd->sc_dk, (bp->b_bcount - bp->b_resid),
            (bp->b_flags & B_READ));
        rnd_add_uint32(&wd->rnd_source, bp->b_blkno);
-       /* XXX Yuck, but we don't want to increment openings in this case */
-       if (__predict_false(bp->b_iodone == wd_split_mod15_write))
-               biodone(bp);
-       else {
-               biodone(bp);
-               wd->openings++;
-       }
+       biodone(bp);
+       wd->openings++;
        KASSERT(wd->sc_bp != NULL);
        wd->sc_bp = NULL;
        wdstart(wd);



Home | Main Index | Thread Index | Old Index