Source-Changes-HG archive

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

[src/trunk]: src/sys ahcisata(4): Introduce AHCI_QUIRK_EXTRA_DELAY quirk for ...



details:   https://anonhg.NetBSD.org/src/rev/5ec90965a167
branches:  trunk
changeset: 1026347:5ec90965a167
user:      rin <rin%NetBSD.org@localhost>
date:      Fri Nov 19 23:46:54 2021 +0000

description:
ahcisata(4): Introduce AHCI_QUIRK_EXTRA_DELAY quirk for devices that
need extra delays as done by AHCISATA_EXTRA_DELAY option.

Enable this quirk for "C600/X79 AHCI". Also add commented out quirk
entries for "Bay Trail SATA (AHCI)" and "Mobile AHCI SATA Controller",
for which non-reproducible failures worked around by extra delays have
been reported.

500 ms of delays inserted by these option/quirk may be too much. Add
AHCISATA_EXTRA_DELAY_MS option to adjust number of delays in ms, like:

----
options         AHCISATA_EXTRA_DELAY_MS=200
----

Thanks prlw1@ and jun@ for testing!

diffstat:

 sys/conf/files             |   3 ++-
 sys/dev/ic/ahcisata_core.c |  40 +++++++++++++++++++++++++---------------
 sys/dev/ic/ahcisatavar.h   |   3 ++-
 sys/dev/pci/ahcisata_pci.c |  23 +++++++++++++++++++++--
 4 files changed, 50 insertions(+), 19 deletions(-)

diffs (167 lines):

diff -r 21cac150b9ae -r 5ec90965a167 sys/conf/files
--- a/sys/conf/files    Fri Nov 19 22:24:29 2021 +0000
+++ b/sys/conf/files    Fri Nov 19 23:46:54 2021 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files,v 1.1289 2021/10/11 13:42:33 jmcneill Exp $
+#      $NetBSD: files,v 1.1290 2021/11/19 23:46:54 rin Exp $
 #      @(#)files.newconf       7.5 (Berkeley) 5/10/93
 
 version        20171118
@@ -1036,6 +1036,7 @@
 
 # AHCI-compatible SATA controllers
 defflag        opt_ahcisata.h  AHCISATA_EXTRA_DELAY
+defparam opt_ahcisata.h        AHCISATA_EXTRA_DELAY_MS
 define ahcisata_core
 file dev/ic/ahcisata_core.c ahcisata_core
 device ahcisata: ata, ata_dma, ata_udma, sata, sata_fis, sata_pmp, ahcisata_core
diff -r 21cac150b9ae -r 5ec90965a167 sys/dev/ic/ahcisata_core.c
--- a/sys/dev/ic/ahcisata_core.c        Fri Nov 19 22:24:29 2021 +0000
+++ b/sys/dev/ic/ahcisata_core.c        Fri Nov 19 23:46:54 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ahcisata_core.c,v 1.104 2021/11/10 17:19:30 msaitoh Exp $      */
+/*     $NetBSD: ahcisata_core.c,v 1.105 2021/11/19 23:46:55 rin Exp $  */
 
 /*
  * Copyright (c) 2006 Manuel Bouyer.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.104 2021/11/10 17:19:30 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.105 2021/11/19 23:46:55 rin Exp $");
 
 #include <sys/types.h>
 #include <sys/malloc.h>
@@ -115,6 +115,21 @@
 #define ATA_RESET_DELAY 31000 /* 31s for a drive reset */
 #define AHCI_RST_WAIT (ATA_RESET_DELAY / 10)
 
+#ifndef AHCISATA_EXTRA_DELAY_MS
+#define        AHCISATA_EXTRA_DELAY_MS 500     /* XXX need to adjust */
+#endif
+
+#ifdef AHCISATA_EXTRA_DELAY
+#define        AHCISATA_DO_EXTRA_DELAY(sc, chp, msg, flags)                    \
+    ata_delay(chp, AHCISATA_EXTRA_DELAY_MS, msg, flags)
+#else
+#define        AHCISATA_DO_EXTRA_DELAY(sc, chp, msg, flags)                    \
+    do {                                                               \
+       if ((sc)->sc_ahci_quirks & AHCI_QUIRK_EXTRA_DELAY)              \
+               ata_delay(chp, AHCISATA_EXTRA_DELAY_MS, msg, flags);    \
+    } while (0)
+#endif
+
 const struct ata_bustype ahci_ata_bustype = {
        .bustype_type = SCSIPI_BUSTYPE_ATA,
        .ata_bio = ahci_ata_bio,
@@ -970,9 +985,7 @@
            AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel))), DEBUG_PROBE);
 end:
        ahci_channel_stop(sc, chp, flags);
-#ifdef AHCISATA_EXTRA_DELAY
-       ata_delay(chp, 500, "ahcirst", flags);
-#endif
+       AHCISATA_DO_EXTRA_DELAY(sc, chp, "ahcirst", flags);
        /* clear port interrupt register */
        AHCI_WRITE(sc, AHCI_P_IS(chp->ch_channel), 0xffffffff);
        ahci_channel_start(sc, chp, flags,
@@ -996,9 +1009,7 @@
                /* XXX and then ? */
        }
        ata_kill_active(chp, KILL_RESET, flags);
-#ifdef AHCISATA_EXTRA_DELAY
-       ata_delay(chp, 500, "ahcirst", flags);
-#endif
+       AHCISATA_DO_EXTRA_DELAY(sc, chp, "ahcirst", flags);
        /* clear port interrupt register */
        AHCI_WRITE(sc, AHCI_P_IS(chp->ch_channel), 0xffffffff);
        /* clear SErrors and start operations */
@@ -1068,9 +1079,7 @@
        switch (sata_reset_interface(chp, sc->sc_ahcit, achp->ahcic_scontrol,
            achp->ahcic_sstatus, AT_WAIT)) {
        case SStatus_DET_DEV:
-#ifdef AHCISATA_EXTRA_DELAY
-               ata_delay(chp, 500, "ahcidv", AT_WAIT);
-#endif
+               AHCISATA_DO_EXTRA_DELAY(sc, chp, "ahcidv", AT_WAIT);
 
                /* Initial value, used in case the soft reset fails */
                sig = AHCI_READ(sc, AHCI_P_SIG(chp->ch_channel));
@@ -1109,10 +1118,11 @@
                    AHCI_P_IX_IFS |
                    AHCI_P_IX_OFS | AHCI_P_IX_DPS | AHCI_P_IX_UFS |
                    AHCI_P_IX_PSS | AHCI_P_IX_DHRS | AHCI_P_IX_SDBS);
-#ifdef AHCISATA_EXTRA_DELAY
-               /* wait 500ms before actually starting operations */
-               ata_delay(chp, 500, "ahciprb", AT_WAIT);
-#endif
+               /*
+                * optionally, wait AHCISATA_EXTRA_DELAY_MS msec before
+                * actually starting operations
+                */
+               AHCISATA_DO_EXTRA_DELAY(sc, chp, "ahciprb", AT_WAIT);
                break;
 
        default:
diff -r 21cac150b9ae -r 5ec90965a167 sys/dev/ic/ahcisatavar.h
--- a/sys/dev/ic/ahcisatavar.h  Fri Nov 19 22:24:29 2021 +0000
+++ b/sys/dev/ic/ahcisatavar.h  Fri Nov 19 23:46:54 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ahcisatavar.h,v 1.26 2020/12/28 14:08:42 jmcneill Exp $        */
+/*     $NetBSD: ahcisatavar.h,v 1.27 2021/11/19 23:46:55 rin Exp $     */
 
 /*
  * Copyright (c) 2006 Manuel Bouyer.
@@ -59,6 +59,7 @@
 #define AHCI_PCI_QUIRK_BAD64   __BIT(1)  /* broken 64-bit DMA */
 #define AHCI_QUIRK_BADPMP      __BIT(2)  /* broken PMP support, ignore */
 #define AHCI_QUIRK_BADNCQ      __BIT(3)  /* possibly broken NCQ support, ignore */
+#define AHCI_QUIRK_EXTRA_DELAY __BIT(4)  /* needs extra delay */
 
        uint32_t sc_ahci_cap;   /* copy of AHCI_CAP */
        int sc_ncmds; /* number of command slots */
diff -r 21cac150b9ae -r 5ec90965a167 sys/dev/pci/ahcisata_pci.c
--- a/sys/dev/pci/ahcisata_pci.c        Fri Nov 19 22:24:29 2021 +0000
+++ b/sys/dev/pci/ahcisata_pci.c        Fri Nov 19 23:46:54 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ahcisata_pci.c,v 1.60 2021/11/12 07:06:06 skrll Exp $  */
+/*     $NetBSD: ahcisata_pci.c,v 1.61 2021/11/19 23:46:55 rin Exp $    */
 
 /*
  * Copyright (c) 2006 Manuel Bouyer.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ahcisata_pci.c,v 1.60 2021/11/12 07:06:06 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ahcisata_pci.c,v 1.61 2021/11/19 23:46:55 rin Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ahcisata_pci.h"
@@ -204,6 +204,25 @@
            AHCI_QUIRK_BADPMP },
        { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801JI_SATA_AHCI,
            AHCI_QUIRK_BADPMP },
+       { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_C600_AHCI,
+           AHCI_QUIRK_EXTRA_DELAY },
+#if 0
+       /*
+        * XXX Non-reproducible failures reported. May need extra-delay quirk.
+        */
+       { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_BAYTRAIL_SATA_AHCI_0,
+           AHCI_QUIRK_EXTRA_DELAY },
+       { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_BAYTRAIL_SATA_AHCI_1,
+           AHCI_QUIRK_EXTRA_DELAY },
+       { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801I_SATA_4,
+           AHCI_QUIRK_EXTRA_DELAY },
+       { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801I_SATA_5,
+           AHCI_QUIRK_EXTRA_DELAY },
+       { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801I_SATA_6,
+           AHCI_QUIRK_EXTRA_DELAY },
+       { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801I_SATA_7,
+           AHCI_QUIRK_EXTRA_DELAY },
+#endif
 };
 
 struct ahci_pci_softc {



Home | Main Index | Thread Index | Old Index