]> mj.ucw.cz Git - pciutils.git/blobdiff - lib/ecam.c
Names: Fixed a rare bug in loading of pci.ids
[pciutils.git] / lib / ecam.c
index aa3b60aab386cbb6da51ed51b239c856f7441b61..c72eae60df3279371530c42adf6ae8f5235e0562 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;
     }
@@ -675,7 +680,8 @@ struct mmap_cache
   int w;
 };
 
-struct ecam_aux
+// Back-end data linked to struct pci_access
+struct ecam_access
 {
   struct acpi_mcfg *mcfg;
   struct mmap_cache *cache;
@@ -684,22 +690,22 @@ struct ecam_aux
 static void
 munmap_reg(struct pci_access *a)
 {
-  struct ecam_aux *aux = a->aux;
-  struct mmap_cache *cache = aux->cache;
+  struct ecam_access *eacc = a->backend_data;
+  struct mmap_cache *cache = eacc->cache;
 
   if (!cache)
     return;
 
   munmap(cache->map, cache->length + (cache->addr & (pagesize-1)));
   pci_mfree(cache);
-  aux->cache = NULL;
+  eacc->cache = NULL;
 }
 
 static int
 mmap_reg(struct pci_access *a, int w, int domain, u8 bus, u8 dev, u8 func, int pos, volatile void **reg)
 {
-  struct ecam_aux *aux = a->aux;
-  struct mmap_cache *cache = aux->cache;
+  struct ecam_access *eacc = a->backend_data;
+  struct mmap_cache *cache = eacc->cache;
   const char *addrs;
   void *map;
   off_t addr;
@@ -715,7 +721,7 @@ mmap_reg(struct pci_access *a, int w, int domain, u8 bus, u8 dev, u8 func, int p
   else
     {
       addrs = pci_get_param(a, "ecam.addrs");
-      if (!get_bus_addr(aux->mcfg, addrs, domain, bus, &addr, &length))
+      if (!get_bus_addr(eacc->mcfg, addrs, domain, bus, &addr, &length))
         return 0;
 
       map = mmap(NULL, length + (addr & (pagesize-1)), w ? PROT_WRITE : PROT_READ, MAP_SHARED, a->fd, addr & ~(pagesize-1));
@@ -725,7 +731,7 @@ mmap_reg(struct pci_access *a, int w, int domain, u8 bus, u8 dev, u8 func, int p
       if (cache)
         munmap(cache->map, cache->length + (cache->addr & (pagesize-1)));
       else
-        cache = aux->cache = pci_malloc(a, sizeof(*cache));
+        cache = eacc->cache = pci_malloc(a, sizeof(*cache));
 
       cache->map = map;
       cache->addr = addr;
@@ -910,7 +916,7 @@ ecam_init(struct pci_access *a)
 #endif
   const char *addrs = pci_get_param(a, "ecam.addrs");
   struct acpi_mcfg *mcfg = NULL;
-  struct ecam_aux *aux = NULL;
+  struct ecam_access *eacc = NULL;
   int use_bsd = 0;
   int use_x86bios = 0;
   int test_domain = 0;
@@ -943,10 +949,10 @@ ecam_init(struct pci_access *a)
         a->error("Option ecam.addrs was not specified and ACPI MCFG table cannot be found.");
     }
 
-  aux = pci_malloc(a, sizeof(*aux));
-  aux->mcfg = mcfg;
-  aux->cache = NULL;
-  a->aux = aux;
+  eacc = pci_malloc(a, sizeof(*eacc));
+  eacc->mcfg = mcfg;
+  eacc->cache = NULL;
+  a->backend_data = eacc;
 
   if (mcfg)
     get_mcfg_allocation(mcfg, 0, &test_domain, &test_bus, NULL, NULL, NULL);
@@ -961,14 +967,15 @@ ecam_init(struct pci_access *a)
 static void
 ecam_cleanup(struct pci_access *a)
 {
-  struct ecam_aux *aux = a->aux;
+  struct ecam_access *eacc = a->backend_data;
 
   if (a->fd < 0)
     return;
 
   munmap_reg(a);
-  pci_mfree(aux->mcfg);
-  pci_mfree(aux);
+  pci_mfree(eacc->mcfg);
+  pci_mfree(eacc);
+  a->backend_data = NULL;
 
   close(a->fd);
   a->fd = -1;
@@ -978,7 +985,7 @@ static void
 ecam_scan(struct pci_access *a)
 {
   const char *addrs = pci_get_param(a, "ecam.addrs");
-  struct ecam_aux *aux = a->aux;
+  struct ecam_access *eacc = a->backend_data;
   u32 *segments;
   int i, j, count;
   int domain;
@@ -986,11 +993,11 @@ ecam_scan(struct pci_access *a)
   segments = pci_malloc(a, 0xFFFF/8);
   memset(segments, 0, 0xFFFF/8);
 
-  if (aux->mcfg)
+  if (eacc->mcfg)
     {
-      count = get_mcfg_allocations_count(aux->mcfg);
+      count = get_mcfg_allocations_count(eacc->mcfg);
       for (i = 0; i < count; i++)
-        segments[aux->mcfg->allocations[i].pci_segment / 32] |= 1 << (aux->mcfg->allocations[i].pci_segment % 32);
+        segments[eacc->mcfg->allocations[i].pci_segment / 32] |= 1 << (eacc->mcfg->allocations[i].pci_segment % 32);
     }
   else
     {