On Sun, Jun 02, 2013 at 10:38:41PM +0200, Thomas Klausner wrote: > --- > configure.ac | 4 +- > src/netbsd_pci.c | 471 > +++++++++++++++++++++++++++++++++++++++---------------- > 2 files changed, 342 insertions(+), 133 deletions(-)
Reviewed-by: Matthieu Herrb <matthieu.he...@laas.fr> > > diff --git a/configure.ac b/configure.ac > index 91374e5..3441b63 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -77,10 +77,10 @@ case $host_os in > *netbsd*) > case $host in > *i386*) > - PCIACCESS_LIBS="-li386" > + PCIACCESS_LIBS="-li386 -lpci" > ;; > *x86_64*|*amd64*) > - PCIACCESS_LIBS="-lx86_64" > + PCIACCESS_LIBS="-lx86_64 -lpci" > ;; > esac > netbsd=yes > diff --git a/src/netbsd_pci.c b/src/netbsd_pci.c > index 63585e3..f5a90c0 100644 > --- a/src/netbsd_pci.c > +++ b/src/netbsd_pci.c > @@ -1,6 +1,7 @@ > /* > * Copyright (c) 2008 Juan Romero Pardines > * Copyright (c) 2008 Mark Kettenis > + * Copyright (c) 2009 Michael Lorenz > * > * Permission to use, copy, modify, and distribute this software for any > * purpose with or without fee is hereby granted, provided that the above > @@ -20,12 +21,15 @@ > #include <sys/mman.h> > #include <sys/types.h> > > +#ifdef HAVE_MTRR > #include <machine/sysarch.h> > #include <machine/mtrr.h> > +#define netbsd_set_mtrr(mr, num) _X86_SYSARCH_L(set_mtrr)(mr, num) > +#endif > > +#include <dev/pci/pcidevs.h> > #include <dev/pci/pciio.h> > #include <dev/pci/pcireg.h> > -#include <dev/pci/pcidevs.h> > > #include <errno.h> > #include <fcntl.h> > @@ -35,126 +39,152 @@ > #include <unistd.h> > > > +#include <pci.h> > +#include <dev/wscons/wsconsio.h> > + > #include "pciaccess.h" > #include "pciaccess_private.h" > > -static int pcifd; > +typedef struct _pcibus { > + int fd; /* /dev/pci* */ > + int num; /* bus number */ > + int maxdevs; /* maximum number of devices */ > +} PciBus; > + > +static PciBus buses[32]; /* indexed by pci_device.domain */ > +static int nbuses = 0; /* number of buses found */ > + > +/* > + * NetBSD's userland has a /dev/pci* entry for each bus but userland has no > way > + * to tell if a bus is a subordinate of another one or if it's on a different > + * host bridge. On some architectures ( macppc for example ) all root buses > have > + * bus number 0 but on sparc64 for example the two roots in an Ultra60 have > + * different bus numbers - one is 0 and the other 128. > + * With each /dev/pci* we can map everything on the same root and we can also > + * see all devices on the same root, trying to do that causes problems > though: > + * - since we can't tell which /dev/pci* is a subordinate we would find some > + * devices more than once > + * - we would have to guess subordinate bus numbers which is a waste of time > + * since we can ask each /dev/pci* for its bus number so we can scan only > the > + * buses we know exist, not all 256 which may exist in each domain. > + * - some bus_space_mmap() methods may limit mappings to address ranges which > + * belong to known devices on that bus only. > + * Each host bridge may or may not have its own IO range, to avoid guesswork > + * here each /dev/pci* will let userland map its appropriate IO range at > + * PCI_MAGIC_IO_RANGE if defined in <machine/param.h> > + * With all this we should be able to use any PCI graphics device on any PCI > + * bus on any architecture as long as Xorg has a driver, without allowing > + * arbitrary mappings via /dev/mem and without userland having to know or > care > + * about translating bus addresses to physical addresses or the other way > + * around. > + */ > > static int > -pci_read(int bus, int dev, int func, uint32_t reg, uint32_t *val) > +pci_read(int domain, int bus, int dev, int func, uint32_t reg, uint32_t *val) > { > - struct pciio_bdf_cfgreg io; > - int err; > + uint32_t rval; > > - bzero(&io, sizeof(io)); > - io.bus = bus; > - io.device = dev; > - io.function = func; > - io.cfgreg.reg = reg; > + if ((domain < 0) || (domain > nbuses)) > + return -1; > > - err = ioctl(pcifd, PCI_IOC_BDF_CFGREAD, &io); > - if (err) > - return (err); > + if (pcibus_conf_read(buses[domain].fd, (unsigned int)bus, > + (unsigned int)dev, (unsigned int)func, reg, &rval) == -1) > + return (-1); > > - *val = io.cfgreg.val; > + *val = rval; > > return 0; > } > > static int > -pci_write(int bus, int dev, int func, uint32_t reg, uint32_t val) > +pci_write(int domain, int bus, int dev, int func, uint32_t reg, uint32_t val) > { > - struct pciio_bdf_cfgreg io; > > - bzero(&io, sizeof(io)); > - io.bus = bus; > - io.device = dev; > - io.function = func; > - io.cfgreg.reg = reg; > - io.cfgreg.val = val; > + if ((domain < 0) || (domain > nbuses)) > + return -1; > > - return ioctl(pcifd, PCI_IOC_BDF_CFGWRITE, &io); > + return pcibus_conf_write(buses[domain].fd, (unsigned int)bus, > + (unsigned int)dev, (unsigned int)func, reg, val); > } > > static int > -pci_nfuncs(int bus, int dev) > +pci_nfuncs(int domain, int bus, int dev) > { > uint32_t hdr; > > - if (pci_read(bus, dev, 0, PCI_BHLC_REG, &hdr) != 0) > + if ((domain < 0) || (domain > nbuses)) > + return -1; > + > + if (pci_read(domain, bus, dev, 0, PCI_BHLC_REG, &hdr) != 0) > return -1; > > return (PCI_HDRTYPE_MULTIFN(hdr) ? 8 : 1); > } > > +/*ARGSUSED*/ > static int > pci_device_netbsd_map_range(struct pci_device *dev, > struct pci_device_mapping *map) > { > - struct mtrr mtrr; > - int fd, error, nmtrr, prot = PROT_READ; > +#ifdef HAVE_MTRR > + struct mtrr m; > + int n = 1; > +#endif > + int prot, ret = 0; > > - if ((fd = open("/dev/mem", O_RDWR | O_CLOEXEC)) == -1) > - return errno; > + prot = PROT_READ; > > if (map->flags & PCI_DEV_MAP_FLAG_WRITABLE) > prot |= PROT_WRITE; > - > - map->memory = mmap(NULL, map->size, prot, MAP_SHARED, > - fd, map->base); > + map->memory = mmap(NULL, (size_t)map->size, prot, MAP_SHARED, > + buses[dev->domain].fd, (off_t)map->base); > if (map->memory == MAP_FAILED) > return errno; > > +#ifdef HAVE_MTRR > + memset(&m, 0, sizeof(m)); > + > /* No need to set an MTRR if it's the default mode. */ > if ((map->flags & PCI_DEV_MAP_FLAG_CACHABLE) || > (map->flags & PCI_DEV_MAP_FLAG_WRITE_COMBINE)) { > - mtrr.base = map->base; > - mtrr.len = map->size; > - mtrr.flags = MTRR_VALID; > - > + m.base = map->base; > + m.flags = MTRR_VALID | MTRR_PRIVATE; > + m.len = map->size; > + m.owner = getpid(); > if (map->flags & PCI_DEV_MAP_FLAG_CACHABLE) > - mtrr.type = MTRR_TYPE_WB; > + m.type = MTRR_TYPE_WB; > if (map->flags & PCI_DEV_MAP_FLAG_WRITE_COMBINE) > - mtrr.type = MTRR_TYPE_WC; > -#ifdef __i386__ > - error = i386_set_mtrr(&mtrr, &nmtrr); > -#endif > -#ifdef __amd64__ > - error = x86_64_set_mtrr(&mtrr, &nmtrr); > -#endif > - if (error) { > - close(fd); > - return errno; > + m.type = MTRR_TYPE_WC; > + > + if ((netbsd_set_mtrr(&m, &n)) == -1) { > + fprintf(stderr, "mtrr set failed: %s\n", > + strerror(errno)); > } > } > +#endif > > - close(fd); > - > - return 0; > + return ret; > } > > static int > pci_device_netbsd_unmap_range(struct pci_device *dev, > struct pci_device_mapping *map) > { > - struct mtrr mtrr; > - int nmtrr, error; > +#ifdef HAVE_MTRR > + struct mtrr m; > + int n = 1; > + > + memset(&m, 0, sizeof(m)); > > if ((map->flags & PCI_DEV_MAP_FLAG_CACHABLE) || > (map->flags & PCI_DEV_MAP_FLAG_WRITE_COMBINE)) { > - mtrr.base = map->base; > - mtrr.len = map->size; > - mtrr.type = MTRR_TYPE_UC; > - mtrr.flags = 0; /* clear/set MTRR */ > -#ifdef __i386__ > - error = i386_set_mtrr(&mtrr, &nmtrr); > -#endif > -#ifdef __amd64__ > - error = x86_64_set_mtrr(&mtrr, &nmtrr); > -#endif > - if (error) > - return errno; > + m.base = map->base; > + m.flags = 0; > + m.len = map->size; > + m.type = MTRR_TYPE_UC; > + (void)netbsd_set_mtrr(&m, &n); > } > +#endif > > return pci_device_generic_unmap_range(dev, map); > } > @@ -163,25 +193,23 @@ static int > pci_device_netbsd_read(struct pci_device *dev, void *data, > pciaddr_t offset, pciaddr_t size, pciaddr_t *bytes_read) > { > - struct pciio_bdf_cfgreg io; > - > - io.bus = dev->bus; > - io.device = dev->dev; > - io.function = dev->func; > + u_int reg, rval; > > *bytes_read = 0; > while (size > 0) { > - int toread = MIN(size, 4 - (offset & 0x3)); > + size_t toread = MIN(size, 4 - (offset & 0x3)); > > - io.cfgreg.reg = (offset & ~0x3); > + reg = (u_int)(offset & ~0x3); > > - if (ioctl(pcifd, PCI_IOC_BDF_CFGREAD, &io) == -1) > + if ((pcibus_conf_read(buses[dev->domain].fd, > + (unsigned int)dev->bus, (unsigned int)dev->dev, > + (unsigned int)dev->func, reg, &rval)) == -1) > return errno; > > - io.cfgreg.val = htole32(io.cfgreg.val); > - io.cfgreg.val >>= ((offset & 0x3) * 8); > + rval = htole32(rval); > + rval >>= ((offset & 0x3) * 8); > > - memcpy(data, &io.cfgreg.val, toread); > + memcpy(data, &rval, toread); > > offset += toread; > data = (char *)data + toread; > @@ -196,25 +224,23 @@ static int > pci_device_netbsd_write(struct pci_device *dev, const void *data, > pciaddr_t offset, pciaddr_t size, pciaddr_t *bytes_written) > { > - struct pciio_bdf_cfgreg io; > + u_int reg, val; > > if ((offset % 4) != 0 || (size % 4) != 0) > return EINVAL; > > - io.bus = dev->bus; > - io.device = dev->dev; > - io.function = dev->func; > - > *bytes_written = 0; > while (size > 0) { > - io.cfgreg.reg = offset; > - memcpy(&io.cfgreg.val, data, 4); > + reg = (u_int)offset; > + memcpy(&val, data, 4); > > - if (ioctl(pcifd, PCI_IOC_BDF_CFGWRITE, &io) == -1) > + if ((pcibus_conf_write(buses[dev->domain].fd, > + (unsigned int)dev->bus, (unsigned int)dev->dev, > + (unsigned int)dev->func, reg, val)) == -1) > return errno; > > offset += 4; > - data = (char *)data + 4; > + data = (const char *)data + 4; > size -= 4; > *bytes_written += 4; > } > @@ -222,10 +248,51 @@ pci_device_netbsd_write(struct pci_device *dev, const > void *data, > return 0; > } > > +static int > +pci_device_netbsd_boot_vga(struct pci_device *dev) > +{ > + int ret; > + struct wsdisplayio_bus_id busid; > + int fd; > + > + fd = open("/dev/ttyE0", O_RDONLY); > + if (fd == -1) { > + fprintf(stderr, "failed to open /dev/ttyE0: %s\n", > + strerror(errno)); > + return 0; > + } > + > + ret = ioctl(fd, WSDISPLAYIO_GET_BUSID, &busid); > + close(fd); > + if (ret == -1) { > + fprintf(stderr, "ioctl WSDISPLAYIO_GET_BUSID failed: %s\n", > + strerror(errno)); > + return 0; > + } > + > + if (busid.bus_type != WSDISPLAYIO_BUS_PCI) > + return 0; > + > + if (busid.ubus.pci.domain != dev->domain) > + return 0; > + if (busid.ubus.pci.bus != dev->bus) > + return 0; > + if (busid.ubus.pci.device != dev->dev) > + return 0; > + if (busid.ubus.pci.function != dev->func) > + return 0; > + > + return 1; > +} > + > static void > pci_system_netbsd_destroy(void) > { > - close(pcifd); > + int i; > + > + for (i = 0; i < nbuses; i++) { > + close(buses[i].fd); > + } > free(pci_sys); > pci_sys = NULL; > } > @@ -233,17 +300,34 @@ pci_system_netbsd_destroy(void) > static int > pci_device_netbsd_probe(struct pci_device *device) > { > - struct pci_device_private *priv = (struct pci_device_private *)device; > + struct pci_device_private *priv = > + (struct pci_device_private *)(void *)device; > struct pci_mem_region *region; > uint64_t reg64, size64; > uint32_t bar, reg, size; > - int bus, dev, func, err; > + int bus, dev, func, err, domain; > > + domain = device->domain; > bus = device->bus; > dev = device->dev; > func = device->func; > > - err = pci_read(bus, dev, func, PCI_BHLC_REG, ®); > + /* Enable the device if necessary */ > + err = pci_read(domain, bus, dev, func, PCI_COMMAND_STATUS_REG, ®); > + if (err) > + return err; > + if ((reg & (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE | > PCI_COMMAND_MASTER_ENABLE)) != > + (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE | > PCI_COMMAND_MASTER_ENABLE)) { > + reg |= PCI_COMMAND_IO_ENABLE | > + PCI_COMMAND_MEM_ENABLE | > + PCI_COMMAND_MASTER_ENABLE; > + err = pci_write(domain, bus, dev, func, PCI_COMMAND_STATUS_REG, > + reg); > + if (err) > + return err; > + } > + > + err = pci_read(domain, bus, dev, func, PCI_BHLC_REG, ®); > if (err) > return err; > > @@ -254,16 +338,16 @@ pci_device_netbsd_probe(struct pci_device *device) > region = device->regions; > for (bar = PCI_MAPREG_START; bar < PCI_MAPREG_END; > bar += sizeof(uint32_t), region++) { > - err = pci_read(bus, dev, func, bar, ®); > + err = pci_read(domain, bus, dev, func, bar, ®); > if (err) > return err; > > /* Probe the size of the region. */ > - err = pci_write(bus, dev, func, bar, ~0); > + err = pci_write(domain, bus, dev, func, bar, (unsigned int)~0); > if (err) > return err; > - pci_read(bus, dev, func, bar, &size); > - pci_write(bus, dev, func, bar, reg); > + 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; > @@ -286,66 +370,185 @@ pci_device_netbsd_probe(struct pci_device *device) > > bar += sizeof(uint32_t); > > - err = pci_read(bus, dev, func, bar, ®); > + err = pci_read(domain, bus, dev, func, bar, > ®); > if (err) > return err; > reg64 |= (uint64_t)reg << 32; > > - err = pci_write(bus, dev, func, bar, ~0); > + err = pci_write(domain, bus, dev, func, bar, > + (unsigned int)~0); > if (err) > return err; > - pci_read(bus, dev, func, bar, &size); > - pci_write(bus, dev, func, bar, reg64 >> 32); > + pci_read(domain, bus, dev, func, bar, &size); > + pci_write(domain, bus, dev, func, bar, > + (unsigned int)(reg64 >> 32)); > size64 |= (uint64_t)size << 32; > > - region->base_addr = > PCI_MAPREG_MEM64_ADDR(reg64); > - region->size = PCI_MAPREG_MEM64_SIZE(size64); > + region->base_addr = > + (unsigned long)PCI_MAPREG_MEM64_ADDR(reg64); > + region->size = > + (unsigned > long)PCI_MAPREG_MEM64_SIZE(size64); > region++; > break; > } > } > } > > + /* Probe expansion ROM if present */ > + err = pci_read(domain, bus, dev, func, PCI_MAPREG_ROM, ®); > + if (err) > + return err; > + if (reg != 0) { > + err = pci_write(domain, bus, dev, func, PCI_MAPREG_ROM, > + (uint32_t)(~PCI_MAPREG_ROM_ENABLE)); > + if (err) > + return err; > + pci_read(domain, bus, dev, func, PCI_MAPREG_ROM, &size); > + pci_write(domain, bus, dev, func, PCI_MAPREG_ROM, reg); > + if ((reg & PCI_MAPREG_MEM_ADDR_MASK) != 0) { > + priv->rom_base = reg & PCI_MAPREG_MEM_ADDR_MASK; > + device->rom_size = -(size & PCI_MAPREG_MEM_ADDR_MASK); > + } > + } > + > return 0; > } > > +/** > + * Read a VGA rom using the 0xc0000 mapping. > + * > + * This function should be extended to handle access through PCI resources, > + * which should be more reliable when available. > + */ > +static int > +pci_device_netbsd_read_rom(struct pci_device *dev, void *buffer) > +{ > + struct pci_device_private *priv = (struct pci_device_private *)(void > *)dev; > + void *bios; > + pciaddr_t rom_base; > + size_t rom_size; > + uint32_t bios_val, command_val; > + int pci_rom; > + > + if (((priv->base.device_class >> 16) & 0xff) != PCI_CLASS_DISPLAY || > + ((priv->base.device_class >> 8) & 0xff) != PCI_SUBCLASS_DISPLAY_VGA) > + return ENOSYS; > + > + if (priv->rom_base == 0) { > +#if defined(__amd64__) || defined(__i386__) > + /* > + * We need a way to detect when this isn't the console and reject > + * this request outright. > + */ > + rom_base = 0xc0000; > + rom_size = 0x10000; > + pci_rom = 0; > +#else > + return ENOSYS; > +#endif > + } else { > + rom_base = priv->rom_base; > + rom_size = dev->rom_size; > + pci_rom = 1; > + if ((pcibus_conf_read(buses[dev->domain].fd, (unsigned int)dev->bus, > + (unsigned int)dev->dev, (unsigned int)dev->func, > + PCI_COMMAND_STATUS_REG, &command_val)) == -1) > + return errno; > + if ((command_val & PCI_COMMAND_MEM_ENABLE) == 0) { > + if ((pcibus_conf_write(buses[dev->domain].fd, > + (unsigned int)dev->bus, (unsigned int)dev->dev, > + (unsigned int)dev->func, PCI_COMMAND_STATUS_REG, > + command_val | PCI_COMMAND_MEM_ENABLE)) == -1) > + return errno; > + } > + if ((pcibus_conf_read(buses[dev->domain].fd, (unsigned int)dev->bus, > + (unsigned int)dev->dev, (unsigned int)dev->func, > + PCI_MAPREG_ROM, &bios_val)) == -1) > + return errno; > + if ((bios_val & PCI_MAPREG_ROM_ENABLE) == 0) { > + if ((pcibus_conf_write(buses[dev->domain].fd, > + (unsigned int)dev->bus, > + (unsigned int)dev->dev, (unsigned int)dev->func, > + PCI_MAPREG_ROM, bios_val | PCI_MAPREG_ROM_ENABLE)) == -1) > + return errno; > + } > + } > + > + fprintf(stderr, "Using rom_base = 0x%lx 0x%lx (pci_rom=%d)\n", > + (long)rom_base, (long)rom_size, pci_rom); > + > + bios = mmap(NULL, rom_size, PROT_READ, MAP_SHARED, > buses[dev->domain].fd, > + (off_t)rom_base); > + if (bios == MAP_FAILED) { > + int serrno = errno; > + return serrno; > + } > + > + memcpy(buffer, bios, rom_size); > + > + munmap(bios, rom_size); > + > + if (pci_rom) { > + if ((command_val & PCI_COMMAND_MEM_ENABLE) == 0) { > + if ((pcibus_conf_write(buses[dev->domain].fd, > + (unsigned int)dev->bus, > + (unsigned int)dev->dev, (unsigned int)dev->func, > + PCI_COMMAND_STATUS_REG, command_val)) == -1) > + return errno; > + } > + if ((bios_val & PCI_MAPREG_ROM_ENABLE) == 0) { > + if ((pcibus_conf_write(buses[dev->domain].fd, > + (unsigned int)dev->bus, > + (unsigned int)dev->dev, (unsigned int)dev->func, > + PCI_MAPREG_ROM, bios_val)) == -1) > + return errno; > + } > + } > + > + return 0; > +} > + > static const struct pci_system_methods netbsd_pci_methods = { > - pci_system_netbsd_destroy, > - NULL, > - NULL, > - pci_device_netbsd_probe, > - pci_device_netbsd_map_range, > - pci_device_netbsd_unmap_range, > - pci_device_netbsd_read, > - pci_device_netbsd_write, > - pci_fill_capabilities_generic > + .destroy = pci_system_netbsd_destroy, > + .destroy_device = NULL, > + .read_rom = pci_device_netbsd_read_rom, > + .probe = pci_device_netbsd_probe, > + .map_range = pci_device_netbsd_map_range, > + .unmap_range = pci_device_netbsd_unmap_range, > + .read = pci_device_netbsd_read, > + .write = pci_device_netbsd_write, > + .fill_capabilities = pci_fill_capabilities_generic, > + .boot_vga = pci_device_netbsd_boot_vga, > }; > > int > pci_system_netbsd_create(void) > { > struct pci_device_private *device; > - int bus, dev, func, ndevs, nfuncs; > + int bus, dev, func, ndevs, nfuncs, domain, pcifd; > uint32_t reg; > - > - pcifd = open("/dev/pci0", O_RDWR | O_CLOEXEC); > - if (pcifd == -1) > - return ENXIO; > + char netbsd_devname[32]; > + struct pciio_businfo businfo; > > pci_sys = calloc(1, sizeof(struct pci_system)); > - if (pci_sys == NULL) { > - close(pcifd); > - return ENOMEM; > - } > > pci_sys->methods = &netbsd_pci_methods; > > ndevs = 0; > - for (bus = 0; bus < 256; bus++) { > - for (dev = 0; dev < 32; dev++) { > - nfuncs = pci_nfuncs(bus, dev); > + nbuses = 0; > + snprintf(netbsd_devname, 32, "/dev/pci%d", nbuses); > + pcifd = open(netbsd_devname, O_RDWR | O_CLOEXEC); > + while (pcifd > 0) { > + ioctl(pcifd, PCI_IOC_BUSINFO, &businfo); > + buses[nbuses].fd = pcifd; > + buses[nbuses].num = bus = businfo.busno; > + buses[nbuses].maxdevs = businfo.maxdevs; > + domain = nbuses; > + nbuses++; > + for (dev = 0; dev < businfo.maxdevs; dev++) { > + nfuncs = pci_nfuncs(domain, bus, dev); > for (func = 0; func < nfuncs; func++) { > - if (pci_read(bus, dev, func, PCI_ID_REG, > + if (pci_read(domain, bus, dev, func, PCI_ID_REG, > ®) != 0) > continue; > if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID || > @@ -355,37 +558,43 @@ pci_system_netbsd_create(void) > ndevs++; > } > } > + snprintf(netbsd_devname, 32, "/dev/pci%d", nbuses); > + pcifd = open(netbsd_devname, O_RDWR); > } > > pci_sys->num_devices = ndevs; > pci_sys->devices = calloc(ndevs, sizeof(struct pci_device_private)); > if (pci_sys->devices == NULL) { > + int i; > + > + for (i = 0; i < nbuses; i++) > + close(buses[i].fd); > free(pci_sys); > - close(pcifd); > return ENOMEM; > } > > device = pci_sys->devices; > - for (bus = 0; bus < 256; bus++) { > - for (dev = 0; dev < 32; dev++) { > - nfuncs = pci_nfuncs(bus, dev); > + for (domain = 0; domain < nbuses; domain++) { > + bus = buses[domain].num; > + for (dev = 0; dev < buses[domain].maxdevs; dev++) { > + nfuncs = pci_nfuncs(domain, bus, dev); > for (func = 0; func < nfuncs; func++) { > - if (pci_read(bus, dev, func, PCI_ID_REG, > - ®) != 0) > + if (pci_read(domain, bus, dev, func, > + PCI_ID_REG, ®) != 0) > continue; > if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID || > PCI_VENDOR(reg) == 0) > continue; > > - device->base.domain = 0; > + device->base.domain = domain; > device->base.bus = bus; > device->base.dev = dev; > device->base.func = func; > device->base.vendor_id = PCI_VENDOR(reg); > device->base.device_id = PCI_PRODUCT(reg); > > - if (pci_read(bus, dev, func, PCI_CLASS_REG, > - ®) != 0) > + if (pci_read(domain, bus, dev, func, > + PCI_CLASS_REG, ®) != 0) > continue; > > device->base.device_class = > @@ -393,8 +602,8 @@ pci_system_netbsd_create(void) > PCI_SUBCLASS(reg) << 8; > device->base.revision = PCI_REVISION(reg); > > - if (pci_read(bus, dev, func, PCI_SUBSYS_ID_REG, > - ®) != 0) > + if (pci_read(domain, bus, dev, func, > + PCI_SUBSYS_ID_REG, ®) != 0) > continue; > > device->base.subvendor_id = PCI_VENDOR(reg); > -- > 1.8.2.3 > > _______________________________________________ > xorg-devel@lists.x.org: X.Org development > Archives: http://lists.x.org/archives/xorg-devel > Info: http://lists.x.org/mailman/listinfo/xorg-devel -- Matthieu Herrb _______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel