Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/acpi Do not discard ACPI PCI addresses with function...



details:   https://anonhg.NetBSD.org/src/rev/caec1cea1c48
branches:  trunk
changeset: 757801:caec1cea1c48
user:      gsutre <gsutre%NetBSD.org@localhost>
date:      Fri Sep 24 07:48:59 2010 +0000

description:
Do not discard ACPI PCI addresses with function number 0xFFFF: the
ACPI specification allows them (ACPI 4.0a, p. 200).

ok jruoho@

diffstat:

 sys/dev/acpi/acpi_pci.c     |  40 +++++++++++++++++++++++++++-------------
 sys/dev/acpi/acpi_verbose.c |   7 +++++--
 sys/dev/acpi/acpivar.h      |  13 ++++++++++++-
 3 files changed, 44 insertions(+), 16 deletions(-)

diffs (146 lines):

diff -r 94306da0f9a2 -r caec1cea1c48 sys/dev/acpi/acpi_pci.c
--- a/sys/dev/acpi/acpi_pci.c   Thu Sep 23 21:34:14 2010 +0000
+++ b/sys/dev/acpi/acpi_pci.c   Fri Sep 24 07:48:59 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_pci.c,v 1.14 2010/08/09 09:36:42 gsutre Exp $ */
+/* $NetBSD: acpi_pci.c,v 1.15 2010/09/24 07:48:59 gsutre Exp $ */
 
 /*
  * Copyright (c) 2009, 2010 The NetBSD Foundation, Inc.
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_pci.c,v 1.14 2010/08/09 09:36:42 gsutre Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_pci.c,v 1.15 2010/09/24 07:48:59 gsutre Exp $");
 
 #include <sys/param.h>
 #include <sys/device.h>
@@ -113,9 +113,10 @@
        if (ACPI_FAILURE(rv))
                return rv;
 
-       if (bus < 0 || bus > 0xFFFF)
+       if (bus == -1)
                return AE_NOT_EXIST;
 
+       /* Here it holds that 0 <= bus <= 0xFFFF. */
        *busp = (uint16_t)bus;
 
        return rv;
@@ -142,7 +143,10 @@
        if (*bus != -1)
                return AE_ALREADY_EXISTS;
 
-       *bus = addr64.Minimum;
+       if (addr64.Minimum > 0xFFFF)
+               return AE_BAD_DATA;
+
+       *bus = (int32_t)addr64.Minimum;
 
        return AE_OK;
 }
@@ -211,7 +215,7 @@
                ap->ap_function = ACPI_LOLODWORD(ad->ad_devinfo->Address);
 
                if (ap->ap_bus > 255 || ap->ap_device > 31 ||
-                   ap->ap_function > 7) {
+                   (ap->ap_function > 7 && ap->ap_function != 0xFFFF)) {
                        aprint_error_dev(ad->ad_root,
                            "invalid PCI address for %s\n", ad->ad_name);
                        kmem_free(ap, sizeof(*ap));
@@ -246,21 +250,31 @@
                ap->ap_device = ACPI_HILODWORD(ad->ad_devinfo->Address);
                ap->ap_function = ACPI_LOLODWORD(ad->ad_devinfo->Address);
 
-               if (ap->ap_device > 31 || ap->ap_function > 7) {
+               if (ap->ap_device > 31 ||
+                   (ap->ap_function > 7 && ap->ap_function != 0xFFFF)) {
                        aprint_error_dev(ad->ad_root,
                            "invalid PCI address for %s\n", ad->ad_name);
                        kmem_free(ap, sizeof(*ap));
                        goto rec;
                }
 
-               /*
-                * Check whether this device is a PCI-to-PCI
-                * bridge and get its secondary bus number.
-                */
-               rv = acpi_pcidev_ppb_downbus(ap->ap_segment, ap->ap_bus,
-                   ap->ap_device, ap->ap_function, &ap->ap_downbus);
+               if (ap->ap_function == 0xFFFF) {
+                       /*
+                        * Assume that this device is not a PCI-to-PCI bridge.
+                        * XXX: Do we need to be smarter?
+                        */
+                       ap->ap_bridge = false;
+               } else {
+                       /*
+                        * Check whether this device is a PCI-to-PCI
+                        * bridge and get its secondary bus number.
+                        */
+                       rv = acpi_pcidev_ppb_downbus(ap->ap_segment, ap->ap_bus,
+                           ap->ap_device, ap->ap_function, &ap->ap_downbus);
 
-               ap->ap_bridge = (rv != AE_OK) ? false : true;
+                       ap->ap_bridge = (rv != AE_OK) ? false : true;
+               }
+
                ad->ad_pciinfo = ap;
 
                goto rec;
diff -r 94306da0f9a2 -r caec1cea1c48 sys/dev/acpi/acpi_verbose.c
--- a/sys/dev/acpi/acpi_verbose.c       Thu Sep 23 21:34:14 2010 +0000
+++ b/sys/dev/acpi/acpi_verbose.c       Fri Sep 24 07:48:59 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: acpi_verbose.c,v 1.10 2010/08/11 10:32:42 gsutre Exp $ */
+/*     $NetBSD: acpi_verbose.c,v 1.11 2010/09/24 07:48:59 gsutre Exp $ */
 
 /*-
  * Copyright (c) 2003, 2007, 2010 The NetBSD Foundation, Inc.
@@ -65,7 +65,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_verbose.c,v 1.10 2010/08/11 10:32:42 gsutre Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_verbose.c,v 1.11 2010/09/24 07:48:59 gsutre Exp $");
 
 #include <sys/param.h>
 #include <sys/device.h>
@@ -510,6 +510,9 @@
        struct pci_softc *pci;
        deviter_t di;
 
+       if (ap->ap_function == 0xFFFF)
+               return NULL;
+
        for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST); dv != NULL;
             dv = deviter_next(&di)) {
                pr = device_parent(dv);
diff -r 94306da0f9a2 -r caec1cea1c48 sys/dev/acpi/acpivar.h
--- a/sys/dev/acpi/acpivar.h    Thu Sep 23 21:34:14 2010 +0000
+++ b/sys/dev/acpi/acpivar.h    Fri Sep 24 07:48:59 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: acpivar.h,v 1.62 2010/09/06 15:54:27 jmcneill Exp $    */
+/*     $NetBSD: acpivar.h,v 1.63 2010/09/24 07:48:59 gsutre Exp $      */
 
 /*
  * Copyright 2001 Wasabi Systems, Inc.
@@ -66,6 +66,17 @@
 
 /*
  * PCI information for ACPI device nodes that correspond to PCI devices.
+ *
+ * Remarks:
+ *
+ *     ap_bus          <= 255
+ *     ap_device       <= 31
+ *     ap_function     <= 7            or      ap_function == 0xFFFF
+ *     ap_downbus      <= 255          if      ap_bridge == true
+ *
+ * The device and function numbers are encoded in the value returned by
+ * _ADR.  A function number of 0xFFFF is used to refer to all the
+ * functions on a PCI device (ACPI 4.0a, p. 200).
  */
 struct acpi_pci_info {
        uint16_t                 ap_segment;    /* PCI segment group */



Home | Main Index | Thread Index | Old Index