aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/quirks.c51
-rw-r--r--include/linux/pci.h8
2 files changed, 59 insertions, 0 deletions
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 2a7521677541..acd3956b44bd 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -3179,3 +3179,54 @@ int pci_dev_specific_reset(struct pci_dev *dev, int probe)
3179 3179
3180 return -ENOTTY; 3180 return -ENOTTY;
3181} 3181}
3182
3183static struct pci_dev *pci_func_0_dma_source(struct pci_dev *dev)
3184{
3185 if (!PCI_FUNC(dev->devfn))
3186 return pci_dev_get(dev);
3187
3188 return pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn), 0));
3189}
3190
3191static const struct pci_dev_dma_source {
3192 u16 vendor;
3193 u16 device;
3194 struct pci_dev *(*dma_source)(struct pci_dev *dev);
3195} pci_dev_dma_source[] = {
3196 /*
3197 * https://bugzilla.redhat.com/show_bug.cgi?id=605888
3198 *
3199 * Some Ricoh devices use the function 0 source ID for DMA on
3200 * other functions of a multifunction device. The DMA devices
3201 * is therefore function 0, which will have implications of the
3202 * iommu grouping of these devices.
3203 */
3204 { PCI_VENDOR_ID_RICOH, 0xe822, pci_func_0_dma_source },
3205 { PCI_VENDOR_ID_RICOH, 0xe230, pci_func_0_dma_source },
3206 { PCI_VENDOR_ID_RICOH, 0xe832, pci_func_0_dma_source },
3207 { PCI_VENDOR_ID_RICOH, 0xe476, pci_func_0_dma_source },
3208 { 0 }
3209};
3210
3211/*
3212 * IOMMUs with isolation capabilities need to be programmed with the
3213 * correct source ID of a device. In most cases, the source ID matches
3214 * the device doing the DMA, but sometimes hardware is broken and will
3215 * tag the DMA as being sourced from a different device. This function
3216 * allows that translation. Note that the reference count of the
3217 * returned device is incremented on all paths.
3218 */
3219struct pci_dev *pci_get_dma_source(struct pci_dev *dev)
3220{
3221 const struct pci_dev_dma_source *i;
3222
3223 for (i = pci_dev_dma_source; i->dma_source; i++) {
3224 if ((i->vendor == dev->vendor ||
3225 i->vendor == (u16)PCI_ANY_ID) &&
3226 (i->device == dev->device ||
3227 i->device == (u16)PCI_ANY_ID))
3228 return i->dma_source(dev);
3229 }
3230
3231 return pci_dev_get(dev);
3232}
diff --git a/include/linux/pci.h b/include/linux/pci.h
index d8c379dba6ad..39983be7b25b 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1332,6 +1332,9 @@ static inline struct pci_dev *pci_get_bus_and_slot(unsigned int bus,
1332static inline int pci_domain_nr(struct pci_bus *bus) 1332static inline int pci_domain_nr(struct pci_bus *bus)
1333{ return 0; } 1333{ return 0; }
1334 1334
1335static inline struct pci_dev *pci_dev_get(struct pci_dev *dev)
1336{ return NULL; }
1337
1335#define dev_is_pci(d) (false) 1338#define dev_is_pci(d) (false)
1336#define dev_is_pf(d) (false) 1339#define dev_is_pf(d) (false)
1337#define dev_num_vf(d) (0) 1340#define dev_num_vf(d) (0)
@@ -1486,9 +1489,14 @@ enum pci_fixup_pass {
1486 1489
1487#ifdef CONFIG_PCI_QUIRKS 1490#ifdef CONFIG_PCI_QUIRKS
1488void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev); 1491void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev);
1492struct pci_dev *pci_get_dma_source(struct pci_dev *dev);
1489#else 1493#else
1490static inline void pci_fixup_device(enum pci_fixup_pass pass, 1494static inline void pci_fixup_device(enum pci_fixup_pass pass,
1491 struct pci_dev *dev) {} 1495 struct pci_dev *dev) {}
1496static inline struct pci_dev *pci_get_dma_source(struct pci_dev *dev)
1497{
1498 return pci_dev_get(dev);
1499}
1492#endif 1500#endif
1493 1501
1494void __iomem *pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen); 1502void __iomem *pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen);