Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci Ensure that the memory or i/o space we need is a...



details:   https://anonhg.NetBSD.org/src/rev/a03b7761820a
branches:  trunk
changeset: 750400:a03b7761820a
user:      jakllsch <jakllsch%NetBSD.org@localhost>
date:      Wed Dec 30 00:24:38 2009 +0000

description:
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.

diffstat:

 sys/dev/pci/auich.c |  93 +++++++++++++++++++++++++++++++---------------------
 1 files changed, 56 insertions(+), 37 deletions(-)

diffs (141 lines):

diff -r f054e62d80e4 -r a03b7761820a sys/dev/pci/auich.c
--- a/sys/dev/pci/auich.c       Wed Dec 30 00:08:01 2009 +0000
+++ b/sys/dev/pci/auich.c       Wed Dec 30 00:24:38 2009 +0000
@@ -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;
-                       }
+                   &sc->iot, &sc->aud_ioh, NULL, &sc->aud_size)) {
+                       goto retry_map;
                }
-       } 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;
-               }
+               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);



Home | Main Index | Thread Index | Old Index