Source-Changes-HG archive

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

[src/netbsd-3-0]: src/sys/dev/ata Pull up following revision(s) (requested by...



details:   https://anonhg.NetBSD.org/src/rev/3c13af1ba300
branches:  netbsd-3-0
changeset: 579455:3c13af1ba300
user:      riz <riz%NetBSD.org@localhost>
date:      Mon Oct 15 21:54:31 2007 +0000

description:
Pull up following revision(s) (requested by bouyer in ticket #1848):
        sys/dev/ata/wd.c: revision 1.345
Add a workaround for drives with the LBA48 bug:
if we get a "ID not found" error for a transfer crossing LBA48_THRESHOLD,
and the drive is larger than 128GB, automatically add WD_QUIRK_FORCE_LBA48
to the drive's quirks and retry the transfers.
Hopefully this will obsolete the WD_QUIRK_FORCE_LBA48 quirk list ...

diffstat:

 sys/dev/ata/wd.c |  28 ++++++++++++++++++++++++----
 1 files changed, 24 insertions(+), 4 deletions(-)

diffs (69 lines):

diff -r 87a5c0d77586 -r 3c13af1ba300 sys/dev/ata/wd.c
--- a/sys/dev/ata/wd.c  Thu Oct 04 18:37:20 2007 +0000
+++ b/sys/dev/ata/wd.c  Mon Oct 15 21:54:31 2007 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: wd.c,v 1.298.2.7.2.6 2006/11/20 14:56:09 ghen Exp $ */
+/*     $NetBSD: wd.c,v 1.298.2.7.2.7 2007/10/15 21:54:31 riz Exp $ */
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.298.2.7.2.6 2006/11/20 14:56:09 ghen Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.298.2.7.2.7 2007/10/15 21:54:31 riz Exp $");
 
 #ifndef ATADEBUG
 #define ATADEBUG
@@ -755,6 +755,7 @@
        int do_perror = 0;
        ATADEBUG_PRINT(("wddone %s\n", wd->sc_dev.dv_xname),
            DEBUG_XFERS);
+       int nblks;
 
        if (bp == NULL)
                return;
@@ -779,13 +780,33 @@
                        goto noerror;
                errmsg = "error";
                do_perror = 1;
+               if (wd->sc_wdc_bio.r_error & WDCE_IDNF &&
+                   (wd->sc_quirks & WD_QUIRK_FORCE_LBA48) == 0) {
+                       nblks = wd->sc_wdc_bio.bcount /
+                           wd->sc_dk.dk_label->d_secsize;
+                       /*
+                        * If we get a "id not found" when crossing the
+                        * LBA48_THRESHOLD, and the drive is larger than
+                        * 128GB, then we can assume the drive has the
+                        * LBA48 bug and we switch to LBA48.
+                        */
+                       if (wd->sc_wdc_bio.blkno <= LBA48_THRESHOLD &&
+                           wd->sc_wdc_bio.blkno + nblks > LBA48_THRESHOLD &&
+                           wd->sc_capacity > LBA48_THRESHOLD + 1) {
+                               errmsg = "LBA48 bug";
+                               wd->sc_quirks |= WD_QUIRK_FORCE_LBA48;
+                               do_perror = 0;
+                               goto retry2;
+                       }
+               }
 retry:         /* Just reset and retry. Can we do more ? */
                (*wd->atabus->ata_reset_drive)(wd->drvp, AT_RST_NOCMD);
 retry2:
                diskerr(bp, "wd", errmsg, LOG_PRINTF,
                    wd->sc_wdc_bio.blkdone, wd->sc_dk.dk_label);
                if (wd->retries < WDIORETRIES)
-                       printf(", retrying\n");
+                       printf(", retrying");
+               printf("\n");
                if (do_perror)
                        wdperror(wd);
                if (wd->retries < WDIORETRIES) {
@@ -794,7 +815,6 @@
                            wdrestart, wd);
                        return;
                }
-               printf("\n");
 
 #ifdef WD_SOFTBADSECT
                /*



Home | Main Index | Thread Index | Old Index