freebsd_network: use proper BAR size in bus_alloc_mem_resource
This time we use the pci_info directly, it avoids a possible race with PCI config regs, and we already have the value there anyway. Signed-off-by: Augustin Cavalier <waddlesplash@gmail.com> One crucial fix by me: check if size == 0. This avoids the deadlock seen in #14795.
This commit is contained in:
parent
a29a8f98ed
commit
b98f12a601
@ -112,14 +112,31 @@ bus_alloc_irq_resource(device_t dev, struct resource *res)
|
||||
static int
|
||||
bus_alloc_mem_resource(device_t dev, struct resource *res, int regid)
|
||||
{
|
||||
/* TODO: check the offset really is of a BAR */
|
||||
uint32 bar = pci_read_config(dev, regid, 4);
|
||||
uint32 addr = bar & PCI_address_memory_32_mask;
|
||||
pci_write_config(dev, regid, ~0, 4);
|
||||
uint32 size = pci_read_config(dev, regid, 4) & PCI_address_memory_32_mask;
|
||||
//size = (~size) + 1;
|
||||
size = 1024 * 128; /* XXX */
|
||||
pci_write_config(dev, regid, bar, 4);
|
||||
pci_info *info = &((struct root_device_softc *)dev->root->softc)->pci_info;
|
||||
|
||||
// check the offset really is of a BAR
|
||||
if (regid < PCI_base_registers || (regid % sizeof(uint32) != 0)
|
||||
|| (regid >= PCI_base_registers + 6 * (int)sizeof(uint32)))
|
||||
return -1;
|
||||
|
||||
// turn offset into array index
|
||||
regid -= PCI_base_registers;
|
||||
regid /= sizeof(uint32);
|
||||
|
||||
uint32 addr = info->u.h0.base_registers[regid];
|
||||
uint32 size = info->u.h0.base_register_sizes[regid];
|
||||
uchar flags = info->u.h0.base_register_flags[regid];
|
||||
|
||||
// reject empty regions
|
||||
if (size == 0)
|
||||
return -1;
|
||||
|
||||
// reject I/O space
|
||||
if (flags & PCI_address_space)
|
||||
return -1;
|
||||
|
||||
// TODO: check flags & PCI_address_prefetchable ?
|
||||
|
||||
void *virtualAddr;
|
||||
|
||||
res->r_mapped_area = map_mem(&virtualAddr, addr, size, 0,
|
||||
|
Loading…
Reference in New Issue
Block a user