Module Name: src
Committed By: jakllsch
Date: Tue Jul 27 22:27:52 UTC 2010
Modified Files:
src/sys/dev/pci: ahcisata_pci.c
Log Message:
Use use 64-bit DMA tag (where available and supported) for ahcisata.
Avoid the possible ATI SB600 64-bit DMA problem.
To generate a diff of this commit:
cvs rdiff -u -r1.20 -r1.21 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/dev/pci/ahcisata_pci.c
diff -u src/sys/dev/pci/ahcisata_pci.c:1.20 src/sys/dev/pci/ahcisata_pci.c:1.21
--- src/sys/dev/pci/ahcisata_pci.c:1.20 Tue Jul 27 22:07:51 2010
+++ src/sys/dev/pci/ahcisata_pci.c Tue Jul 27 22:27:52 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: ahcisata_pci.c,v 1.20 2010/07/27 22:07:51 jakllsch Exp $ */
+/* $NetBSD: ahcisata_pci.c,v 1.21 2010/07/27 22:27:52 jakllsch Exp $ */
/*
* Copyright (c) 2006 Manuel Bouyer.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ahcisata_pci.c,v 1.20 2010/07/27 22:07:51 jakllsch Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ahcisata_pci.c,v 1.21 2010/07/27 22:27:52 jakllsch Exp $");
#include <sys/types.h>
#include <sys/malloc.h>
@@ -51,6 +51,7 @@
};
#define AHCI_PCI_QUIRK_FORCE __BIT(0) /* force attach */
+#define AHCI_PCI_QUIRK_BAD64 __BIT(1) /* broken 64-bit DMA */
static const struct ahci_pci_quirk ahci_pci_quirks[] = {
{ PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP65_SATA,
@@ -67,6 +68,9 @@
AHCI_PCI_QUIRK_FORCE },
{ PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_88SE6121,
AHCI_PCI_QUIRK_FORCE },
+ /* ATI SB600 AHCI 64-bit DMA only works on some boards/BIOSes */
+ { PCI_VENDOR_ATI, PCI_PRODUCT_ATI_SB600_SATA_1,
+ AHCI_PCI_QUIRK_BAD64 },
};
struct ahci_pci_softc {
@@ -143,6 +147,8 @@
struct ahci_softc *sc = &psc->ah_sc;
char devinfo[256];
const char *intrstr;
+ bool ahci_cap_64bit;
+ bool ahci_bad_64bit;
pci_intr_handle_t intrhandle;
sc->sc_atac.atac_dev = self;
@@ -172,8 +178,21 @@
}
aprint_normal_dev(self, "interrupting at %s\n",
intrstr ? intrstr : "unknown interrupt");
+
sc->sc_dmat = pa->pa_dmat;
+ ahci_cap_64bit = (AHCI_READ(sc, AHCI_CAP) & AHCI_CAP_64BIT) != 0;
+ ahci_bad_64bit = ahci_pci_has_quirk(PCI_VENDOR(pa->pa_id),
+ PCI_PRODUCT(pa->pa_id),
+ AHCI_PCI_QUIRK_BAD64);
+
+ if (pci_dma64_available(pa) && ahci_cap_64bit) {
+ if (!ahci_bad_64bit)
+ sc->sc_dmat = pa->pa_dmat64;
+ aprint_verbose_dev(self, "64-bit DMA%s\n",
+ (sc->sc_dmat == pa->pa_dmat) ? " unavailable" : "");
+ }
+
if (PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_MASS_STORAGE_RAID) {
AHCIDEBUG_PRINT(("%s: RAID mode\n", AHCINAME(sc)), DEBUG_PROBE);
sc->sc_atac_capflags = ATAC_CAP_RAID;