Merge branches 'x86/urgent', 'x86/amd-iommu', 'x86/apic', 'x86/cleanups', 'x86/core...
[pandora-kernel.git] / arch / x86 / kernel / amd_iommu.c
index 4bae96c..c25210e 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/scatterlist.h>
 #include <linux/iommu-helper.h>
 #include <asm/proto.h>
-#include <asm/gart.h>
+#include <asm/iommu.h>
 #include <asm/amd_iommu_types.h>
 #include <asm/amd_iommu.h>
 
 #define to_pages(addr, size) \
         (round_up(((addr) & ~PAGE_MASK) + (size), PAGE_SIZE) >> PAGE_SHIFT)
 
+#define EXIT_LOOP_COUNT 10000000
+
 static DEFINE_RWLOCK(amd_iommu_devtable_lock);
 
 /*
  * general struct to manage commands send to an IOMMU
  */
-struct command {
+struct iommu_cmd {
        u32 data[4];
 };
 
@@ -60,7 +62,7 @@ static int iommu_has_npcache(struct amd_iommu *iommu)
  * Writes the command to the IOMMUs command buffer and informs the
  * hardware about the new command. Must be called with iommu->lock held.
  */
-static int __iommu_queue_command(struct amd_iommu *iommu, struct command *cmd)
+static int __iommu_queue_command(struct amd_iommu *iommu, struct iommu_cmd *cmd)
 {
        u32 tail, head;
        u8 *target;
@@ -81,7 +83,7 @@ static int __iommu_queue_command(struct amd_iommu *iommu, struct command *cmd)
  * General queuing function for commands. Takes iommu->lock and calls
  * __iommu_queue_command().
  */
-static int iommu_queue_command(struct amd_iommu *iommu, struct command *cmd)
+static int iommu_queue_command(struct amd_iommu *iommu, struct iommu_cmd *cmd)
 {
        unsigned long flags;
        int ret;
@@ -103,13 +105,14 @@ static int iommu_queue_command(struct amd_iommu *iommu, struct command *cmd)
 static int iommu_completion_wait(struct amd_iommu *iommu)
 {
        int ret;
-       struct command cmd;
+       struct iommu_cmd cmd;
        volatile u64 ready = 0;
        unsigned long ready_phys = virt_to_phys(&ready);
+       unsigned long i = 0;
 
        memset(&cmd, 0, sizeof(cmd));
        cmd.data[0] = LOW_U32(ready_phys) | CMD_COMPL_WAIT_STORE_MASK;
-       cmd.data[1] = HIGH_U32(ready_phys);
+       cmd.data[1] = upper_32_bits(ready_phys);
        cmd.data[2] = 1; /* value written to 'ready' */
        CMD_SET_TYPE(&cmd, CMD_COMPL_WAIT);
 
@@ -120,8 +123,13 @@ static int iommu_completion_wait(struct amd_iommu *iommu)
        if (ret)
                return ret;
 
-       while (!ready)
+       while (!ready && (i < EXIT_LOOP_COUNT)) {
+               ++i;
                cpu_relax();
+       }
+
+       if (unlikely((i == EXIT_LOOP_COUNT) && printk_ratelimit()))
+               printk(KERN_WARNING "AMD IOMMU: Completion wait loop failed\n");
 
        return 0;
 }
@@ -131,7 +139,7 @@ static int iommu_completion_wait(struct amd_iommu *iommu)
  */
 static int iommu_queue_inv_dev_entry(struct amd_iommu *iommu, u16 devid)
 {
-       struct command cmd;
+       struct iommu_cmd cmd;
 
        BUG_ON(iommu == NULL);
 
@@ -150,14 +158,14 @@ static int iommu_queue_inv_dev_entry(struct amd_iommu *iommu, u16 devid)
 static int iommu_queue_inv_iommu_pages(struct amd_iommu *iommu,
                u64 address, u16 domid, int pde, int s)
 {
-       struct command cmd;
+       struct iommu_cmd cmd;
 
        memset(&cmd, 0, sizeof(cmd));
        address &= PAGE_MASK;
        CMD_SET_TYPE(&cmd, CMD_INV_IOMMU_PAGES);
        cmd.data[1] |= domid;
        cmd.data[2] = LOW_U32(address);
-       cmd.data[3] = HIGH_U32(address);
+       cmd.data[3] = upper_32_bits(address);
        if (s) /* size bit - we flush more than one 4kb page */
                cmd.data[2] |= CMD_INV_IOMMU_PAGES_SIZE_MASK;
        if (pde) /* PDE bit - we wan't flush everything not only the PTEs */
@@ -656,7 +664,7 @@ static int get_device_resources(struct device *dev,
        BUG_ON(!dev || dev->bus != &pci_bus_type || !dev->dma_mask);
 
        pcidev = to_pci_dev(dev);
-       _bdf = (pcidev->bus->number << 8) | pcidev->devfn;
+       _bdf = calc_devid(pcidev->bus->number, pcidev->devfn);
 
        /* device not translated by any IOMMU in the system? */
        if (_bdf >= amd_iommu_last_bdf) {