diff options
-rw-r--r-- | src/netbsd_pci.c | 24 | ||||
-rw-r--r-- | src/openbsd_pci.c | 31 |
2 files changed, 49 insertions, 6 deletions
diff --git a/src/netbsd_pci.c b/src/netbsd_pci.c index e6dae4c..52591b0 100644 --- a/src/netbsd_pci.c +++ b/src/netbsd_pci.c @@ -843,6 +843,29 @@ pci_device_netbsd_unmap_legacy(struct pci_device *dev, void *addr, return pci_device_netbsd_unmap_range(dev, &map); } +static int +pci_device_netbsd_has_kernel_driver(struct pci_device *dev) +{ +#ifdef PCI_IOC_DRVNAME + /* + * NetBSD PCI_IOC_DRVNAME appears at the same time as pci_drvname(3) + */ + char drvname[16]; + + if (dev->bus >= nbuses) + return 0; + + /* + * vga(4) should be considered "not bound". + */ + if (pci_drvname(buses[dev->bus].fd, dev->dev, dev->func, + drvname, sizeof drvname) == 0 && + strncmp(drvname, "vga", 3) != 0) + return 1; +#endif + return 0; +} + static const struct pci_system_methods netbsd_pci_methods = { .destroy = pci_system_netbsd_destroy, .destroy_device = NULL, @@ -867,6 +890,7 @@ static const struct pci_system_methods netbsd_pci_methods = { .write8 = pci_device_netbsd_write8, .map_legacy = pci_device_netbsd_map_legacy, .unmap_legacy = pci_device_netbsd_unmap_legacy, + .has_kernel_driver = pci_device_netbsd_has_kernel_driver, }; int diff --git a/src/openbsd_pci.c b/src/openbsd_pci.c index 5b24a22..1e7e13f 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); |