]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
PCI/ATS: Add pci_ats_page_aligned() interface
authorKuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Tue, 19 Feb 2019 19:06:09 +0000 (11:06 -0800)
committerJoerg Roedel <jroedel@suse.de>
Tue, 26 Feb 2019 10:08:07 +0000 (11:08 +0100)
Return the Page Aligned Request bit in the ATS Capability Register.

As per PCIe spec r4.0, sec 10.5.1.2, if the Page Aligned Request bit is
set, it indicates the Untranslated Addresses generated by the device are
always aligned to a 4096 byte boundary.

An IOMMU that can only translate page-aligned addresses can only be used
with devices that always produce aligned Untranslated Addresses. This
interface will be used by drivers for such IOMMUs to determine whether
devices can use the ATS service.

Cc: Ashok Raj <ashok.raj@intel.com>
Cc: Jacob Pan <jacob.jun.pan@linux.intel.com>
Cc: Keith Busch <keith.busch@intel.com>
Suggested-by: Ashok Raj <ashok.raj@intel.com>
Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
drivers/pci/ats.c
include/linux/pci.h
include/uapi/linux/pci_regs.h

index 420cd0a578d079371227a1d2f0d13ad89b39ceeb..97c08146534ade4b924195c524ea93e7854f22ca 100644 (file)
@@ -142,6 +142,33 @@ int pci_ats_queue_depth(struct pci_dev *dev)
 }
 EXPORT_SYMBOL_GPL(pci_ats_queue_depth);
 
+/**
+ * pci_ats_page_aligned - Return Page Aligned Request bit status.
+ * @pdev: the PCI device
+ *
+ * Returns 1, if the Untranslated Addresses generated by the device
+ * are always aligned or 0 otherwise.
+ *
+ * Per PCIe spec r4.0, sec 10.5.1.2, if the Page Aligned Request bit
+ * is set, it indicates the Untranslated Addresses generated by the
+ * device are always aligned to a 4096 byte boundary.
+ */
+int pci_ats_page_aligned(struct pci_dev *pdev)
+{
+       u16 cap;
+
+       if (!pdev->ats_cap)
+               return 0;
+
+       pci_read_config_word(pdev, pdev->ats_cap + PCI_ATS_CAP, &cap);
+
+       if (cap & PCI_ATS_CAP_PAGE_ALIGNED)
+               return 1;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(pci_ats_page_aligned);
+
 #ifdef CONFIG_PCI_PRI
 /**
  * pci_enable_pri - Enable PRI capability
index 65f1d8c2f08202ea6683a596e67f252de95bea4e..9724a8c0496bbe612666e37aa1f5cfc5c663acc7 100644 (file)
@@ -1524,11 +1524,13 @@ void pci_ats_init(struct pci_dev *dev);
 int pci_enable_ats(struct pci_dev *dev, int ps);
 void pci_disable_ats(struct pci_dev *dev);
 int pci_ats_queue_depth(struct pci_dev *dev);
+int pci_ats_page_aligned(struct pci_dev *dev);
 #else
 static inline void pci_ats_init(struct pci_dev *d) { }
 static inline int pci_enable_ats(struct pci_dev *d, int ps) { return -ENODEV; }
 static inline void pci_disable_ats(struct pci_dev *d) { }
 static inline int pci_ats_queue_depth(struct pci_dev *d) { return -ENODEV; }
+static inline int pci_ats_page_aligned(struct pci_dev *dev) { return 0; }
 #endif
 
 #ifdef CONFIG_PCIE_PTM
index 898be572b010d65b33c3e55bf6ad2295784a8583..5c98133f2c9494c48ee368668daf2495d4aa3b4b 100644 (file)
 #define PCI_ATS_CAP            0x04    /* ATS Capability Register */
 #define  PCI_ATS_CAP_QDEP(x)   ((x) & 0x1f)    /* Invalidate Queue Depth */
 #define  PCI_ATS_MAX_QDEP      32      /* Max Invalidate Queue Depth */
+#define  PCI_ATS_CAP_PAGE_ALIGNED      0x0020 /* Page Aligned Request */
 #define PCI_ATS_CTRL           0x06    /* ATS Control Register */
 #define  PCI_ATS_CTRL_ENABLE   0x8000  /* ATS Enable */
 #define  PCI_ATS_CTRL_STU(x)   ((x) & 0x1f)    /* Smallest Translation Unit */