Date: Wed, 6 May 2015 14:24:24 -0400 From: Ryan Stone <rysto32@gmail.com> To: John Baldwin <jhb@freebsd.org> Cc: FreeBSD Current <freebsd-current@freebsd.org>, Eric Badger <eric_badger@dell.com>, "current@freebsd.org" <current@freebsd.org> Subject: Re: PCI PF memory decode disable when sizing VF BARs Message-ID: <CAFMmRNyUiet0O2WXBv1K%2BTF=qtQT7Tdwf4npcCNKZiF4SZVh8w@mail.gmail.com> In-Reply-To: <11092809.7nmbPfKl0V@ralph.baldwin.cx> References: <cb2ce4e0ff294bcd982c6db87ae64dfb@mspexmb1.Beer.Town> <CAFMmRNyYJPOyvRrFU_pR8dJBsWGCykL1CiPFBHEDCUFte1dSYQ@mail.gmail.com> <11092809.7nmbPfKl0V@ralph.baldwin.cx>
next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, May 6, 2015 at 11:45 AM, John Baldwin <jhb@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 @@ -37,6 +37,7 @@ __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> @@ -62,6 +63,7 @@ __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> @@ -75,6 +77,11 @@ __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); @@ -2647,7 +2654,8 @@ 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 @@ -2677,9 +2685,21 @@ 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 @@ -2701,7 +2721,7 @@ 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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAFMmRNyUiet0O2WXBv1K%2BTF=qtQT7Tdwf4npcCNKZiF4SZVh8w>