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
This commit is contained in:
Roger Pau Monné 2017-08-01 10:47:44 +00:00
parent 945c72c7ae
commit d4ed36cde2

View File

@ -2902,13 +2902,21 @@ pci_read_bar(device_t dev, int reg, pci_addr_t *mapp, pci_addr_t *testvalp,
* 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