]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/commit
Further refine the handling of resources for BARs in the PCI bus driver.
authorjhb <jhb@FreeBSD.org>
Tue, 3 Mar 2009 16:38:59 +0000 (16:38 +0000)
committerjhb <jhb@FreeBSD.org>
Tue, 3 Mar 2009 16:38:59 +0000 (16:38 +0000)
commit534d3efa16fa0651c5b97d3d506ddce25334a6d9
treec8adf2857947d5880db3b088f6d96eebb7055c21
parent20ac2eb4b28545fe7dd2e5033ed55f78f94d157e
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
sys/dev/pci/pci.c
sys/dev/pci/pci_private.h