]> mj.ucw.cz Git - pciutils.git/blobdiff - lib/ecam.c
libpci: ecam: Fix big address range mappings
[pciutils.git] / lib / ecam.c
index aa3b60aab386cbb6da51ed51b239c856f7441b61..e2b941246d09224da5e64bbb1e4db19c05a58b17 100644 (file)
@@ -3,7 +3,9 @@
  *
  *      Copyright (c) 2023 Pali Rohár <pali@kernel.org>
  *
- *      Can be freely distributed and used under the terms of the GNU GPL.
+ *     Can be freely distributed and used under the terms of the GNU GPL v2+.
+ *
+ *     SPDX-License-Identifier: GPL-2.0-or-later
  */
 
 /*
@@ -616,6 +618,24 @@ validate_addrs(const char *addrs)
   return 1;
 }
 
+static int
+calculate_bus_addr(u8 start_bus, off_t start_addr, u32 total_length, u8 bus, off_t *addr, u32 *length)
+{
+  u32 offset;
+
+  offset = 32*8*4096 * (bus - start_bus);
+  if (offset >= total_length)
+    return 0;
+
+  *addr = start_addr + offset;
+  *length = total_length - offset;
+
+  if (*length > 32*8*4096)
+    *length = 32*8*4096;
+
+  return 1;
+}
+
 static int
 get_bus_addr(struct acpi_mcfg *mcfg, const char *addrs, int domain, u8 bus, off_t *addr, u32 *length)
 {
@@ -624,7 +644,6 @@ get_bus_addr(struct acpi_mcfg *mcfg, const char *addrs, int domain, u8 bus, off_
   u8 end_bus;
   off_t start_addr;
   u32 total_length;
-  u32 offset;
   int i, count;
 
   if (mcfg)
@@ -634,14 +653,7 @@ get_bus_addr(struct acpi_mcfg *mcfg, const char *addrs, int domain, u8 bus, off_
         {
           get_mcfg_allocation(mcfg, i, &cur_domain, &start_bus, &end_bus, &start_addr, &total_length);
           if (domain == cur_domain && bus >= start_bus && bus <= end_bus)
-            {
-              offset = 32*8*4096 * (bus - start_bus);
-              if (offset >= total_length)
-                return 0;
-              *addr = start_addr + offset;
-              *length = total_length - offset;
-              return 1;
-            }
+            return calculate_bus_addr(start_bus, start_addr, total_length, bus, addr, length);
         }
       return 0;
     }
@@ -652,14 +664,7 @@ get_bus_addr(struct acpi_mcfg *mcfg, const char *addrs, int domain, u8 bus, off_
           if (!parse_next_addrs(addrs, &addrs, &cur_domain, &start_bus, &end_bus, &start_addr, &total_length))
             return 0;
           if (domain == cur_domain && bus >= start_bus && bus <= end_bus)
-            {
-              offset = 32*8*4096 * (bus - start_bus);
-              if (offset >= total_length)
-                return 0;
-              *addr = start_addr + offset;
-              *length = total_length - offset;
-              return 1;
-            }
+            return calculate_bus_addr(start_bus, start_addr, total_length, bus, addr, length);
         }
       return 0;
     }