summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBernhard Kohl2010-01-22 00:13:48 +0100
committerMarty Connor2010-01-22 00:13:48 +0100
commit466d8fc234cf32cb63d9d773e2f92f51860165f9 (patch)
tree111f8fad657583409c1a78a8448c23628423975f
parent[ftp] User and password URI support for the FTP protocol (diff)
downloadipxe-466d8fc234cf32cb63d9d773e2f92f51860165f9.tar.gz
ipxe-466d8fc234cf32cb63d9d773e2f92f51860165f9.tar.xz
ipxe-466d8fc234cf32cb63d9d773e2f92f51860165f9.zip
[pci] Save and restore PCI command register
This seems to be necessary for some types of PCI devices. We had problems when using gPXE in KVM virtual machines with direct PCI device access. Signed-off-by: Bernhard Kohl <bernhard.kohl@nsn.com> Signed-off-by: Shao Miller <shao.miller@yrdsb.edu.on.ca> Modified-by: Marty Connor <mdc@etherboot.org> Signed-off-by: Marty Connor <mdc@etherboot.org>
-rw-r--r--src/drivers/bus/pciextra.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/src/drivers/bus/pciextra.c b/src/drivers/bus/pciextra.c
index 1dd63ee3..74c40990 100644
--- a/src/drivers/bus/pciextra.c
+++ b/src/drivers/bus/pciextra.c
@@ -60,8 +60,11 @@ int pci_find_capability ( struct pci_device *pci, int cap ) {
* function.
*/
unsigned long pci_bar_size ( struct pci_device *pci, unsigned int reg ) {
+ uint16_t cmd;
uint32_t start, size;
+ /* Save the original command register */
+ pci_read_config_word ( pci, PCI_COMMAND, &cmd );
/* Save the original bar */
pci_read_config_dword ( pci, reg, &start );
/* Compute which bits can be set */
@@ -70,6 +73,8 @@ unsigned long pci_bar_size ( struct pci_device *pci, unsigned int reg ) {
/* Restore the original size */
pci_write_config_dword ( pci, reg, start );
/* Find the significant bits */
+ /* Restore the original command register. This reenables decoding. */
+ pci_write_config_word ( pci, PCI_COMMAND, cmd );
if ( start & PCI_BASE_ADDRESS_SPACE_IO ) {
size &= PCI_BASE_ADDRESS_IO_MASK;
} else {