diff options
author | jhb <jhb@FreeBSD.org> | 2008-08-15 20:17:08 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2008-08-15 20:17:08 +0000 |
commit | 783727042f78886c22e3bd88aa740287b5842e43 (patch) | |
tree | a6a8dd0ada0ef5107b0f5973fe37a23a18c926b1 /sys/dev | |
parent | c44491b181b0cc6cc5f3cd9990c9d7f9aea7dcf0 (diff) | |
download | FreeBSD-src-783727042f78886c22e3bd88aa740287b5842e43.zip FreeBSD-src-783727042f78886c22e3bd88aa740287b5842e43.tar.gz |
MFC: If the kernel fails to allocate resources for the initial value of a
PCI BAR, then zero the BAR and clear the resource list entry so that a
new resource will be allocated by the device driver.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pci/pci.c | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index 0b23594..40dae33 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -1749,7 +1749,7 @@ pci_add_map(device_t pcib, device_t bus, device_t dev, count = 1 << ln2size; if (base == 0 || base == pci_mapbase(testval)) { - start = 0; /* Let the parent deside */ + start = 0; /* Let the parent decide. */ end = ~0ULL; } else { start = base; @@ -1758,13 +1758,27 @@ pci_add_map(device_t pcib, device_t bus, device_t dev, resource_list_add(rl, type, reg, start, end, count); /* - * Not quite sure what to do on failure of allocating the resource - * since I can postulate several right answers. + * Try to allocate the resource for this BAR from our parent + * so that this resource range is already reserved. The + * driver for this device will later inherit this resource in + * pci_alloc_resource(). */ res = resource_list_alloc(rl, bus, dev, type, ®, start, end, count, prefetch ? RF_PREFETCHABLE : 0); - if (res != NULL) - pci_write_config(dev, reg, rman_get_start(res), 4); + if (res == NULL) { + /* + * If the allocation fails, clear the BAR and delete + * the resource list entry to force + * pci_alloc_resource() to allocate resources from the + * parent. + */ + resource_list_delete(rl, type, reg); + start = 0; + } else + start = rman_get_start(res); + pci_write_config(dev, reg, start, 4); + if (ln2range == 64) + pci_write_config(dev, reg + 4, start >> 32, 4); return (barlen); } |