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;