int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle) { struct irq_2_iommu *irq_iommu; spin_lock(&irq_2_ir_lock); irq_iommu = irq_2_iommu_alloc(irq); irq_iommu->iommu = iommu; irq_iommu->irte_index = index; irq_iommu->sub_handle = subhandle; irq_iommu->irte_mask = 0; spin_unlock(&irq_2_ir_lock); return 0; }
int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle) { struct irq_2_iommu *irq_iommu; spin_lock(&irq_2_ir_lock); irq_iommu = irq_2_iommu_alloc(irq); if (!irq_iommu) { spin_unlock(&irq_2_ir_lock); printk(KERN_ERR "can't allocate irq_2_iommu\n"); return -1; } irq_iommu->iommu = iommu; irq_iommu->irte_index = index; irq_iommu->sub_handle = subhandle; irq_iommu->irte_mask = 0; spin_unlock(&irq_2_ir_lock); return 0; }
int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) { struct ir_table *table = iommu->ir_table; struct irq_2_iommu *irq_iommu; u16 index, start_index; unsigned int mask = 0; unsigned long flags; int i; if (!count) return -1; #ifndef CONFIG_SPARSE_IRQ /* protect irq_2_iommu_alloc later */ if (irq >= nr_irqs) return -1; #endif /* * start the IRTE search from index 0. */ index = start_index = 0; if (count > 1) { count = __roundup_pow_of_two(count); mask = ilog2(count); } if (mask > ecap_max_handle_mask(iommu->ecap)) { printk(KERN_ERR "Requested mask %x exceeds the max invalidation handle" " mask value %Lx\n", mask, ecap_max_handle_mask(iommu->ecap)); return -1; } spin_lock_irqsave(&irq_2_ir_lock, flags); do { for (i = index; i < index + count; i++) if (table->base[i].present) break; /* empty index found */ if (i == index + count) break; index = (index + count) % INTR_REMAP_TABLE_ENTRIES; if (index == start_index) { spin_unlock_irqrestore(&irq_2_ir_lock, flags); printk(KERN_ERR "can't allocate an IRTE\n"); return -1; } } while (1); for (i = index; i < index + count; i++) table->base[i].present = 1; irq_iommu = irq_2_iommu_alloc(irq); if (!irq_iommu) { spin_unlock_irqrestore(&irq_2_ir_lock, flags); printk(KERN_ERR "can't allocate irq_2_iommu\n"); return -1; } irq_iommu->iommu = iommu; irq_iommu->irte_index = index; irq_iommu->sub_handle = 0; irq_iommu->irte_mask = mask; spin_unlock_irqrestore(&irq_2_ir_lock, flags); return index; }