lkml.org 
[lkml]   [2008]   [Dec]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 06/21] AMD IOMMU: refactor completion wait handling into separate functions
    Date
    Impact: split one function into three

    The separate functions are required synchronize commands across all
    hardware IOMMUs in the system.

    Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
    ---
    arch/x86/kernel/amd_iommu.c | 65 +++++++++++++++++++++++++++++--------------
    1 files changed, 44 insertions(+), 21 deletions(-)

    diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c
    index 11de0f1..db89001 100644
    --- a/arch/x86/kernel/amd_iommu.c
    +++ b/arch/x86/kernel/amd_iommu.c
    @@ -195,6 +195,46 @@ static int iommu_queue_command(struct amd_iommu *iommu, struct iommu_cmd *cmd)
    }

    /*
    + * This function waits until an IOMMU has completed a completion
    + * wait command
    + */
    +static void __iommu_wait_for_completion(struct amd_iommu *iommu)
    +{
    + int ready = 0;
    + unsigned status = 0;
    + unsigned long i = 0;
    +
    + while (!ready && (i < EXIT_LOOP_COUNT)) {
    + ++i;
    + /* wait for the bit to become one */
    + status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET);
    + ready = status & MMIO_STATUS_COM_WAIT_INT_MASK;
    + }
    +
    + /* set bit back to zero */
    + status &= ~MMIO_STATUS_COM_WAIT_INT_MASK;
    + writel(status, iommu->mmio_base + MMIO_STATUS_OFFSET);
    +
    + if (unlikely((i == EXIT_LOOP_COUNT) && printk_ratelimit()))
    + printk(KERN_WARNING "AMD IOMMU: Completion wait loop failed\n");
    +}
    +
    +/*
    + * This function queues a completion wait command into the command
    + * buffer of an IOMMU
    + */
    +static int __iommu_completion_wait(struct amd_iommu *iommu)
    +{
    + struct iommu_cmd cmd;
    +
    + memset(&cmd, 0, sizeof(cmd));
    + cmd.data[0] = CMD_COMPL_WAIT_INT_MASK;
    + CMD_SET_TYPE(&cmd, CMD_COMPL_WAIT);
    +
    + return __iommu_queue_command(iommu, &cmd);
    +}
    +
    +/*
    * This function is called whenever we need to ensure that the IOMMU has
    * completed execution of all commands we sent. It sends a
    * COMPLETION_WAIT command and waits for it to finish. The IOMMU informs
    @@ -203,14 +243,8 @@ static int iommu_queue_command(struct amd_iommu *iommu, struct iommu_cmd *cmd)
    */
    static int iommu_completion_wait(struct amd_iommu *iommu)
    {
    - int ret = 0, ready = 0;
    - unsigned status = 0;
    - struct iommu_cmd cmd;
    - unsigned long flags, i = 0;
    -
    - memset(&cmd, 0, sizeof(cmd));
    - cmd.data[0] = CMD_COMPL_WAIT_INT_MASK;
    - CMD_SET_TYPE(&cmd, CMD_COMPL_WAIT);
    + int ret = 0;
    + unsigned long flags;

    spin_lock_irqsave(&iommu->lock, flags);

    @@ -219,24 +253,13 @@ static int iommu_completion_wait(struct amd_iommu *iommu)

    iommu->need_sync = 0;

    - ret = __iommu_queue_command(iommu, &cmd);
    + ret = __iommu_completion_wait(iommu);

    if (ret)
    goto out;

    - while (!ready && (i < EXIT_LOOP_COUNT)) {
    - ++i;
    - /* wait for the bit to become one */
    - status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET);
    - ready = status & MMIO_STATUS_COM_WAIT_INT_MASK;
    - }
    -
    - /* set bit back to zero */
    - status &= ~MMIO_STATUS_COM_WAIT_INT_MASK;
    - writel(status, iommu->mmio_base + MMIO_STATUS_OFFSET);
    + __iommu_wait_for_completion(iommu);

    - if (unlikely((i == EXIT_LOOP_COUNT) && printk_ratelimit()))
    - printk(KERN_WARNING "AMD IOMMU: Completion wait loop failed\n");
    out:
    spin_unlock_irqrestore(&iommu->lock, flags);

    --
    1.5.6.4



    \
     
     \ /
      Last update: 2008-12-09 15:25    [W:4.169 / U:0.052 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site