xen/x86/PCI: Add support for the Xen PCI subsystem
[linux-2.6.git] / drivers / xen / events.c
index cd50409..7016a73 100644 (file)
@@ -582,7 +582,9 @@ int xen_allocate_pirq(unsigned gsi, int shareable, char *name)
                goto out;       /* XXX need refcount? */
        }
 
-       if (identity_mapped_irq(gsi)) {
+       /* If we are a PV guest, we don't have GSIs (no ACPI passed). Therefore
+        * we are using the !xen_initial_domain() to drop in the function.*/
+       if (identity_mapped_irq(gsi) || !xen_initial_domain()) {
                irq = gsi;
                irq_to_desc_alloc_node(irq, 0);
                dynamic_irq_init(irq);
@@ -593,7 +595,13 @@ int xen_allocate_pirq(unsigned gsi, int shareable, char *name)
                                      handle_level_irq, name);
 
        irq_op.irq = irq;
-       if (HYPERVISOR_physdev_op(PHYSDEVOP_alloc_irq_vector, &irq_op)) {
+       irq_op.vector = 0;
+
+       /* Only the privileged domain can do this. For non-priv, the pcifront
+        * driver provides a PCI bus that does the call to do exactly
+        * this in the priv domain. */
+       if (xen_initial_domain() &&
+           HYPERVISOR_physdev_op(PHYSDEVOP_alloc_irq_vector, &irq_op)) {
                dynamic_irq_cleanup(irq);
                irq = -ENOSPC;
                goto out;
@@ -608,6 +616,26 @@ out:
        return irq;
 }
 
+int xen_destroy_irq(int irq)
+{
+       struct irq_desc *desc;
+       int rc = -ENOENT;
+
+       spin_lock(&irq_mapping_update_lock);
+
+       desc = irq_to_desc(irq);
+       if (!desc)
+               goto out;
+
+       irq_info[irq] = mk_unbound_info();
+
+       dynamic_irq_cleanup(irq);
+
+out:
+       spin_unlock(&irq_mapping_update_lock);
+       return rc;
+}
+
 int xen_vector_from_irq(unsigned irq)
 {
        return vector_from_irq(irq);