Module Name:    src
Committed By:   jakllsch
Date:           Wed Dec 30 00:24:38 UTC 2009

Modified Files:
        src/sys/dev/pci: auich.c

Log Message:
Ensure that the memory or i/o space we need is accessible at attach
and resume.

Rework register mapping code path, using 'goto', so duplicate code
is reduced.

I've tested this on nvidia and sis auich(4)-compatible controllers.
In addition this change is reported to fix PR/39652.


To generate a diff of this commit:
cvs rdiff -u -r1.132 -r1.133 src/sys/dev/pci/auich.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/auich.c
diff -u src/sys/dev/pci/auich.c:1.132 src/sys/dev/pci/auich.c:1.133
--- src/sys/dev/pci/auich.c:1.132	Thu Nov 26 15:17:08 2009
+++ src/sys/dev/pci/auich.c	Wed Dec 30 00:24:38 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: auich.c,v 1.132 2009/11/26 15:17:08 njoly Exp $	*/
+/*	$NetBSD: auich.c,v 1.133 2009/12/30 00:24:38 jakllsch Exp $	*/
 
 /*-
  * Copyright (c) 2000, 2004, 2005 The NetBSD Foundation, Inc.
@@ -111,7 +111,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: auich.c,v 1.132 2009/11/26 15:17:08 njoly Exp $");
+__KERNEL_RCSID(0, "$NetBSD: auich.c,v 1.133 2009/12/30 00:24:38 jakllsch Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -215,8 +215,11 @@
 	int  sc_sts_reg;
 	/* 440MX workaround */
 	int  sc_dmamap_flags;
-	/* Native mode? */
-	int  sc_native_mode;
+	/* flags */
+	int  sc_iose	:1,
+	     sc_csr_io	:1,
+	     sc_csr_mem	:1,
+		     	:29;
 
 	/* sysctl */
 	struct sysctllog *sc_log;
@@ -482,46 +485,55 @@
 	if (d->id == PCIID_ICH4 || d->id == PCIID_ICH5 || d->id == PCIID_ICH6
 	    || d->id == PCIID_ICH7 || d->id == PCIID_I6300ESB
 	    || d->id == PCIID_ICH4MODEM) {
-		sc->sc_native_mode = 1;
 		/*
 		 * Use native mode for Intel 6300ESB and ICH4/ICH5/ICH6/ICH7
 		 */
+
+		sc->sc_csr_mem = 1;
+		v = pci_conf_read(pa->pa_pc, pa->pa_tag,
+		    PCI_COMMAND_STATUS_REG);
+		pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
+			       v | PCI_COMMAND_MEM_ENABLE);
+		pa->pa_flags |= PCI_FLAGS_MEM_ENABLED;
+
 		if (pci_mapreg_map(pa, ICH_MMBAR, PCI_MAPREG_TYPE_MEM, 0,
-				   &sc->iot, &sc->mix_ioh, NULL, &sc->mix_size)) {
-			v = pci_conf_read(pa->pa_pc, pa->pa_tag, ICH_CFG);
-			pci_conf_write(pa->pa_pc, pa->pa_tag, ICH_CFG,
-				       v | ICH_CFG_IOSE);
-			if (pci_mapreg_map(pa, ICH_NAMBAR, PCI_MAPREG_TYPE_IO,
-					   0, &sc->iot, &sc->mix_ioh, NULL,
-					   &sc->mix_size)) {
-				aprint_error_dev(self, "can't map codec i/o space\n");
-				return;
-			}
+		    &sc->iot, &sc->mix_ioh, NULL, &sc->mix_size)) {
+			goto retry_map;
 		}
 		if (pci_mapreg_map(pa, ICH_MBBAR, PCI_MAPREG_TYPE_MEM, 0,
-				   &sc->iot, &sc->aud_ioh, NULL, &sc->aud_size)) {
-			v = pci_conf_read(pa->pa_pc, pa->pa_tag, ICH_CFG);
-			pci_conf_write(pa->pa_pc, pa->pa_tag, ICH_CFG,
-				       v | ICH_CFG_IOSE);
-			if (pci_mapreg_map(pa, ICH_NABMBAR, PCI_MAPREG_TYPE_IO,
-					   0, &sc->iot, &sc->aud_ioh, NULL,
-					   &sc->aud_size)) {
-				aprint_error_dev(self, "can't map device i/o space\n");
-				return;
-			}
-		}
-	} else {
-		if (pci_mapreg_map(pa, ICH_NAMBAR, PCI_MAPREG_TYPE_IO, 0,
-				   &sc->iot, &sc->mix_ioh, NULL, &sc->mix_size)) {
-			aprint_error_dev(self, "can't map codec i/o space\n");
-			return;
-		}
-		if (pci_mapreg_map(pa, ICH_NABMBAR, PCI_MAPREG_TYPE_IO, 0,
-				   &sc->iot, &sc->aud_ioh, NULL, &sc->aud_size)) {
-			aprint_error_dev(self, "can't map device i/o space\n");
-			return;
+		    &sc->iot, &sc->aud_ioh, NULL, &sc->aud_size)) {
+			goto retry_map;
 		}
+		goto map_done;
+	} else
+		goto non_native_map;
+
+retry_map:
+	sc->sc_iose = 1;
+	v = pci_conf_read(pa->pa_pc, pa->pa_tag, ICH_CFG);
+	pci_conf_write(pa->pa_pc, pa->pa_tag, ICH_CFG,
+		       v | ICH_CFG_IOSE);
+
+non_native_map:
+	sc->sc_csr_io = 1;
+	v = pci_conf_read(pa->pa_pc, pa->pa_tag,
+	    PCI_COMMAND_STATUS_REG);
+	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
+		       v | PCI_COMMAND_IO_ENABLE);
+	pa->pa_flags |= PCI_FLAGS_IO_ENABLED;
+
+	if (pci_mapreg_map(pa, ICH_NAMBAR, PCI_MAPREG_TYPE_IO, 0,
+			   &sc->iot, &sc->mix_ioh, NULL, &sc->mix_size)) {
+		aprint_error_dev(self, "can't map codec i/o space\n");
+		return;
 	}
+	if (pci_mapreg_map(pa, ICH_NABMBAR, PCI_MAPREG_TYPE_IO, 0,
+			   &sc->iot, &sc->aud_ioh, NULL, &sc->aud_size)) {
+		aprint_error_dev(self, "can't map device i/o space\n");
+		return;
+	}
+
+map_done:
 	sc->dmat = pa->pa_dmat;
 
 	/* enable bus mastering */
@@ -1578,12 +1590,19 @@
 	struct auich_softc *sc = device_private(dv);
 	pcireg_t v;
 
-	if (sc->sc_native_mode) {
+	if (sc->sc_iose) {
 		v = pci_conf_read(sc->sc_pc, sc->sc_pt, ICH_CFG);
 		pci_conf_write(sc->sc_pc, sc->sc_pt, ICH_CFG,
 			       v | ICH_CFG_IOSE);
 	}
 
+	v = pci_conf_read(sc->sc_pc, sc->sc_pt, PCI_COMMAND_STATUS_REG);
+	if (sc->sc_csr_io)
+		v |= PCI_COMMAND_IO_ENABLE;
+	if (sc->sc_csr_mem)
+		v |= PCI_COMMAND_MEM_ENABLE;
+	pci_conf_write(sc->sc_pc, sc->sc_pt, PCI_COMMAND_STATUS_REG, v);
+
 	auich_reset_codec(sc);
 	DELAY(1000);
 	(sc->codec_if->vtbl->restore_ports)(sc->codec_if);

Reply via email to