Re: [virtio-dev] [RFC PATCH V2] virtio_pci: Add SR-IOV support
> On Feb 25, 2018, at 7:20 AM, Yan Vugenfirerwrote: > > Small mistake in the commit message. Red Hat (Qumranet) vendor ID is 1af4, > virtio-net device ID is 1041. > Should be: > PF: vendor: 1af4 device: 1041 subvendor: 8086 subdevice: 15fe > VF: vendor: 1af4 device: 1041 subvendor: 8086 subdevice: 05fe You are so right. I will fix it before I send the updated patch that provides the generic helper that Christoph suggested. Thanks for catching my mislabeling. -- Mark Rustad, mrus...@gmail.com signature.asc Description: Message signed with OpenPGP
Re: [Intel-wired-lan] [PATCH] e1000e: prevent division by zero if TIMINCA is zero
Jarod Wilsonwrote: On Fri, May 06, 2016 at 11:43:17PM +, Rustad, Mark D wrote: Denys Vlasenko wrote: Users report that under VMWare, er32(TIMINCA) returns zero. This causes division by zero at init time as follows: ==>incvalue = er32(TIMINCA) & E1000_TIMINCA_INCVALUE_MASK; for (i = 0; i < E1000_MAX_82574_SYSTIM_REREADS; i++) { /* latch SYSTIMH on read of SYSTIML */ systim_next = (cycle_t)er32(SYSTIML); systim_next |= (cycle_t)er32(SYSTIMH) << 32; time_delta = systim_next - systim; temp = time_delta; > rem = do_div(temp, incvalue); This change makes kernel survive this, and users report that NIC does work after this change. Since on real hardware incvalue is never zero, this should not affect real hardware use case. ... I seem to recall that this was rejected before because it really is VMWare's bug and, if they fix it, any existing VMs that use this will just work. Changing the driver will only fix it for vms that install a new driver. I don't object to doing it, it just seems like not the most effective place to address the issue. You could also have people who never update VMWare, for whom a kernel work-around would be better. I think it'd be best to address it both at the driver level and the emulated hardware level, to improve things for the most possible users. Those who update neither hypervisor or kernel/driver, well, they reap what they sow. That is a sound argument for doing both. I would expect that there are more frozen VM images than host environments, but I can certainly imagine that some choose to freeze their host. Of course if everything is frozen there is no point at all. :-) I am on an extended vacation, and don't work on e1000e anyway, so I will quit my kibitzing here. -- Mark Rustad, mrus...@gmail.com signature.asc Description: Message signed with OpenPGP using GPGMail
[PATCH V4 1/2] pci: Add dev_flags bit to access VPD through function 0
From: Mark Rustad mark.d.rus...@intel.com Add a dev_flags bit, PCI_DEV_FLAGS_VPD_REF_F0, to access VPD through function 0 to provide VPD access on other functions. This is for hardware devices that provide copies of the same VPD capability registers in multiple functions. Because the kernel expects that each function has its own registers, both the locking and the state tracking are affected by VPD accesses to different functions. On such devices for example, if a VPD write is performed on function 0, *any* later attempt to read VPD from any other function of that device will hang. This has to do with how the kernel tracks the expected value of the F bit per function. Concurrent accesses to different functions of the same device can not only hang but also corrupt both read and write VPD data. When hangs occur, typically the error message: vpd r/w failed. This is likely a firmware bug on this device. will be seen. Never set this bit on function 0 or there will be an infinite recursion. Signed-off-by: Mark Rustad mark.d.rus...@intel.com --- Changes in V2: - Corrected spelling in log message - Added checks to see that the referenced function 0 is reasonable Changes in V3: - Don't leak a device reference - Check that function 0 has VPD - Make a helper for the function 0 checks - Do multifunction check in the quirk Changes in V4: - Provide a much more detailed explanation in the commit log --- drivers/pci/access.c | 61 +- include/linux/pci.h |2 ++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/drivers/pci/access.c b/drivers/pci/access.c index d9b64a175990..b965c12168b7 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c @@ -439,6 +439,56 @@ static const struct pci_vpd_ops pci_vpd_pci22_ops = { .release = pci_vpd_pci22_release, }; +static ssize_t pci_vpd_f0_read(struct pci_dev *dev, loff_t pos, size_t count, + void *arg) +{ + struct pci_dev *tdev = pci_get_slot(dev-bus, PCI_SLOT(dev-devfn)); + ssize_t ret; + + if (!tdev) + return -ENODEV; + + ret = pci_read_vpd(tdev, pos, count, arg); + pci_dev_put(tdev); + return ret; +} + +static ssize_t pci_vpd_f0_write(struct pci_dev *dev, loff_t pos, size_t count, + const void *arg) +{ + struct pci_dev *tdev = pci_get_slot(dev-bus, PCI_SLOT(dev-devfn)); + ssize_t ret; + + if (!tdev) + return -ENODEV; + + ret = pci_write_vpd(tdev, pos, count, arg); + pci_dev_put(tdev); + return ret; +} + +static const struct pci_vpd_ops pci_vpd_f0_ops = { + .read = pci_vpd_f0_read, + .write = pci_vpd_f0_write, + .release = pci_vpd_pci22_release, +}; + +static int pci_vpd_f0_dev_check(struct pci_dev *dev) +{ + struct pci_dev *tdev = pci_get_slot(dev-bus, PCI_SLOT(dev-devfn)); + int ret = 0; + + if (!tdev) + return -ENODEV; + if (!tdev-vpd || !tdev-multifunction || + dev-class != tdev-class || dev-vendor != tdev-vendor || + dev-device != tdev-device) + ret = -ENODEV; + + pci_dev_put(tdev); + return ret; +} + int pci_vpd_pci22_init(struct pci_dev *dev) { struct pci_vpd_pci22 *vpd; @@ -447,12 +497,21 @@ int pci_vpd_pci22_init(struct pci_dev *dev) cap = pci_find_capability(dev, PCI_CAP_ID_VPD); if (!cap) return -ENODEV; + if (dev-dev_flags PCI_DEV_FLAGS_VPD_REF_F0) { + int ret = pci_vpd_f0_dev_check(dev); + + if (ret) + return ret; + } vpd = kzalloc(sizeof(*vpd), GFP_ATOMIC); if (!vpd) return -ENOMEM; vpd-base.len = PCI_VPD_PCI22_SIZE; - vpd-base.ops = pci_vpd_pci22_ops; + if (dev-dev_flags PCI_DEV_FLAGS_VPD_REF_F0) + vpd-base.ops = pci_vpd_f0_ops; + else + vpd-base.ops = pci_vpd_pci22_ops; mutex_init(vpd-lock); vpd-cap = cap; vpd-busy = false; diff --git a/include/linux/pci.h b/include/linux/pci.h index 8a0321a8fb59..8edb125db13a 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -180,6 +180,8 @@ enum pci_dev_flags { PCI_DEV_FLAGS_NO_BUS_RESET = (__force pci_dev_flags_t) (1 6), /* Do not use PM reset even if device advertises NoSoftRst- */ PCI_DEV_FLAGS_NO_PM_RESET = (__force pci_dev_flags_t) (1 7), + /* Get VPD from function 0 VPD */ + PCI_DEV_FLAGS_VPD_REF_F0 = (__force pci_dev_flags_t) (1 8), }; enum pci_irq_reroute_variant { -- To unsubscribe from this list: send the line unsubscribe netdev in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V4 2/2] pci: Add VPD quirk for Intel Ethernet devices
From: Mark Rustad mark.d.rus...@intel.com This quirk sets the PCI_DEV_FLAGS_VPD_REF_F0 flag on all Intel Ethernet device functions other than function 0. Signed-off-by: Mark Rustad mark.d.rus...@intel.com --- Changes in V3: - Added a multifunction device check --- drivers/pci/quirks.c |9 + 1 file changed, 9 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index e9fd0e90fa3b..08c04e4f5ab2 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -1894,6 +1894,15 @@ static void quirk_netmos(struct pci_dev *dev) DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID, PCI_CLASS_COMMUNICATION_SERIAL, 8, quirk_netmos); +static void quirk_f0_vpd_link(struct pci_dev *dev) +{ + if (!dev-multifunction || !PCI_FUNC(dev-devfn)) + return; + dev-dev_flags |= PCI_DEV_FLAGS_VPD_REF_F0; +} +DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, + PCI_CLASS_NETWORK_ETHERNET, 8, quirk_f0_vpd_link); + static void quirk_e100_interrupt(struct pci_dev *dev) { u16 command, pmcsr; -- To unsubscribe from this list: send the line unsubscribe netdev in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V4 0/2] pci: Provide a flag to access VPD through function 0
Many multi-function devices provide shared registers in extended config space for accessing VPD. The behavior of these registers means that the state must be tracked and access locked correctly for accesses not to hang or worse. One way to meet these needs is to always perform the accesses through function 0, thereby using the state tracking and mutex that already exists. To provide this behavior, add a dev_flags bit to indicate that this should be done. This bit can then be set for any non-zero function that needs to redirect such VPD access to function 0. Do not set this bit on the zero function or there will be an infinite recursion. The second patch uses this new flag to invoke this behavior on all multi-function Intel Ethernet devices. Any hardware that shares VPD registers with multiple functions has been suffering these problems forever. The hangs result in the log message: vpd r/w failed. This is likely a firmware bug on this device. Both read and write data corruption are also possible during overlapping accesses in addition to hangs. Signed-off-by: Mark Rustad mark.d.rus...@intel.com --- Changes in V2: - Corrected a spelling error in a log message - Added checks to see that the referenced function 0 is reasonable Changes in V3: - Don't leak a device reference - Check that function 0 has VPD - Make a helper for the function 0 checks - Moved a multifunction check to the quirk patch Changes in V4: - Provide a more extensive commit log for patch 1 --- Mark Rustad (2): pci: Add dev_flags bit to access VPD through function 0 pci: Add VPD quirk for Intel Ethernet devices drivers/pci/access.c | 61 +- drivers/pci/quirks.c |9 +++ include/linux/pci.h |2 ++ 3 files changed, 71 insertions(+), 1 deletion(-) -- Mark Rustad, Network Division, Intel Corporation -- To unsubscribe from this list: send the line unsubscribe netdev in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V3 2/2] pci: Add VPD quirk for Intel Ethernet devices
This quirk sets the PCI_DEV_FLAGS_VPD_REF_F0 flag on all Intel Ethernet device functions other than function 0. Signed-off-by: Mark Rustad mark.d.rus...@intel.com --- Changes in V3: - Added a multifunction device check --- drivers/pci/quirks.c |9 + 1 file changed, 9 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index c6dc1dfd25d5..1d6d848b66f9 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -1903,6 +1903,15 @@ static void quirk_netmos(struct pci_dev *dev) DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID, PCI_CLASS_COMMUNICATION_SERIAL, 8, quirk_netmos); +static void quirk_f0_vpd_link(struct pci_dev *dev) +{ + if (!dev-multifunction || !PCI_FUNC(dev-devfn)) + return; + dev-dev_flags |= PCI_DEV_FLAGS_VPD_REF_F0; +} +DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, + PCI_CLASS_NETWORK_ETHERNET, 8, quirk_f0_vpd_link); + static void quirk_e100_interrupt(struct pci_dev *dev) { u16 command, pmcsr; -- To unsubscribe from this list: send the line unsubscribe netdev in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V3 1/2] pci: Add dev_flags bit to access VPD through function 0
Add a dev_flags bit, PCI_DEV_FLAGS_VPD_REF_F0, to access VPD through function 0 to provide VPD access on other functions. This solves concurrent access problems on many devices without changing the attributes exposed in sysfs. Never set this bit on function 0 or there will be an infinite recursion. Signed-off-by: Mark Rustad mark.d.rus...@intel.com --- Changes in V2: - Corrected spelling in log message - Added checks to see that the referenced function 0 is reasonable Changes in V3: - Don't leak a device reference - Check that function 0 has VPD - Make a helper for the function 0 checks - Do multifunction check in the quirk --- drivers/pci/access.c | 61 +- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/drivers/pci/access.c b/drivers/pci/access.c index d9b64a175990..b965c12168b7 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c @@ -439,6 +439,56 @@ static const struct pci_vpd_ops pci_vpd_pci22_ops = { .release = pci_vpd_pci22_release, }; +static ssize_t pci_vpd_f0_read(struct pci_dev *dev, loff_t pos, size_t count, + void *arg) +{ + struct pci_dev *tdev = pci_get_slot(dev-bus, PCI_SLOT(dev-devfn)); + ssize_t ret; + + if (!tdev) + return -ENODEV; + + ret = pci_read_vpd(tdev, pos, count, arg); + pci_dev_put(tdev); + return ret; +} + +static ssize_t pci_vpd_f0_write(struct pci_dev *dev, loff_t pos, size_t count, + const void *arg) +{ + struct pci_dev *tdev = pci_get_slot(dev-bus, PCI_SLOT(dev-devfn)); + ssize_t ret; + + if (!tdev) + return -ENODEV; + + ret = pci_write_vpd(tdev, pos, count, arg); + pci_dev_put(tdev); + return ret; +} + +static const struct pci_vpd_ops pci_vpd_f0_ops = { + .read = pci_vpd_f0_read, + .write = pci_vpd_f0_write, + .release = pci_vpd_pci22_release, +}; + +static int pci_vpd_f0_dev_check(struct pci_dev *dev) +{ + struct pci_dev *tdev = pci_get_slot(dev-bus, PCI_SLOT(dev-devfn)); + int ret = 0; + + if (!tdev) + return -ENODEV; + if (!tdev-vpd || !tdev-multifunction || + dev-class != tdev-class || dev-vendor != tdev-vendor || + dev-device != tdev-device) + ret = -ENODEV; + + pci_dev_put(tdev); + return ret; +} + int pci_vpd_pci22_init(struct pci_dev *dev) { struct pci_vpd_pci22 *vpd; @@ -447,12 +497,21 @@ int pci_vpd_pci22_init(struct pci_dev *dev) cap = pci_find_capability(dev, PCI_CAP_ID_VPD); if (!cap) return -ENODEV; + if (dev-dev_flags PCI_DEV_FLAGS_VPD_REF_F0) { + int ret = pci_vpd_f0_dev_check(dev); + + if (ret) + return ret; + } vpd = kzalloc(sizeof(*vpd), GFP_ATOMIC); if (!vpd) return -ENOMEM; vpd-base.len = PCI_VPD_PCI22_SIZE; - vpd-base.ops = pci_vpd_pci22_ops; + if (dev-dev_flags PCI_DEV_FLAGS_VPD_REF_F0) + vpd-base.ops = pci_vpd_f0_ops; + else + vpd-base.ops = pci_vpd_pci22_ops; mutex_init(vpd-lock); vpd-cap = cap; vpd-busy = false; diff --git a/include/linux/pci.h b/include/linux/pci.h index 353db8dc4c6e..194df6d635e6 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -180,6 +180,8 @@ enum pci_dev_flags { PCI_DEV_FLAGS_NO_BUS_RESET = (__force pci_dev_flags_t) (1 6), /* Do not use PM reset even if device advertises NoSoftRst- */ PCI_DEV_FLAGS_NO_PM_RESET = (__force pci_dev_flags_t) (1 7), + /* Get VPD from function 0 VPD */ + PCI_DEV_FLAGS_VPD_REF_F0 = (__force pci_dev_flags_t) (1 8), }; enum pci_irq_reroute_variant { -- To unsubscribe from this list: send the line unsubscribe netdev in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V3 0/2] pci: Provide a flag to access VPD through function 0
Many multi-function devices provide shared registers in extended config space for accessing VPD. The behavior of these registers means that the state must be tracked and access locked correctly for accesses not to hang or worse. One way to meet these needs is to always perform the accesses through function 0, thereby using the state tracking and mutex that already exists. To provide this behavior, add a dev_flags bit to indicate that this should be done. This bit can then be set for any non-zero function that needs to redirect such VPD access to function 0. Do not set this bit on the zero function or there will be an infinite recursion. The second patch uses this new flag to invoke this behavior on all multi-function Intel Ethernet devices. Signed-off-by: Mark Rustad mark.d.rus...@intel.com --- Changes in V2: - Corrected a spelling error in a log message - Added checks to see that the referenced function 0 is reasonable Changes in V3: - Don't leak a device reference - Check that function 0 has VPD - Make a helper for the function 0 checks - Moved a multifunction check to the quirk patch --- Mark D Rustad (2): pci: Add dev_flags bit to access VPD through function 0 pci: Add VPD quirk for Intel Ethernet devices drivers/pci/access.c | 61 +- drivers/pci/quirks.c |9 +++ 2 files changed, 69 insertions(+), 1 deletion(-) -- Mark Rustad, Network Division, Intel Corporation -- To unsubscribe from this list: send the line unsubscribe netdev in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V2 2/2] pci: Add VPD quirk for Intel Ethernet devices
This quirk sets the PCI_DEV_FLAGS_VPD_REF_F0 flag on all Intel Ethernet device functions other than function 0. Signed-off-by: Mark Rustad mark.d.rus...@intel.com --- drivers/pci/quirks.c |9 + 1 file changed, 9 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index c6dc1dfd25d5..9ddf6a533f4f 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -1903,6 +1903,15 @@ static void quirk_netmos(struct pci_dev *dev) DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID, PCI_CLASS_COMMUNICATION_SERIAL, 8, quirk_netmos); +static void quirk_f0_vpd_link(struct pci_dev *dev) +{ + if (!PCI_FUNC(dev-devfn)) + return; + dev-dev_flags |= PCI_DEV_FLAGS_VPD_REF_F0; +} +DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, + PCI_CLASS_NETWORK_ETHERNET, 8, quirk_f0_vpd_link); + static void quirk_e100_interrupt(struct pci_dev *dev) { u16 command, pmcsr; -- To unsubscribe from this list: send the line unsubscribe netdev in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V2 0/2] pci: Provide a flag to access VPD through function 0
Many multi-function devices provide shared registers in extended config space for accessing VPD. The behavior of these registers means that the state must be tracked and access locked correctly for accesses not to hang or worse. One way to meet these needs is to always perform the accesses through function 0, thereby using the state tracking and mutex that already exists. To provide this behavior, add a dev_flags bit to indicate that this should be done. This bit can then be set for any non-zero function that needs to redirect such VPD access to function 0. Do not set this bit on the zero function or there will be an infinite recursion. The second patch uses this new flag to invoke this behavior on all multi-function Intel Ethernet devices. Signed-off-by: Mark Rustad mark.d.rus...@intel.com --- Changes in V2: - Corrected a spelling error in a log message - Added checks to see that the referenced function 0 is reasonable --- Mark D Rustad (2): pci: Add dev_flags bit to access VPD through function 0 pci: Add VPD quirk for Intel Ethernet devices drivers/pci/access.c | 48 +++- drivers/pci/quirks.c |9 + 2 files changed, 56 insertions(+), 1 deletion(-) -- Mark Rustad, Network Division, Intel Corporation -- To unsubscribe from this list: send the line unsubscribe netdev in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V2 1/2] pci: Add dev_flags bit to access VPD through function 0
Add a dev_flags bit, PCI_DEV_FLAGS_VPD_REF_F0, to access VPD through function 0 to provide VPD access on other functions. This solves concurrent access problems on many devices without changing the attributes exposed in sysfs. Never set this bit on function 0 or there will be an infinite recursion. Signed-off-by: Mark Rustad mark.d.rus...@intel.com --- Changes in V2: - Corrected spelling in log message - Added checks to see that the referenced function 0 is reasonable --- drivers/pci/access.c | 48 +++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/drivers/pci/access.c b/drivers/pci/access.c index d9b64a175990..74634d4868a2 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c @@ -439,6 +439,40 @@ static const struct pci_vpd_ops pci_vpd_pci22_ops = { .release = pci_vpd_pci22_release, }; +static ssize_t pci_vpd_f0_read(struct pci_dev *dev, loff_t pos, size_t count, + void *arg) +{ + struct pci_dev *tdev = pci_get_slot(dev-bus, PCI_SLOT(dev-devfn)); + ssize_t ret; + + if (!tdev) + return -ENODEV; + + ret = pci_read_vpd(tdev, pos, count, arg); + pci_dev_put(tdev); + return ret; +} + +static ssize_t pci_vpd_f0_write(struct pci_dev *dev, loff_t pos, size_t count, + const void *arg) +{ + struct pci_dev *tdev = pci_get_slot(dev-bus, PCI_SLOT(dev-devfn)); + ssize_t ret; + + if (!tdev) + return -ENODEV; + + ret = pci_write_vpd(tdev, pos, count, arg); + pci_dev_put(tdev); + return ret; +} + +static const struct pci_vpd_ops pci_vpd_f0_ops = { + .read = pci_vpd_f0_read, + .write = pci_vpd_f0_write, + .release = pci_vpd_pci22_release, +}; + int pci_vpd_pci22_init(struct pci_dev *dev) { struct pci_vpd_pci22 *vpd; @@ -447,12 +481,24 @@ int pci_vpd_pci22_init(struct pci_dev *dev) cap = pci_find_capability(dev, PCI_CAP_ID_VPD); if (!cap) return -ENODEV; + if (dev-dev_flags PCI_DEV_FLAGS_VPD_REF_F0) { + struct pci_dev *tdev; + + tdev = pci_get_slot(dev-bus, PCI_SLOT(dev-devfn)); + if (!tdev || !dev-multifunction || !tdev-multifunction || + dev-class != tdev-class || dev-vendor != tdev-vendor || + dev-device != tdev-device) + return -ENODEV; + } vpd = kzalloc(sizeof(*vpd), GFP_ATOMIC); if (!vpd) return -ENOMEM; vpd-base.len = PCI_VPD_PCI22_SIZE; - vpd-base.ops = pci_vpd_pci22_ops; + if (dev-dev_flags PCI_DEV_FLAGS_VPD_REF_F0) + vpd-base.ops = pci_vpd_f0_ops; + else + vpd-base.ops = pci_vpd_pci22_ops; mutex_init(vpd-lock); vpd-cap = cap; vpd-busy = false; diff --git a/include/linux/pci.h b/include/linux/pci.h index 353db8dc4c6e..194df6d635e6 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -180,6 +180,8 @@ enum pci_dev_flags { PCI_DEV_FLAGS_NO_BUS_RESET = (__force pci_dev_flags_t) (1 6), /* Do not use PM reset even if device advertises NoSoftRst- */ PCI_DEV_FLAGS_NO_PM_RESET = (__force pci_dev_flags_t) (1 7), + /* Get VPD from function 0 VPD */ + PCI_DEV_FLAGS_VPD_REF_F0 = (__force pci_dev_flags_t) (1 8), }; enum pci_irq_reroute_variant { -- To unsubscribe from this list: send the line unsubscribe netdev in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2] pci: Add VPD quirk for Intel Ethernet devices
This quirk sets the PCI_DEV_FLAGS_VPD_REF_F0 flag on all Intel Ethernet device functions other than function 0. Signed-off-by: Mark Rustad mark.d.rus...@intel.com --- drivers/pci/quirks.c |9 + 1 file changed, 9 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index c6dc1dfd25d5..9ddf6a533f4f 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -1903,6 +1903,15 @@ static void quirk_netmos(struct pci_dev *dev) DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID, PCI_CLASS_COMMUNICATION_SERIAL, 8, quirk_netmos); +static void quirk_f0_vpd_link(struct pci_dev *dev) +{ + if (!PCI_FUNC(dev-devfn)) + return; + dev-dev_flags |= PCI_DEV_FLAGS_VPD_REF_F0; +} +DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, + PCI_CLASS_NETWORK_ETHERNET, 8, quirk_f0_vpd_link); + static void quirk_e100_interrupt(struct pci_dev *dev) { u16 command, pmcsr; -- To unsubscribe from this list: send the line unsubscribe netdev in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2] pci: Add dev_flags bit to access VPD through function 0
Add a dev_flags bit, PCI_DEV_FLAGS_VPD_REF_F0, to access VPD through function 0 to provide VPD access on other functions. This solves concurrent access problems on many devices without changing the attributes exposed in sysfs. Never set this bit on funciton 0 or there will be an infinite recursion. Signed-off-by: Mark Rustad mark.d.rus...@intel.com --- drivers/pci/access.c | 39 ++- include/linux/pci.h |2 ++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/drivers/pci/access.c b/drivers/pci/access.c index d9b64a175990..e435c087c354 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c @@ -439,6 +439,40 @@ static const struct pci_vpd_ops pci_vpd_pci22_ops = { .release = pci_vpd_pci22_release, }; +static ssize_t pci_vpd_f0_read(struct pci_dev *dev, loff_t pos, size_t count, + void *arg) +{ + struct pci_dev *tdev = pci_get_slot(dev-bus, PCI_SLOT(dev-devfn)); + ssize_t ret; + + if (!tdev) + return -ENODEV; + + ret = pci_read_vpd(tdev, pos, count, arg); + pci_dev_put(tdev); + return ret; +} + +static ssize_t pci_vpd_f0_write(struct pci_dev *dev, loff_t pos, size_t count, + const void *arg) +{ + struct pci_dev *tdev = pci_get_slot(dev-bus, PCI_SLOT(dev-devfn)); + ssize_t ret; + + if (!tdev) + return -ENODEV; + + ret = pci_write_vpd(tdev, pos, count, arg); + pci_dev_put(tdev); + return ret; +} + +static const struct pci_vpd_ops pci_vpd_f0_ops = { + .read = pci_vpd_f0_read, + .write = pci_vpd_f0_write, + .release = pci_vpd_pci22_release, +}; + int pci_vpd_pci22_init(struct pci_dev *dev) { struct pci_vpd_pci22 *vpd; @@ -452,7 +486,10 @@ int pci_vpd_pci22_init(struct pci_dev *dev) return -ENOMEM; vpd-base.len = PCI_VPD_PCI22_SIZE; - vpd-base.ops = pci_vpd_pci22_ops; + if (dev-dev_flags PCI_DEV_FLAGS_VPD_REF_F0) + vpd-base.ops = pci_vpd_f0_ops; + else + vpd-base.ops = pci_vpd_pci22_ops; mutex_init(vpd-lock); vpd-cap = cap; vpd-busy = false; diff --git a/include/linux/pci.h b/include/linux/pci.h index 353db8dc4c6e..194df6d635e6 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -180,6 +180,8 @@ enum pci_dev_flags { PCI_DEV_FLAGS_NO_BUS_RESET = (__force pci_dev_flags_t) (1 6), /* Do not use PM reset even if device advertises NoSoftRst- */ PCI_DEV_FLAGS_NO_PM_RESET = (__force pci_dev_flags_t) (1 7), + /* Get VPD from function 0 VPD */ + PCI_DEV_FLAGS_VPD_REF_F0 = (__force pci_dev_flags_t) (1 8), }; enum pci_irq_reroute_variant { -- To unsubscribe from this list: send the line unsubscribe netdev in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/2] pci: Provide a flag to access VPD through function 0
Many multi-function devices provide shared registers in extended config space for accessing VPD. The behavior of these registers means that the state must be tracked and access locked correctly for accesses not to hang or worse. One way to meet these needs is to always perform the accesses through function 0, thereby using the state tracking and mutex that already exists. To provide this behavior, add a dev_flags bit to indicate that this should be done. This bit can then be set for any non-zero function that needs to redirect such VPD access to function 0. Do not set this bit on the zero function or there will be an infinite recursion. The second patch uses this new flag to invoke this behavior on all multi-function Intel Ethernet devices. Signed-off-by: Mark Rustad mark.d.rus...@intel.com --- Mark D Rustad (2): pci: Add dev_flags bit to access VPD through function 0 pci: Add VPD quirk for Intel Ethernet devices drivers/pci/access.c | 39 ++- drivers/pci/quirks.c |9 + include/linux/pci.h |2 ++ 3 files changed, 49 insertions(+), 1 deletion(-) -- Mark Rustad, Network Division, Intel Corporation -- To unsubscribe from this list: send the line unsubscribe netdev in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html