aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/pci/pci_private.h
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2009-03-03 16:38:59 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2009-03-03 16:38:59 +0000
commit6b0ff427a57b12372e9b7181e92e50b17c773ca9 (patch)
treec8adf2857947d5880db3b088f6d96eebb7055c21 /sys/dev/pci/pci_private.h
parentd38d0090c0a19005eceb643a2d6992bb69c4855e (diff)
downloadsrc-6b0ff427a57b12372e9b7181e92e50b17c773ca9.tar.gz
src-6b0ff427a57b12372e9b7181e92e50b17c773ca9.zip
Further refine the handling of resources for BARs in the PCI bus driver.
A while back, Warner changed the PCI bus code to reserve resources when enumerating devices and simply give devices the previously allocated resources when they call bus_alloc_resource(). This ensures that address ranges being decoded by a BAR are always allocated in the nexus0 device (or whatever device the PCI bus gets its address space from) even if a device driver is not attached to the device. This patch extends this behavior further: - To let the PCI bus distinguish between a resource being allocated by a device driver vs. merely being allocated by the bus, use rman_set_device() to assign the device to the bus when it is owned by the bus and to the child device when it is allocated by the child device's driver. We can now prevent a device driver from allocating the same device twice. Doing so could result in odd things like allocating duplicate virtual memory to map the resource on some archs and leaking the original mapping. - When a PCI device driver releases a resource, don't pass the request all the way up the tree and release it in the nexus (or similar device) since the BAR is still active and decoding. Otherwise, another device could later allocate the same range even though it is still in use. Instead, deactivate the resource and assign it back to the PCI bus using rman_set_device(). - pci_delete_resource() will actually completely free a BAR including attemping to disable it. - Disable BAR decoding via the command register when sizing a BAR in pci_alloc_map() which is used to allocate resources for a BAR when the BIOS/firmware did not assign a usable resource range during boot. This mirrors an earlier fix to pci_add_map() which is used when to size BARs during boot. - Move the activation of I/O decoding in the PCI command register into pci_activate_resource() instead of doing it in pci_alloc_resource(). Previously we could actually enable decoding before a BAR was initialized via pci_alloc_map(). Glanced at by: bsdimp
Notes
Notes: svn path=/head/; revision=189306
Diffstat (limited to 'sys/dev/pci/pci_private.h')
-rw-r--r--sys/dev/pci/pci_private.h4
1 files changed, 4 insertions, 0 deletions
diff --git a/sys/dev/pci/pci_private.h b/sys/dev/pci/pci_private.h
index f7ccc1958c30..e45afb7ac1c3 100644
--- a/sys/dev/pci/pci_private.h
+++ b/sys/dev/pci/pci_private.h
@@ -82,6 +82,10 @@ int pci_msix_count_method(device_t dev, device_t child);
struct resource *pci_alloc_resource(device_t dev, device_t child,
int type, int *rid, u_long start, u_long end, u_long count,
u_int flags);
+int pci_release_resource(device_t dev, device_t child, int type,
+ int rid, struct resource *r);
+int pci_activate_resource(device_t dev, device_t child, int type,
+ int rid, struct resource *r);
void pci_delete_resource(device_t dev, device_t child,
int type, int rid);
struct resource_list *pci_get_resource_list (device_t dev, device_t child);