ia64/xen-unstable

diff xen/drivers/passthrough/vtd/qinval.c @ 19734:4fb8a6c993e2

VT-d: correct way to submit command to GCMD register

Per VT-d spec, software should submit only one "incremental" command
at a time to Global Command reigster. Current implementation uses a
variable (gcmd) to record the state of Global Status register. It's
error prone.

Signed-off-by: Weidong Han <weidong.han@intel.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Jun 05 09:29:42 2009 +0100 (2009-06-05)
parents a69daf23602a
children cc07094a02e4
line diff
     1.1 --- a/xen/drivers/passthrough/vtd/qinval.c	Fri Jun 05 09:27:18 2009 +0100
     1.2 +++ b/xen/drivers/passthrough/vtd/qinval.c	Fri Jun 05 09:29:42 2009 +0100
     1.3 @@ -454,8 +454,8 @@ int enable_qinval(struct iommu *iommu)
     1.4      dmar_writeq(iommu->reg, DMAR_IQT_REG, 0);
     1.5  
     1.6      /* enable queued invalidation hardware */
     1.7 -    iommu->gcmd |= DMA_GCMD_QIE;
     1.8 -    dmar_writel(iommu->reg, DMAR_GCMD_REG, iommu->gcmd);
     1.9 +    sts = dmar_readl(iommu->reg, DMAR_GSTS_REG);
    1.10 +    dmar_writel(iommu->reg, DMAR_GCMD_REG, sts | DMA_GCMD_QIE);
    1.11  
    1.12      /* Make sure hardware complete it */
    1.13      IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, dmar_readl,
    1.14 @@ -471,8 +471,8 @@ void disable_qinval(struct iommu *iommu)
    1.15  
    1.16      ASSERT(ecap_queued_inval(iommu->ecap) && iommu_qinval);
    1.17  
    1.18 -    iommu->gcmd &= ~DMA_GCMD_QIE;
    1.19 -    dmar_writel(iommu->reg, DMAR_GCMD_REG, iommu->gcmd);
    1.20 +    sts = dmar_readl(iommu->reg, DMAR_GSTS_REG);
    1.21 +    dmar_writel(iommu->reg, DMAR_GCMD_REG, sts & (~DMA_GCMD_QIE));
    1.22  
    1.23      /* Make sure hardware complete it */
    1.24      IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, dmar_readl,