*
* 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
*/
/*
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)
{
u8 end_bus;
off_t start_addr;
u32 total_length;
- u32 offset;
int i, count;
if (mcfg)
{
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;
}
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;
}
int w;
};
-struct ecam_aux
+// Back-end data linked to struct pci_access
+struct ecam_access
{
struct acpi_mcfg *mcfg;
struct mmap_cache *cache;
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;
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));
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;
#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;
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);
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;
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;
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
{