From 4fe0395550aeb6709ea5332f46de3644aef7d328 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 9 Jan 2017 21:37:40 +0100 Subject: PCI/MSI: Remove pci_enable_msi_{exact,range}() All multi-MSI allocations are now done through pci_irq_alloc_vectors(), so remove the old pci_enable_msi_range() and pci_enable_msi_exact() interfaces. Signed-off-by: Christoph Hellwig Signed-off-by: Bjorn Helgaas --- include/linux/pci.h | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index e2d1a124216a..2159376dc673 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1309,14 +1309,7 @@ void pci_msix_shutdown(struct pci_dev *dev); void pci_disable_msix(struct pci_dev *dev); void pci_restore_msi_state(struct pci_dev *dev); int pci_msi_enabled(void); -int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec); -static inline int pci_enable_msi_exact(struct pci_dev *dev, int nvec) -{ - int rc = pci_enable_msi_range(dev, nvec, nvec); - if (rc < 0) - return rc; - return 0; -} +int pci_enable_msi(struct pci_dev *dev); int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, int minvec, int maxvec); static inline int pci_enable_msix_exact(struct pci_dev *dev, @@ -1347,10 +1340,7 @@ static inline void pci_msix_shutdown(struct pci_dev *dev) { } static inline void pci_disable_msix(struct pci_dev *dev) { } static inline void pci_restore_msi_state(struct pci_dev *dev) { } static inline int pci_msi_enabled(void) { return 0; } -static inline int pci_enable_msi_range(struct pci_dev *dev, int minvec, - int maxvec) -{ return -ENOSYS; } -static inline int pci_enable_msi_exact(struct pci_dev *dev, int nvec) +static inline int pci_enable_msi(struct pci_dev *dev) { return -ENOSYS; } static inline int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, int minvec, int maxvec) @@ -1426,8 +1416,6 @@ static inline void pcie_set_ecrc_checking(struct pci_dev *dev) { } static inline void pcie_ecrc_get_policy(char *str) { } #endif -#define pci_enable_msi(pdev) pci_enable_msi_exact(pdev, 1) - #ifdef CONFIG_HT_IRQ /* The functions a driver should call */ int ht_create_irq(struct pci_dev *dev, int idx); -- cgit v1.2.3 From 72f2ff0deb870145a5a2d24cd75b4f9936159a62 Mon Sep 17 00:00:00 2001 From: Dongdong Liu Date: Fri, 3 Feb 2017 15:02:07 -0600 Subject: PCI: Disable MSI for HiSilicon Hip06/Hip07 Root Ports The PCIe Root Port in Hip06/Hip07 SoCs advertises an MSI capability, but it cannot generate MSIs. It can transfer MSI/MSI-X from downstream devices, but does not support MSI/MSI-X itself. Add a quirk to prevent use of MSI/MSI-X by the Root Port. [bhelgaas: changelog, sort vendor ID #define, drop device ID #define] Signed-off-by: Dongdong Liu Signed-off-by: Bjorn Helgaas Reviewed-by: Gabriele Paoloni Reviewed-by: Zhou Wang --- drivers/pci/quirks.c | 1 + include/linux/pci_ids.h | 2 ++ 2 files changed, 3 insertions(+) (limited to 'include/linux') diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 1800befa8b8b..c49ac99bda4b 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -1634,6 +1634,7 @@ static void quirk_pcie_mch(struct pci_dev *pdev) DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, quirk_pcie_mch); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, quirk_pcie_mch); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quirk_pcie_mch); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_HUAWEI, 0x1610, quirk_pcie_mch); /* diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 73dda0edcb97..a4f77feecbb0 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2516,6 +2516,8 @@ #define PCI_DEVICE_ID_KORENIX_JETCARDF2 0x1700 #define PCI_DEVICE_ID_KORENIX_JETCARDF3 0x17ff +#define PCI_VENDOR_ID_HUAWEI 0x19e5 + #define PCI_VENDOR_ID_NETRONOME 0x19ee #define PCI_DEVICE_ID_NETRONOME_NFP3200 0x3200 #define PCI_DEVICE_ID_NETRONOME_NFP3240 0x3240 -- cgit v1.2.3 From 2fd260f03b6a365bad48522f3948463928f91c2c Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 24 Jan 2017 19:35:56 +0200 Subject: PCI/AER: Remove unused .link_reset() callback No hardware seems to actually call .link_reset(), and no driver implements it as more than a nop stub. Drop mentions of the callback from everywhere. It's dropped from the documentation as well, but the doc really needs to be updated to reflect reality better (e.g., on PCIe, slot reset is the link reset). This will be done in a later patch. Signed-off-by: Michael S. Tsirkin Signed-off-by: Bjorn Helgaas --- Documentation/PCI/pci-error-recovery.txt | 24 +++--------------------- drivers/infiniband/hw/hfi1/pcie.c | 10 ---------- drivers/infiniband/hw/qib/qib_pcie.c | 8 -------- drivers/media/pci/ngene/ngene-cards.c | 7 ------- drivers/misc/genwqe/card_base.c | 1 - include/linux/pci.h | 3 --- 6 files changed, 3 insertions(+), 50 deletions(-) (limited to 'include/linux') diff --git a/Documentation/PCI/pci-error-recovery.txt b/Documentation/PCI/pci-error-recovery.txt index ac26869c7db4..da3b2176d5da 100644 --- a/Documentation/PCI/pci-error-recovery.txt +++ b/Documentation/PCI/pci-error-recovery.txt @@ -78,7 +78,6 @@ struct pci_error_handlers { int (*error_detected)(struct pci_dev *dev, enum pci_channel_state); int (*mmio_enabled)(struct pci_dev *dev); - int (*link_reset)(struct pci_dev *dev); int (*slot_reset)(struct pci_dev *dev); void (*resume)(struct pci_dev *dev); }; @@ -104,8 +103,7 @@ if it implements any, it must implement error_detected(). If a callback is not implemented, the corresponding feature is considered unsupported. For example, if mmio_enabled() and resume() aren't there, then it is assumed that the driver is not doing any direct recovery and requires -a slot reset. If link_reset() is not implemented, the card is assumed to -not care about link resets. Typically a driver will want to know about +a slot reset. Typically a driver will want to know about a slot_reset(). The actual steps taken by a platform to recover from a PCI error @@ -232,25 +230,9 @@ proceeds to STEP 4 (Slot Reset) STEP 3: Link Reset ------------------ -The platform resets the link, and then calls the link_reset() callback -on all affected device drivers. This is a PCI-Express specific state +The platform resets the link. This is a PCI-Express specific step and is done whenever a non-fatal error has been detected that can be -"solved" by resetting the link. This call informs the driver of the -reset and the driver should check to see if the device appears to be -in working condition. - -The driver is not supposed to restart normal driver I/O operations -at this point. It should limit itself to "probing" the device to -check its recoverability status. If all is right, then the platform -will call resume() once all drivers have ack'd link_reset(). - - Result codes: - (identical to STEP 3 (MMIO Enabled) - -The platform then proceeds to either STEP 4 (Slot Reset) or STEP 5 -(Resume Operations). - ->>> The current powerpc implementation does not implement this callback. +"solved" by resetting the link. STEP 4: Slot Reset ------------------ diff --git a/drivers/infiniband/hw/hfi1/pcie.c b/drivers/infiniband/hw/hfi1/pcie.c index 4ac8f330c5cb..ebd941fc8a92 100644 --- a/drivers/infiniband/hw/hfi1/pcie.c +++ b/drivers/infiniband/hw/hfi1/pcie.c @@ -598,15 +598,6 @@ pci_slot_reset(struct pci_dev *pdev) return PCI_ERS_RESULT_CAN_RECOVER; } -static pci_ers_result_t -pci_link_reset(struct pci_dev *pdev) -{ - struct hfi1_devdata *dd = pci_get_drvdata(pdev); - - dd_dev_info(dd, "HFI1 link_reset function called, ignored\n"); - return PCI_ERS_RESULT_CAN_RECOVER; -} - static void pci_resume(struct pci_dev *pdev) { @@ -625,7 +616,6 @@ pci_resume(struct pci_dev *pdev) const struct pci_error_handlers hfi1_pci_err_handler = { .error_detected = pci_error_detected, .mmio_enabled = pci_mmio_enabled, - .link_reset = pci_link_reset, .slot_reset = pci_slot_reset, .resume = pci_resume, }; diff --git a/drivers/infiniband/hw/qib/qib_pcie.c b/drivers/infiniband/hw/qib/qib_pcie.c index 6abe1c621aa4..c379b8342a09 100644 --- a/drivers/infiniband/hw/qib/qib_pcie.c +++ b/drivers/infiniband/hw/qib/qib_pcie.c @@ -682,13 +682,6 @@ qib_pci_slot_reset(struct pci_dev *pdev) return PCI_ERS_RESULT_CAN_RECOVER; } -static pci_ers_result_t -qib_pci_link_reset(struct pci_dev *pdev) -{ - qib_devinfo(pdev, "QIB link_reset function called, ignored\n"); - return PCI_ERS_RESULT_CAN_RECOVER; -} - static void qib_pci_resume(struct pci_dev *pdev) { @@ -707,7 +700,6 @@ qib_pci_resume(struct pci_dev *pdev) const struct pci_error_handlers qib_pci_err_handler = { .error_detected = qib_pci_error_detected, .mmio_enabled = qib_pci_mmio_enabled, - .link_reset = qib_pci_link_reset, .slot_reset = qib_pci_slot_reset, .resume = qib_pci_resume, }; diff --git a/drivers/media/pci/ngene/ngene-cards.c b/drivers/media/pci/ngene/ngene-cards.c index 423e8c889310..8438c1c8acde 100644 --- a/drivers/media/pci/ngene/ngene-cards.c +++ b/drivers/media/pci/ngene/ngene-cards.c @@ -781,12 +781,6 @@ static pci_ers_result_t ngene_error_detected(struct pci_dev *dev, return PCI_ERS_RESULT_CAN_RECOVER; } -static pci_ers_result_t ngene_link_reset(struct pci_dev *dev) -{ - printk(KERN_INFO DEVICE_NAME ": link reset\n"); - return 0; -} - static pci_ers_result_t ngene_slot_reset(struct pci_dev *dev) { printk(KERN_INFO DEVICE_NAME ": slot reset\n"); @@ -800,7 +794,6 @@ static void ngene_resume(struct pci_dev *dev) static const struct pci_error_handlers ngene_errors = { .error_detected = ngene_error_detected, - .link_reset = ngene_link_reset, .slot_reset = ngene_slot_reset, .resume = ngene_resume, }; diff --git a/drivers/misc/genwqe/card_base.c b/drivers/misc/genwqe/card_base.c index 6c1f49a85023..4fd21e86ad56 100644 --- a/drivers/misc/genwqe/card_base.c +++ b/drivers/misc/genwqe/card_base.c @@ -1336,7 +1336,6 @@ static int genwqe_sriov_configure(struct pci_dev *dev, int numvfs) static struct pci_error_handlers genwqe_err_handler = { .error_detected = genwqe_err_error_detected, .mmio_enabled = genwqe_err_result_none, - .link_reset = genwqe_err_result_none, .slot_reset = genwqe_err_slot_reset, .resume = genwqe_err_resume, }; diff --git a/include/linux/pci.h b/include/linux/pci.h index e2d1a124216a..2c0158b4dbed 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -678,9 +678,6 @@ struct pci_error_handlers { /* MMIO has been re-enabled, but not DMA */ pci_ers_result_t (*mmio_enabled)(struct pci_dev *dev); - /* PCI Express link has been reset */ - pci_ers_result_t (*link_reset)(struct pci_dev *dev); - /* PCI slot has been reset */ pci_ers_result_t (*slot_reset)(struct pci_dev *dev); -- cgit v1.2.3 From 47feb41888bc82ba5c9268c344775adc483d6de7 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 8 Feb 2017 18:17:43 +0100 Subject: PCI/MSI: Remove unused pci_msi_create_default_irq_domain() pci_msi_create_default_irq_domain() is never called in the whole tree, so remove it as well as all the supporting code for a default PCI MSI domain. Signed-off-by: Christoph Hellwig Signed-off-by: Bjorn Helgaas Reviewed-by: Thomas Gleixner --- drivers/pci/msi.c | 50 ++------------------------------------------------ include/linux/msi.h | 3 --- 2 files changed, 2 insertions(+), 51 deletions(-) (limited to 'include/linux') diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 0f77b38f03dd..79f20e4cb7bf 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -32,30 +32,11 @@ int pci_msi_ignore_mask; #define msix_table_size(flags) ((flags & PCI_MSIX_FLAGS_QSIZE) + 1) #ifdef CONFIG_PCI_MSI_IRQ_DOMAIN -static struct irq_domain *pci_msi_default_domain; -static DEFINE_MUTEX(pci_msi_domain_lock); - -struct irq_domain * __weak arch_get_pci_msi_domain(struct pci_dev *dev) -{ - return pci_msi_default_domain; -} - -static struct irq_domain *pci_msi_get_domain(struct pci_dev *dev) -{ - struct irq_domain *domain; - - domain = dev_get_msi_domain(&dev->dev); - if (domain) - return domain; - - return arch_get_pci_msi_domain(dev); -} - static int pci_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) { struct irq_domain *domain; - domain = pci_msi_get_domain(dev); + domain = dev_get_msi_domain(&dev->dev); if (domain && irq_domain_is_hierarchy(domain)) return pci_msi_domain_alloc_irqs(domain, dev, nvec, type); @@ -66,7 +47,7 @@ static void pci_msi_teardown_msi_irqs(struct pci_dev *dev) { struct irq_domain *domain; - domain = pci_msi_get_domain(dev); + domain = dev_get_msi_domain(&dev->dev); if (domain && irq_domain_is_hierarchy(domain)) pci_msi_domain_free_irqs(domain, dev); else @@ -1499,33 +1480,6 @@ void pci_msi_domain_free_irqs(struct irq_domain *domain, struct pci_dev *dev) msi_domain_free_irqs(domain, &dev->dev); } -/** - * pci_msi_create_default_irq_domain - Create a default MSI interrupt domain - * @fwnode: Optional fwnode of the interrupt controller - * @info: MSI domain info - * @parent: Parent irq domain - * - * Returns: A domain pointer or NULL in case of failure. If successful - * the default PCI/MSI irqdomain pointer is updated. - */ -struct irq_domain *pci_msi_create_default_irq_domain(struct fwnode_handle *fwnode, - struct msi_domain_info *info, struct irq_domain *parent) -{ - struct irq_domain *domain; - - mutex_lock(&pci_msi_domain_lock); - if (pci_msi_default_domain) { - pr_err("PCI: default irq domain for PCI MSI has already been created.\n"); - domain = NULL; - } else { - domain = pci_msi_create_irq_domain(fwnode, info, parent); - pci_msi_default_domain = domain; - } - mutex_unlock(&pci_msi_domain_lock); - - return domain; -} - static int get_msi_id_cb(struct pci_dev *pdev, u16 alias, void *data) { u32 *pa = data; diff --git a/include/linux/msi.h b/include/linux/msi.h index 0db320b7bb15..18b8566b3ce3 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -319,9 +319,6 @@ struct irq_domain *pci_msi_create_irq_domain(struct fwnode_handle *fwnode, int pci_msi_domain_alloc_irqs(struct irq_domain *domain, struct pci_dev *dev, int nvec, int type); void pci_msi_domain_free_irqs(struct irq_domain *domain, struct pci_dev *dev); -struct irq_domain *pci_msi_create_default_irq_domain(struct fwnode_handle *fwnode, - struct msi_domain_info *info, struct irq_domain *parent); - irq_hw_number_t pci_msi_domain_calc_hwirq(struct pci_dev *dev, struct msi_desc *desc); int pci_msi_domain_check_cap(struct irq_domain *domain, -- cgit v1.2.3 From 699c4cec238731a4c466f73fe6e9e45ab6f49a41 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 8 Feb 2017 18:17:44 +0100 Subject: PCI/MSI: Remove pci_msi_domain_{alloc,free}_irqs() Just call the msi_* version directly instead of having trivial wrappers for one or two callsites. Signed-off-by: Christoph Hellwig Signed-off-by: Bjorn Helgaas Reviewed-by: Thomas Gleixner --- arch/x86/kernel/apic/msi.c | 2 +- drivers/pci/msi.c | 30 ++---------------------------- include/linux/msi.h | 3 --- 3 files changed, 3 insertions(+), 32 deletions(-) (limited to 'include/linux') diff --git a/arch/x86/kernel/apic/msi.c b/arch/x86/kernel/apic/msi.c index 015bbf30e3e3..c61aec7e65f4 100644 --- a/arch/x86/kernel/apic/msi.c +++ b/arch/x86/kernel/apic/msi.c @@ -82,7 +82,7 @@ int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) if (domain == NULL) return -ENOSYS; - return pci_msi_domain_alloc_irqs(domain, dev, nvec, type); + return msi_domain_alloc_irqs(domain, &dev->dev, nvec); } void native_teardown_msi_irq(unsigned int irq) diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 79f20e4cb7bf..b44ad7c21b29 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -38,7 +38,7 @@ static int pci_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) domain = dev_get_msi_domain(&dev->dev); if (domain && irq_domain_is_hierarchy(domain)) - return pci_msi_domain_alloc_irqs(domain, dev, nvec, type); + return msi_domain_alloc_irqs(domain, &dev->dev, nvec); return arch_setup_msi_irqs(dev, nvec, type); } @@ -49,7 +49,7 @@ static void pci_msi_teardown_msi_irqs(struct pci_dev *dev) domain = dev_get_msi_domain(&dev->dev); if (domain && irq_domain_is_hierarchy(domain)) - pci_msi_domain_free_irqs(domain, dev); + msi_domain_free_irqs(domain, &dev->dev); else arch_teardown_msi_irqs(dev); } @@ -1454,32 +1454,6 @@ struct irq_domain *pci_msi_create_irq_domain(struct fwnode_handle *fwnode, } EXPORT_SYMBOL_GPL(pci_msi_create_irq_domain); -/** - * pci_msi_domain_alloc_irqs - Allocate interrupts for @dev in @domain - * @domain: The interrupt domain to allocate from - * @dev: The device for which to allocate - * @nvec: The number of interrupts to allocate - * @type: Unused to allow simpler migration from the arch_XXX interfaces - * - * Returns: - * A virtual interrupt number or an error code in case of failure - */ -int pci_msi_domain_alloc_irqs(struct irq_domain *domain, struct pci_dev *dev, - int nvec, int type) -{ - return msi_domain_alloc_irqs(domain, &dev->dev, nvec); -} - -/** - * pci_msi_domain_free_irqs - Free interrupts for @dev in @domain - * @domain: The interrupt domain - * @dev: The device for which to free interrupts - */ -void pci_msi_domain_free_irqs(struct irq_domain *domain, struct pci_dev *dev) -{ - msi_domain_free_irqs(domain, &dev->dev); -} - static int get_msi_id_cb(struct pci_dev *pdev, u16 alias, void *data) { u32 *pa = data; diff --git a/include/linux/msi.h b/include/linux/msi.h index 18b8566b3ce3..1b6f3ebbe876 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -316,9 +316,6 @@ void pci_msi_domain_write_msg(struct irq_data *irq_data, struct msi_msg *msg); struct irq_domain *pci_msi_create_irq_domain(struct fwnode_handle *fwnode, struct msi_domain_info *info, struct irq_domain *parent); -int pci_msi_domain_alloc_irqs(struct irq_domain *domain, struct pci_dev *dev, - int nvec, int type); -void pci_msi_domain_free_irqs(struct irq_domain *domain, struct pci_dev *dev); irq_hw_number_t pci_msi_domain_calc_hwirq(struct pci_dev *dev, struct msi_desc *desc); int pci_msi_domain_check_cap(struct irq_domain *domain, -- cgit v1.2.3