summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@openbsd.org>2014-09-29 22:34:25 +0200
committerMark Kettenis <kettenis@openbsd.org>2014-09-29 22:43:30 +0200
commit9b1bf11c81881c9cc6e6145011cf229978f109f4 (patch)
treefaf8bcf954449109bf81d11d66903ff6ea29b3e2
parentb7e42643d2ee6521cf23e6dfe49a8369ba4bf9bb (diff)
Use PCIOCREADMASK on OpenBSD.
If the machdep.allowaperture sysctl(8) variable is set to 0, writing to PCI config space is not allowed. So instead of writing 0xffffffff to the BARs in order to determine their size, use the PCIOCREADMASK ioctl(2) which returns the mask of changeable bits that was saved by the kernel when the devices was initially probed. Reviewed-by: Matthieu Herrb <matthieu@herbb.eu> Signed-off-by: Mark Kettenis <kettenis@openbsd.org>
-rw-r--r--src/openbsd_pci.c31
1 files changed, 25 insertions, 6 deletions
diff --git a/src/openbsd_pci.c b/src/openbsd_pci.c
index fe034f3..4d1b5cd 100644
--- a/src/openbsd_pci.c
+++ b/src/openbsd_pci.c
@@ -81,6 +81,29 @@ pci_write(int domain, int bus, int dev, int func, uint32_t reg, uint32_t val)
return ioctl(pcifd[domain], PCIOCWRITE, &io);
}
+static int
+pci_readmask(int domain, int bus, int dev, int func, uint32_t reg,
+ uint32_t *val)
+{
+ struct pci_io io;
+ int err;
+
+ bzero(&io, sizeof(io));
+ io.pi_sel.pc_bus = bus;
+ io.pi_sel.pc_dev = dev;
+ io.pi_sel.pc_func = func;
+ io.pi_reg = reg;
+ io.pi_width = 4;
+
+ err = ioctl(pcifd[domain], PCIOCREADMASK, &io);
+ if (err)
+ return (err);
+
+ *val = io.pi_data;
+
+ return 0;
+}
+
/**
* Read a VGA ROM
*
@@ -328,11 +351,9 @@ pci_device_openbsd_probe(struct pci_device *device)
return err;
/* Probe the size of the region. */
- err = pci_write(domain, bus, dev, func, bar, ~0);
+ err = pci_readmask(domain, bus, dev, func, bar, &size);
if (err)
return err;
- pci_read(domain, bus, dev, func, bar, &size);
- pci_write(domain, bus, dev, func, bar, reg);
if (PCI_MAPREG_TYPE(reg) == PCI_MAPREG_TYPE_IO) {
region->is_IO = 1;
@@ -360,11 +381,9 @@ pci_device_openbsd_probe(struct pci_device *device)
return err;
reg64 |= (uint64_t)reg << 32;
- err = pci_write(domain, bus, dev, func, bar, ~0);
+ err = pci_readmask(domain, bus, dev, func, bar, &size);
if (err)
return err;
- pci_read(domain, bus, dev, func, bar, &size);
- pci_write(domain, bus, dev, func, bar, reg64 >> 32);
size64 |= (uint64_t)size << 32;
region->base_addr = PCI_MAPREG_MEM64_ADDR(reg64);