X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=lib%2Fecam.c;h=c72eae60df3279371530c42adf6ae8f5235e0562;hb=06f9ecf36e529695feea35038e15233dffe37bb7;hp=aa3b60aab386cbb6da51ed51b239c856f7441b61;hpb=2ba0f6f434abbad44888e9ad372d7b562570cd1f;p=pciutils.git diff --git a/lib/ecam.c b/lib/ecam.c index aa3b60a..c72eae6 100644 --- a/lib/ecam.c +++ b/lib/ecam.c @@ -3,7 +3,9 @@ * * Copyright (c) 2023 Pali Rohár * - * 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 {