svn commit: r321863 - head/sys/dev/pci
Roger Pau Monné
royger at FreeBSD.org
Tue Aug 1 10:47:45 UTC 2017
Author: royger
Date: Tue Aug 1 10:47:44 2017
New Revision: 321863
URL: https://svnweb.freebsd.org/changeset/base/321863
Log:
pci: fix write order when sizing BARs
According to the PCI Local Specification rev. 3.0 in case of a 64-bit
BAR both the low and the high parts of the register should be set to
~0 before attempting to read back the size.
So far I have found no single device that has problems with the
previous approach, but I think it's better to stay on the safe size.
This commit should not introduce any functional change.
MFC after: 3 weeks
Sponsored by: Citrix Systems R&D
Reviewed by: jhb
Differential revision: https://reviews.freebsd.org/D11750
Modified:
head/sys/dev/pci/pci.c
Modified: head/sys/dev/pci/pci.c
==============================================================================
--- head/sys/dev/pci/pci.c Tue Aug 1 10:46:47 2017 (r321862)
+++ head/sys/dev/pci/pci.c Tue Aug 1 10:47:44 2017 (r321863)
@@ -2902,13 +2902,21 @@ pci_read_bar(device_t dev, int reg, pci_addr_t *mapp,
* Determine the BAR's length by writing all 1's. The bottom
* log_2(size) bits of the BAR will stick as 0 when we read
* the value back.
+ *
+ * NB: according to the PCI Local Bus Specification, rev. 3.0:
+ * "Software writes 0FFFFFFFFh to both registers, reads them back,
+ * and combines the result into a 64-bit value." (section 6.2.5.1)
+ *
+ * Writes to both registers must be performed before attempting to
+ * read back the size value.
*/
+ testval = 0;
pci_write_config(dev, reg, 0xffffffff, 4);
- testval = pci_read_config(dev, reg, 4);
if (ln2range == 64) {
pci_write_config(dev, reg + 4, 0xffffffff, 4);
testval |= (pci_addr_t)pci_read_config(dev, reg + 4, 4) << 32;
}
+ testval |= pci_read_config(dev, reg, 4);
/*
* Restore the original value of the BAR. We may have reprogrammed
More information about the svn-src-all
mailing list