Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 12 Oct 2011 14:13:32 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r226302 - head/sys/dev/acpica
Message-ID:  <201110121413.p9CEDWks069400@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Wed Oct 12 14:13:32 2011
New Revision: 226302
URL: http://svn.freebsd.org/changeset/base/226302

Log:
  If an allocation for a specific resource range fails because it is not in
  a decoded range for an ACPI Host-PCI bridge, try to allocate it from the
  ACPI system resource range.  If that works, permit the resource allocation
  regardless.
  
  MFC after:	1 week

Modified:
  head/sys/dev/acpica/acpi.c
  head/sys/dev/acpica/acpi_pcib_acpi.c
  head/sys/dev/acpica/acpivar.h

Modified: head/sys/dev/acpica/acpi.c
==============================================================================
--- head/sys/dev/acpica/acpi.c	Wed Oct 12 12:08:03 2011	(r226301)
+++ head/sys/dev/acpica/acpi.c	Wed Oct 12 14:13:32 2011	(r226302)
@@ -1238,7 +1238,6 @@ acpi_alloc_resource(device_t bus, device
     struct resource_list_entry *rle;
     struct resource_list *rl;
     struct resource *res;
-    struct rman *rm;
     int isdefault = (start == 0UL && end == ~0UL);
 
     /*
@@ -1291,15 +1290,29 @@ acpi_alloc_resource(device_t bus, device
     } else
 	res = BUS_ALLOC_RESOURCE(device_get_parent(bus), child, type, rid,
 	    start, end, count, flags);
-    if (res != NULL || start + count - 1 != end)
-	return (res);
 
     /*
      * If the first attempt failed and this is an allocation of a
      * specific range, try to satisfy the request via a suballocation
-     * from our system resource regions.  Note that we only handle
-     * memory and I/O port system resources.
+     * from our system resource regions.
      */
+    if (res == NULL && start + count - 1 == end)
+	res = acpi_alloc_sysres(child, type, rid, start, end, count, flags);
+    return (res);
+}
+
+/*
+ * Attempt to allocate a specific resource range from the system
+ * resource ranges.  Note that we only handle memory and I/O port
+ * system resources.
+ */
+struct resource *
+acpi_alloc_sysres(device_t child, int type, int *rid, u_long start, u_long end,
+    u_long count, u_int flags)
+{
+    struct rman *rm;
+    struct resource *res;
+
     switch (type) {
     case SYS_RES_IOPORT:
 	rm = &acpi_rman_io;
@@ -1311,6 +1324,7 @@ acpi_alloc_resource(device_t bus, device
 	return (NULL);
     }
 
+    KASSERT(start + count - 1 == end, ("wildcard resource range"));
     res = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE,
 	child);
     if (res == NULL)

Modified: head/sys/dev/acpica/acpi_pcib_acpi.c
==============================================================================
--- head/sys/dev/acpica/acpi_pcib_acpi.c	Wed Oct 12 12:08:03 2011	(r226301)
+++ head/sys/dev/acpica/acpi_pcib_acpi.c	Wed Oct 12 14:13:32 2011	(r226302)
@@ -501,6 +501,7 @@ acpi_pcib_acpi_alloc_resource(device_t d
 {
 #ifdef NEW_PCIB
     struct acpi_hpcib_softc *sc;
+    struct resource *res;
 #endif
 
 #if defined(__i386__) || defined(__amd64__)
@@ -509,8 +510,11 @@ acpi_pcib_acpi_alloc_resource(device_t d
 
 #ifdef NEW_PCIB
     sc = device_get_softc(dev);
-    return (pcib_host_res_alloc(&sc->ap_host_res, child, type, rid, start, end,
-	count, flags));
+    res = pcib_host_res_alloc(&sc->ap_host_res, child, type, rid, start, end,
+	count, flags);
+    if (res == NULL && start + count - 1 == end)
+	res = acpi_alloc_sysres(child, type, rid, start, end, count, flags);
+    return (res);
 #else
     return (bus_generic_alloc_resource(dev, child, type, rid, start, end,
 	count, flags));

Modified: head/sys/dev/acpica/acpivar.h
==============================================================================
--- head/sys/dev/acpica/acpivar.h	Wed Oct 12 12:08:03 2011	(r226301)
+++ head/sys/dev/acpica/acpivar.h	Wed Oct 12 14:13:32 2011	(r226302)
@@ -382,6 +382,8 @@ ACPI_STATUS	acpi_lookup_irq_resource(dev
 		    struct resource *res, ACPI_RESOURCE *acpi_res);
 ACPI_STATUS	acpi_parse_resources(device_t dev, ACPI_HANDLE handle,
 		    struct acpi_parse_resource_set *set, void *arg);
+struct resource *acpi_alloc_sysres(device_t child, int type, int *rid,
+		    u_long start, u_long end, u_long count, u_int flags);
 
 /* ACPI event handling */
 UINT32		acpi_event_power_button_sleep(void *context);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201110121413.p9CEDWks069400>