- move_native_irq(vector);
- ack_APIC_irq();
-}
-
-static void end_msi_irq_w_maskbit(unsigned int vector)
-{
- move_native_irq(vector);
- unmask_MSI_irq(vector);
- ack_APIC_irq();
-}
-
-static void do_nothing(unsigned int vector)
-{
-}
-
-/*
- * Interrupt Type for MSI-X PCI/PCI-X/PCI-Express Devices,
- * which implement the MSI-X Capability Structure.
- */
-static struct hw_interrupt_type msix_irq_type = {
- .typename = "PCI-MSI-X",
- .startup = startup_msi_irq_w_maskbit,
- .shutdown = shutdown_msi_irq,
- .enable = unmask_MSI_irq,
- .disable = mask_MSI_irq,
- .ack = mask_MSI_irq,
- .end = end_msi_irq_w_maskbit,
- .set_affinity = set_msi_affinity
-};
-
-/*
- * Interrupt Type for MSI PCI/PCI-X/PCI-Express Devices,
- * which implement the MSI Capability Structure with
- * Mask-and-Pending Bits.
- */
-static struct hw_interrupt_type msi_irq_w_maskbit_type = {
- .typename = "PCI-MSI",
- .startup = startup_msi_irq_w_maskbit,
- .shutdown = shutdown_msi_irq,
- .enable = unmask_MSI_irq,
- .disable = mask_MSI_irq,
- .ack = mask_MSI_irq,
- .end = end_msi_irq_w_maskbit,
- .set_affinity = set_msi_affinity
-};
-
-/*
- * Interrupt Type for MSI PCI/PCI-X/PCI-Express Devices,
- * which implement the MSI Capability Structure without
- * Mask-and-Pending Bits.
- */
-static struct hw_interrupt_type msi_irq_wo_maskbit_type = {
- .typename = "PCI-MSI",
- .startup = startup_msi_irq_wo_maskbit,
- .shutdown = shutdown_msi_irq,
- .enable = do_nothing,
- .disable = do_nothing,
- .ack = do_nothing,
- .end = end_msi_irq_wo_maskbit,
- .set_affinity = set_msi_affinity
-};
-
-static int msi_free_vector(struct pci_dev* dev, int vector, int reassign);
-static int assign_msi_vector(void)
-{
- static int new_vector_avail = 1;
- int vector;
- unsigned long flags;
-
- /*
- * msi_lock is provided to ensure that successful allocation of MSI
- * vector is assigned unique among drivers.
- */
- spin_lock_irqsave(&msi_lock, flags);
-
- if (!new_vector_avail) {
- int free_vector = 0;
-
- /*
- * vector_irq[] = -1 indicates that this specific vector is:
- * - assigned for MSI (since MSI have no associated IRQ) or
- * - assigned for legacy if less than 16, or
- * - having no corresponding 1:1 vector-to-IOxAPIC IRQ mapping
- * vector_irq[] = 0 indicates that this vector, previously
- * assigned for MSI, is freed by hotplug removed operations.
- * This vector will be reused for any subsequent hotplug added
- * operations.
- * vector_irq[] > 0 indicates that this vector is assigned for
- * IOxAPIC IRQs. This vector and its value provides a 1-to-1
- * vector-to-IOxAPIC IRQ mapping.
- */
- for (vector = FIRST_DEVICE_VECTOR; vector < NR_IRQS; vector++) {
- if (vector_irq[vector] != 0)
- continue;
- free_vector = vector;
- if (!msi_desc[vector])
- break;
- else
- continue;
- }
- if (!free_vector) {
- spin_unlock_irqrestore(&msi_lock, flags);
- return -EBUSY;
- }
- vector_irq[free_vector] = -1;
- nr_released_vectors--;
- spin_unlock_irqrestore(&msi_lock, flags);
- if (msi_desc[free_vector] != NULL) {
- struct pci_dev *dev;
- int tail;
-
- /* free all linked vectors before re-assign */
- do {
- spin_lock_irqsave(&msi_lock, flags);
- dev = msi_desc[free_vector]->dev;
- tail = msi_desc[free_vector]->link.tail;
- spin_unlock_irqrestore(&msi_lock, flags);
- msi_free_vector(dev, tail, 1);
- } while (free_vector != tail);
- }
-
- return free_vector;
- }
- vector = assign_irq_vector(AUTO_ASSIGN);
- last_alloc_vector = vector;
- if (vector == LAST_DEVICE_VECTOR)
- new_vector_avail = 0;
-
- spin_unlock_irqrestore(&msi_lock, flags);
- return vector;
-}
-
-static int get_new_vector(void)
-{
- int vector = assign_msi_vector();
-
- if (vector > 0)
- set_intr_gate(vector, interrupt[vector]);
-
- return vector;