On Wed, May 6, 2015 at 11:45 AM, John Baldwin <jhb_at_freebsd.org> wrote: > There are some devices with BARs in non-standard locations. :( If there is > a flag to just disable the VF bar decoding, then ideally we should just be > doing that and leaving the global decoding flag alone while sizing the VF > BAR. > Disabling SR-IOV BAR decoding in this function is currently redundant, as it's already done in pci_iov.c, but I guess to keep the interface sane it makes sense to do it here too. Something like this then? diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index b4c6151..c9d7541 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c _at__at_ -37,6 +37,7 _at__at_ __FBSDID("$FreeBSD$"); #include <sys/module.h> #include <sys/limits.h> #include <sys/linker.h> +#include <sys/nv.h> #include <sys/fcntl.h> #include <sys/conf.h> #include <sys/kernel.h> _at__at_ -62,6 +63,7 _at__at_ __FBSDID("$FreeBSD$"); #include <dev/pci/pcireg.h> #include <dev/pci/pcivar.h> #include <dev/pci/pci_private.h> +#include <dev/pci/pci_iov_private.h> #include <dev/usb/controller/xhcireg.h> #include <dev/usb/controller/ehcireg.h> _at__at_ -75,6 +77,11 _at__at_ __FBSDID("$FreeBSD$"); (((cfg)->hdrtype == PCIM_HDRTYPE_NORMAL && reg == PCIR_BIOS) || \ ((cfg)->hdrtype == PCIM_HDRTYPE_BRIDGE && reg == PCIR_BIOS_1)) +#define PCIR_IS_IOV(cfg, reg) \ + (((cfg)->iov != NULL) && \ + ((reg) >= (cfg)->iov->iov_pos + PCIR_SRIOV_BAR(0)) && \ + ((reg) <= (cfg)->iov->iov_pos + PCIR_SRIOV_BAR(PCIR_MAX_BAR_0))) + static int pci_has_quirk(uint32_t devid, int quirk); static pci_addr_t pci_mapbase(uint64_t mapreg); static const char *pci_maptype(uint64_t mapreg); _at__at_ -2647,7 +2654,8 _at__at_ pci_read_bar(device_t dev, int reg, pci_addr_t *mapp, pci_addr_t *testvalp, struct pci_devinfo *dinfo; pci_addr_t map, testval; int ln2range; - uint16_t cmd; + uint32_t restore_reg; + uint16_t cmd, mask; /* * The device ROM BAR is special. It is always a 32-bit _at__at_ -2677,9 +2685,21 _at__at_ pci_read_bar(device_t dev, int reg, pci_addr_t *mapp, pci_addr_t *testvalp, * determining the BAR's length since we will be placing it in * a weird state. */ - cmd = pci_read_config(dev, PCIR_COMMAND, 2); - pci_write_config(dev, PCIR_COMMAND, - cmd & ~(PCI_BAR_MEM(map) ? PCIM_CMD_MEMEN : PCIM_CMD_PORTEN), 2); +#ifdef PCI_IOV + if (PCIR_IS_IOV(&dinfo->cfg, reg)) { + restore_reg = dinfo->cfg.iov->iov_pos + PCIR_SRIOV_CTL; + cmd = pci_read_config(dev, restore_reg, 2); + pci_write_config(dev, restore_reg, cmd & ~PCIM_SRIOV_VF_MSE, 2); + } else +#endif + { + cmd = pci_read_config(dev, PCIR_COMMAND, 2); + mask = PCI_BAR_MEM(map) ? PCIM_CMD_MEMEN : PCIM_CMD_PORTEN; + pci_write_config(dev, PCIR_COMMAND, cmd & ~mask, 2); + restore_reg = PCIR_COMMAND; + } /* * Determine the BAR's length by writing all 1's. The bottom _at__at_ -2701,7 +2721,7 _at__at_ pci_read_bar(device_t dev, int reg, pci_addr_t *mapp, pci_addr_t *testvalp, pci_write_config(dev, reg, map, 4); if (ln2range == 64) pci_write_config(dev, reg + 4, map >> 32, 4); - pci_write_config(dev, PCIR_COMMAND, cmd, 2); + pci_write_config(dev, restore_reg, cmd, 2); *mapp = map; *testvalp = testval;Received on Wed May 06 2015 - 16:24:26 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:57 UTC