Skip to content

Instantly share code, notes, and snippets.

@rokuyama
Created November 8, 2021 11:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rokuyama/7535594fc42a7867e3890702aee34c5c to your computer and use it in GitHub Desktop.
Save rokuyama/7535594fc42a7867e3890702aee34c5c to your computer and use it in GitHub Desktop.
Index: conf/files
===================================================================
RCS file: /cvsroot/src/sys/conf/files,v
retrieving revision 1.1289
diff -p -u -r1.1289 files
--- conf/files 11 Oct 2021 13:42:33 -0000 1.1289
+++ conf/files 8 Nov 2021 11:03:16 -0000
@@ -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: dev/ic/ahcisata_core.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/ahcisata_core.c,v
retrieving revision 1.103
diff -p -u -r1.103 ahcisata_core.c
--- dev/ic/ahcisata_core.c 11 Oct 2021 12:48:10 -0000 1.103
+++ dev/ic/ahcisata_core.c 8 Nov 2021 11:03:16 -0000
@@ -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: dev/ic/ahcisatavar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/ahcisatavar.h,v
retrieving revision 1.26
diff -p -u -r1.26 ahcisatavar.h
--- dev/ic/ahcisatavar.h 28 Dec 2020 14:08:42 -0000 1.26
+++ dev/ic/ahcisatavar.h 8 Nov 2021 11:03:16 -0000
@@ -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: dev/pci/ahcisata_pci.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/ahcisata_pci.c,v
retrieving revision 1.59
diff -p -u -r1.59 ahcisata_pci.c
--- dev/pci/ahcisata_pci.c 8 Nov 2021 11:01:51 -0000 1.59
+++ dev/pci/ahcisata_pci.c 8 Nov 2021 11:03:16 -0000
@@ -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 {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment