Module Name: src Committed By: rin Date: Fri Nov 19 23:46:55 UTC 2021
Modified Files: src/sys/conf: files src/sys/dev/ic: ahcisata_core.c ahcisatavar.h src/sys/dev/pci: ahcisata_pci.c Log Message: 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! To generate a diff of this commit: cvs rdiff -u -r1.1289 -r1.1290 src/sys/conf/files cvs rdiff -u -r1.104 -r1.105 src/sys/dev/ic/ahcisata_core.c cvs rdiff -u -r1.26 -r1.27 src/sys/dev/ic/ahcisatavar.h cvs rdiff -u -r1.60 -r1.61 src/sys/dev/pci/ahcisata_pci.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/conf/files diff -u src/sys/conf/files:1.1289 src/sys/conf/files:1.1290 --- src/sys/conf/files:1.1289 Mon Oct 11 13:42:33 2021 +++ src/sys/conf/files Fri Nov 19 23:46:54 2021 @@ -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 @@ file dev/ic/ninjaata32.c njata # 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 Index: src/sys/dev/ic/ahcisata_core.c diff -u src/sys/dev/ic/ahcisata_core.c:1.104 src/sys/dev/ic/ahcisata_core.c:1.105 --- src/sys/dev/ic/ahcisata_core.c:1.104 Wed Nov 10 17:19:30 2021 +++ src/sys/dev/ic/ahcisata_core.c Fri Nov 19 23:46:55 2021 @@ -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 @@ static const struct scsipi_bustype ahci_ #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 @@ again: 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 @@ ahci_reset_channel(struct ata_channel *c /* 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 @@ ahci_probe_drive(struct ata_channel *chp 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_probe_drive(struct ata_channel *chp 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: Index: src/sys/dev/ic/ahcisatavar.h diff -u src/sys/dev/ic/ahcisatavar.h:1.26 src/sys/dev/ic/ahcisatavar.h:1.27 --- src/sys/dev/ic/ahcisatavar.h:1.26 Mon Dec 28 14:08:42 2020 +++ src/sys/dev/ic/ahcisatavar.h Fri Nov 19 23:46:55 2021 @@ -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 @@ struct ahci_softc { #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 */ Index: src/sys/dev/pci/ahcisata_pci.c diff -u src/sys/dev/pci/ahcisata_pci.c:1.60 src/sys/dev/pci/ahcisata_pci.c:1.61 --- src/sys/dev/pci/ahcisata_pci.c:1.60 Fri Nov 12 07:06:06 2021 +++ src/sys/dev/pci/ahcisata_pci.c Fri Nov 19 23:46:55 2021 @@ -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 @@ static const struct ahci_pci_quirk ahci_ 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 {