diff options
author | Martin Mares <mj@ucw.cz> | 2022-11-18 14:15:08 +0100 |
---|---|---|
committer | Martin Mares <mj@ucw.cz> | 2022-11-18 14:15:08 +0100 |
commit | 0a4fae20efcafa60ec2f2efd2e7de81b863471b7 (patch) | |
tree | d222fc546e14188ae5759087516a1f4c3f753707 | |
parent | b35db44c776e1fffe20f05015e8db589c774b172 (diff) | |
parent | b0c61ad624f8398b91bcdd201cdf13dc02d51372 (diff) | |
download | pciutils-0a4fae20efcafa60ec2f2efd2e7de81b863471b7.tar.gz |
Merge remote-tracking branch 'pali/intel-conf1-memio'
-rwxr-xr-x | lib/configure | 6 | ||||
-rw-r--r-- | lib/mmio-ports.c | 19 |
2 files changed, 19 insertions, 6 deletions
diff --git a/lib/configure b/lib/configure index eb4b9bf..57b064b 100755 --- a/lib/configure +++ b/lib/configure @@ -97,7 +97,7 @@ case $sys in echo >>$c '#define PCI_HAVE_STDINT_H' ;; freebsd*|kfreebsd*) - echo_n " fbsd-device" + echo_n " fbsd-device mem-ports" echo >>$c '#define PCI_HAVE_PM_FBSD_DEVICE' echo >>$c '#define PCI_HAVE_PM_MMIO_CONF' echo >>$c '#define PCI_PATH_FBSD_DEVICE "/dev/pci"' @@ -107,7 +107,7 @@ case $sys in fi ;; openbsd) - echo_n " obsd-device" + echo_n " obsd-device mem-ports" echo >>$c '#define PCI_HAVE_PM_OBSD_DEVICE' echo >>$c '#define PCI_HAVE_PM_MMIO_CONF' echo >>$c '#define PCI_PATH_OBSD_DEVICE "/dev/pci"' @@ -132,7 +132,7 @@ case $sys in echo >>$m 'DIRINSTALL=mkdir -p' ;; netbsd) - echo_n " nbsd-libpci" + echo_n " nbsd-libpci mem-ports" echo >>$c '#define PCI_HAVE_PM_NBSD_LIBPCI' echo >>$c '#define PCI_HAVE_PM_MMIO_CONF' echo >>$c '#define PCI_PATH_NBSD_DEVICE "/dev/pci0"' diff --git a/lib/mmio-ports.c b/lib/mmio-ports.c index b9e3926..ae9c30d 100644 --- a/lib/mmio-ports.c +++ b/lib/mmio-ports.c @@ -243,9 +243,9 @@ conf1_detect(struct pci_access *a) return 0; } - if (access(devmem, R_OK)) + if (access(devmem, R_OK | W_OK)) { - a->debug("cannot access %s", devmem); + a->debug("cannot access %s: %s", devmem, strerror(errno)); return 0; } @@ -269,7 +269,7 @@ conf1_init(struct pci_access *a) if (!validate_addrs(addrs)) a->error("Option mmio-conf1.addrs has invalid address format \"%s\".", addrs); - a->fd = open(devmem, O_RDWR); + a->fd = open(devmem, O_RDWR | O_DSYNC); /* O_DSYNC bypass CPU cache for mmap() on Linux */ if (a->fd < 0) a->error("Cannot open %s: %s.", devmem, strerror(errno)); } @@ -316,6 +316,7 @@ conf1_read(struct pci_dev *d, int pos, byte *buf, int len) return 0; writel(0x80000000 | ((d->bus & 0xff) << 16) | (PCI_DEVFN(d->dev, d->func) << 8) | (pos & 0xfc), addr); + readl(addr); /* write barrier for address */ switch (len) { @@ -353,6 +354,7 @@ conf1_write(struct pci_dev *d, int pos, byte *buf, int len) return 0; writel(0x80000000 | ((d->bus & 0xff) << 16) | (PCI_DEVFN(d->dev, d->func) << 8) | (pos & 0xfc), addr); + readl(addr); /* write barrier for address */ switch (len) { @@ -367,6 +369,17 @@ conf1_write(struct pci_dev *d, int pos, byte *buf, int len) break; } + /* + * write barrier for data + * Note that we cannot read from data port because it may have side effect. + * Instead we read from address port (which should not have side effect) to + * create a barrier between two conf1_write() calls. But this does not have + * to be 100% correct as it does not ensure barrier on data port itself. + * Correct way is to issue CPU instruction for full hw sync barrier but gcc + * does not provide any (builtin) function yet. + */ + readl(addr); + return 1; } |