Source-Changes-HG archive

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

[src/trunk]: src/sys Fix a bug that ichlpcib(4) maps I/O area incorrectly and...



details:   https://anonhg.NetBSD.org/src/rev/63fad496bd83
branches:  trunk
changeset: 335104:63fad496bd83
user:      msaitoh <msaitoh%NetBSD.org@localhost>
date:      Fri Dec 26 05:09:03 2014 +0000

description:
Fix a bug that ichlpcib(4) maps I/O area incorrectly and then fails to attach
gpio. It might also fix ACPI related problem described in PR#48960:
 - The LPCIB_PCI_PMBASE and LPCIB_PCI_GPIO register are alike PCI BAR but not
   completely compatible with it. It's ok because the registers' addresses are
   out of BAR0-BAR5(0x10-0x24) and are located in the device-dependent header.
   The PMBASE and GPIO registers define the base address and the type but not
   describe the size. The size is fixed to 128bytes. So use
   pci_mapreg_submap().
 - Make pci_mapreg_submap() extern again.
 - Fix the calculation of the map size in pci_mapreg_submap().

diffstat:

 sys/arch/x86/pci/ichlpcib.c |  29 ++++++++++++++++++++---------
 sys/dev/ic/i82801lpcreg.h   |   4 +++-
 sys/dev/pci/pci_map.c       |  14 +++++---------
 sys/dev/pci/pcivar.h        |   6 +++++-
 4 files changed, 33 insertions(+), 20 deletions(-)

diffs (161 lines):

diff -r 0ec6984a5077 -r 63fad496bd83 sys/arch/x86/pci/ichlpcib.c
--- a/sys/arch/x86/pci/ichlpcib.c       Fri Dec 26 03:49:00 2014 +0000
+++ b/sys/arch/x86/pci/ichlpcib.c       Fri Dec 26 05:09:03 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ichlpcib.c,v 1.44 2014/12/15 13:29:42 msaitoh Exp $    */
+/*     $NetBSD: ichlpcib.c,v 1.45 2014/12/26 05:09:03 msaitoh Exp $    */
 
 /*-
  * Copyright (c) 2004 The NetBSD Foundation, Inc.
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ichlpcib.c,v 1.44 2014/12/15 13:29:42 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ichlpcib.c,v 1.45 2014/12/26 05:09:03 msaitoh Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -321,9 +321,14 @@
         * Part of our I/O registers are used as ACPI PM regs.
         * Since our ACPI subsystem accesses the I/O space directly so far,
         * we do not have to bother bus_space I/O map confliction.
+        *
+        * The PMBASE register is alike PCI BAR but not completely compatible
+        * with it. The PMBASE define the base address and the type but
+        * not describe the size.
         */
-       if (pci_mapreg_map(pa, LPCIB_PCI_PMBASE, PCI_MAPREG_TYPE_IO, 0,
-                          &sc->sc_iot, &sc->sc_ioh, NULL, &sc->sc_iosize)) {
+       if (pci_mapreg_submap(pa, LPCIB_PCI_PMBASE, PCI_MAPREG_TYPE_IO, 0,
+               LPCIB_PCI_PM_SIZE, 0, &sc->sc_iot, &sc->sc_ioh, NULL,
+               &sc->sc_iosize)) {
                aprint_error_dev(self, "can't map power management i/o space\n");
                return;
        }
@@ -1057,6 +1062,7 @@
        pcireg_t gpio_cntl;
        uint32_t use, io, bit;
        int pin, shift, base_reg, cntl_reg, reg;
+       int rv;
 
        /* this implies ICH >= 6, and thus different mapreg */
        if (sc->sc_has_rcba) {
@@ -1073,11 +1079,16 @@
        /* Is GPIO enabled? */
        if ((gpio_cntl & LPCIB_PCI_GPIO_CNTL_EN) == 0)
                return;
-               
-       if (pci_mapreg_map(&sc->sc_pa, base_reg, PCI_MAPREG_TYPE_IO, 0,
-                          &sc->sc_gpio_iot, &sc->sc_gpio_ioh,
-                          NULL, &sc->sc_gpio_ios)) {
-               aprint_error_dev(self, "can't map general purpose i/o space\n");
+       /*
+        * The GPIO_BASE register is alike PCI BAR but not completely
+        * compatible with it. The PMBASE define the base address and the type
+        * but not describe the size.
+        */
+       rv = pci_mapreg_submap(&sc->sc_pa, base_reg, PCI_MAPREG_TYPE_IO, 0,
+           LPCIB_PCI_GPIO_SIZE, 0, &sc->sc_gpio_iot, &sc->sc_gpio_ioh,
+           NULL, &sc->sc_gpio_ios);
+       if (rv != 0) {
+               aprint_error_dev(self, "can't map general purpose i/o space(rv = %d)\n", rv);
                return;
        }
 
diff -r 0ec6984a5077 -r 63fad496bd83 sys/dev/ic/i82801lpcreg.h
--- a/sys/dev/ic/i82801lpcreg.h Fri Dec 26 03:49:00 2014 +0000
+++ b/sys/dev/ic/i82801lpcreg.h Fri Dec 26 05:09:03 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: i82801lpcreg.h,v 1.11 2010/07/23 02:23:58 jakllsch Exp $       */
+/*     $NetBSD: i82801lpcreg.h,v 1.12 2014/12/26 05:09:03 msaitoh Exp $        */
 
 /*-
  * Copyright (c) 2004 The NetBSD Foundation, Inc.
@@ -40,6 +40,7 @@
  * PCI configuration registers
  */
 #define LPCIB_PCI_PMBASE       0x40
+#define LPCIB_PCI_PM_SIZE      0x00000080
 #define LPCIB_PCI_ACPI_CNTL    0x44
 # define LPCIB_PCI_ACPI_CNTL_EN        (1 << 4)
 /* GPIO config registers ICH6+ */
@@ -51,6 +52,7 @@
 #define LPCIB_PCI_TCO_CNTL     0x54
 /* GPIO config registers ICH0-ICH5 */
 #define LPCIB_PCI_GPIO_BASE    0x58
+#define LPCIB_PCI_GPIO_SIZE    0x00000080
 #define LPCIB_PCI_GPIO_CNTL    0x5c
 #define LPCIB_PCI_GPIO_CNTL_EN (1 << 4)
 #define LPCIB_PCI_PIRQA_ROUT   0x60
diff -r 0ec6984a5077 -r 63fad496bd83 sys/dev/pci/pci_map.c
--- a/sys/dev/pci/pci_map.c     Fri Dec 26 03:49:00 2014 +0000
+++ b/sys/dev/pci/pci_map.c     Fri Dec 26 05:09:03 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pci_map.c,v 1.31 2014/10/16 12:31:23 riastradh Exp $   */
+/*     $NetBSD: pci_map.c,v 1.32 2014/12/26 05:09:03 msaitoh Exp $     */
 
 /*-
  * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pci_map.c,v 1.31 2014/10/16 12:31:23 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pci_map.c,v 1.32 2014/12/26 05:09:03 msaitoh Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -43,10 +43,6 @@
 #include <dev/pci/pcireg.h>
 #include <dev/pci/pcivar.h>
 
-static int pci_mapreg_submap(const struct pci_attach_args *, int, pcireg_t, int,
-    bus_size_t, bus_size_t, bus_space_tag_t *, bus_space_handle_t *, 
-    bus_addr_t *, bus_size_t *);
-
 static int
 pci_io_find(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t type,
     bus_addr_t *basep, bus_size_t *sizep, int *flagsp)
@@ -282,7 +278,7 @@
            handlep, basep, sizep);
 }
 
-static int
+int
 pci_mapreg_submap(const struct pci_attach_args *pa, int reg, pcireg_t type,
     int busflags, bus_size_t maxsize, bus_size_t offset, bus_space_tag_t *tagp,
        bus_space_handle_t *handlep, bus_addr_t *basep, bus_size_t *sizep)
@@ -324,10 +320,10 @@
         * pci_mapreg_map.
         */
 
-       maxsize = (maxsize && offset) ? maxsize : size;
+       maxsize = (maxsize != 0) ? maxsize : size;
        base += offset;
 
-       if ((maxsize < size && offset + maxsize <= size) || offset != 0)
+       if ((size < maxsize) || (size < (offset + maxsize)))
                return 1;
 
        if (bus_space_map(tag, base, maxsize, busflags | flags, &handle))
diff -r 0ec6984a5077 -r 63fad496bd83 sys/dev/pci/pcivar.h
--- a/sys/dev/pci/pcivar.h      Fri Dec 26 03:49:00 2014 +0000
+++ b/sys/dev/pci/pcivar.h      Fri Dec 26 05:09:03 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pcivar.h,v 1.100 2014/10/16 12:31:23 riastradh Exp $   */
+/*     $NetBSD: pcivar.h,v 1.101 2014/12/26 05:09:03 msaitoh Exp $     */
 
 /*
  * Copyright (c) 1996, 1997 Christopher G. Demetriou.  All rights reserved.
@@ -269,6 +269,10 @@
 int    pci_mapreg_map(const struct pci_attach_args *, int, pcireg_t, int,
            bus_space_tag_t *, bus_space_handle_t *, bus_addr_t *,
            bus_size_t *);
+int    pci_mapreg_submap(const struct pci_attach_args *, int, pcireg_t, int,
+           bus_size_t, bus_size_t, bus_space_tag_t *, bus_space_handle_t *, 
+           bus_addr_t *, bus_size_t *);
+
 
 int pci_find_rom(const struct pci_attach_args *, bus_space_tag_t,
            bus_space_handle_t, bus_size_t,



Home | Main Index | Thread Index | Old Index