[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] x86: split MSI IRQ chip
# HG changeset patch # User Jan Beulich <jbeulich@xxxxxxxx> # Date 1316302012 -3600 # Node ID a422e2a4451e16dc791b293f41966b842fa4781d # Parent 2dab09bcec8136a5962e71beed1f5dc06275a6b1 x86: split MSI IRQ chip With the .end() accessor having become optional and noting that several of the accessors' behavior really depends on the result of msi_maskable_irq(), the splits the MSI IRQ chip type into two - one for the maskable ones, and the other for the (MSI only) non-maskable ones. At once the implementation of those methods gets moved from io_apic.c to msi.c. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> --- diff -r 2dab09bcec81 -r a422e2a4451e xen/arch/x86/hpet.c --- a/xen/arch/x86/hpet.c Sun Sep 18 00:25:57 2011 +0100 +++ b/xen/arch/x86/hpet.c Sun Sep 18 00:26:52 2011 +0100 @@ -312,7 +312,7 @@ { struct msi_msg msg; - msi_compose_msg(desc->irq, &msg); + msi_compose_msg(desc, &msg); hpet_msi_write(desc->action->dev_id, &msg); } diff -r 2dab09bcec81 -r a422e2a4451e xen/arch/x86/hvm/vmsi.c --- a/xen/arch/x86/hvm/vmsi.c Sun Sep 18 00:25:57 2011 +0100 +++ b/xen/arch/x86/hvm/vmsi.c Sun Sep 18 00:26:52 2011 +0100 @@ -382,7 +382,7 @@ return r; } - if ( irq_desc->handler != &pci_msi_type ) + if ( !irq_desc->msi_desc ) goto out; msi_desc = irq_desc->msi_desc; @@ -426,7 +426,7 @@ if ( !irq_desc ) return; - if ( irq_desc->handler != &pci_msi_type ) + if ( !irq_desc->msi_desc ) goto out; msi_desc = irq_desc->msi_desc; diff -r 2dab09bcec81 -r a422e2a4451e xen/arch/x86/io_apic.c --- a/xen/arch/x86/io_apic.c Sun Sep 18 00:25:57 2011 +0100 +++ b/xen/arch/x86/io_apic.c Sun Sep 18 00:26:52 2011 +0100 @@ -1882,44 +1882,6 @@ .set_affinity = set_ioapic_affinity_irq, }; -static unsigned int startup_msi_irq(struct irq_desc *desc) -{ - unmask_msi_irq(desc); - return 0; -} - -static void ack_msi_irq(struct irq_desc *desc) -{ - irq_complete_move(desc); - move_native_irq(desc); - - if ( msi_maskable_irq(desc->msi_desc) ) - ack_APIC_irq(); /* ACKTYPE_NONE */ -} - -static void end_msi_irq(struct irq_desc *desc, u8 vector) -{ - if ( !msi_maskable_irq(desc->msi_desc) ) - ack_APIC_irq(); /* ACKTYPE_EOI */ -} - -#define shutdown_msi_irq mask_msi_irq - -/* - * IRQ Chip for MSI PCI/PCI-X/PCI-Express Devices, - * which implement the MSI or MSI-X Capability Structure. - */ -hw_irq_controller pci_msi_type = { - .typename = "PCI-MSI", - .startup = startup_msi_irq, - .shutdown = shutdown_msi_irq, - .enable = unmask_msi_irq, - .disable = mask_msi_irq, - .ack = ack_msi_irq, - .end = end_msi_irq, - .set_affinity = set_msi_affinity, -}; - static inline void init_IO_APIC_traps(void) { int irq; diff -r 2dab09bcec81 -r a422e2a4451e xen/arch/x86/irq.c --- a/xen/arch/x86/irq.c Sun Sep 18 00:25:57 2011 +0100 +++ b/xen/arch/x86/irq.c Sun Sep 18 00:26:52 2011 +0100 @@ -1304,7 +1304,7 @@ * MSIs are treated as edge-triggered interrupts, except * when there is no proper way to mask them. */ - if ( desc->handler == &pci_msi_type ) + if ( desc->msi_desc ) return msi_maskable_irq(desc->msi_desc) ? ACKTYPE_NONE : ACKTYPE_EOI; /* @@ -1723,7 +1723,7 @@ if ( desc->handler != &no_irq_type ) dprintk(XENLOG_G_ERR, "dom%d: irq %d in use\n", d->domain_id, irq); - desc->handler = &pci_msi_type; + setup_msi_handler(desc, msi_desc); if ( opt_irq_vector_map == OPT_IRQ_VECTOR_MAP_PERDEV && !desc->chip_data->used_vectors ) @@ -1739,7 +1739,7 @@ } set_domain_irq_pirq(d, irq, info); - setup_msi_irq(msi_desc, irq); + setup_msi_irq(desc); spin_unlock_irqrestore(&desc->lock, flags); } else @@ -1807,6 +1807,12 @@ radix_tree_int_to_ptr(-pirq)); } + if ( msi_desc ) + { + desc->handler = &no_irq_type; + desc->msi_desc = NULL; + } + spin_unlock_irqrestore(&desc->lock, flags); if (msi_desc) msi_free_irq(msi_desc); @@ -1819,9 +1825,6 @@ dprintk(XENLOG_G_ERR, "dom%d: could not deny access to irq %d\n", d->domain_id, pirq); - if ( desc->handler == &pci_msi_type ) - desc->handler = &no_irq_type; - done: return ret; } diff -r 2dab09bcec81 -r a422e2a4451e xen/arch/x86/msi.c --- a/xen/arch/x86/msi.c Sun Sep 18 00:25:57 2011 +0100 +++ b/xen/arch/x86/msi.c Sun Sep 18 00:26:52 2011 +0100 @@ -120,11 +120,11 @@ /* * MSI message composition */ -void msi_compose_msg(int irq, struct msi_msg *msg) +void msi_compose_msg(struct irq_desc *desc, struct msi_msg *msg) { unsigned dest; cpumask_t domain; - struct irq_cfg *cfg = irq_cfg(irq); + struct irq_cfg *cfg = desc->chip_data; int vector = cfg->vector; domain = cfg->cpu_mask; @@ -205,19 +205,6 @@ iommu_read_msi_from_ire(entry, msg); } -static int set_irq_msi(struct msi_desc *entry) -{ - if ( entry->irq >= nr_irqs ) - { - dprintk(XENLOG_ERR, "Trying to install msi data for irq %d\n", - entry->irq); - return -EINVAL; - } - - irq_desc[entry->irq].msi_desc = entry; - return 0; -} - static void write_msi_msg(struct msi_desc *entry, struct msi_msg *msg) { entry->msg = *msg; @@ -266,7 +253,7 @@ } } -void set_msi_affinity(struct irq_desc *desc, const cpumask_t *mask) +static void set_msi_affinity(struct irq_desc *desc, const cpumask_t *mask) { struct msi_msg msg; unsigned int dest; @@ -387,16 +374,65 @@ return -1; } -void mask_msi_irq(struct irq_desc *desc) +static void mask_msi_irq(struct irq_desc *desc) { msi_set_mask_bit(desc, 1); } -void unmask_msi_irq(struct irq_desc *desc) +static void unmask_msi_irq(struct irq_desc *desc) { msi_set_mask_bit(desc, 0); } +static unsigned int startup_msi_irq(struct irq_desc *desc) +{ + unmask_msi_irq(desc); + return 0; +} + +static void ack_nonmaskable_msi_irq(struct irq_desc *desc) +{ + irq_complete_move(desc); + move_native_irq(desc); +} + +static void ack_maskable_msi_irq(struct irq_desc *desc) +{ + ack_nonmaskable_msi_irq(desc); + ack_APIC_irq(); /* ACKTYPE_NONE */ +} + +static void end_nonmaskable_msi_irq(struct irq_desc *desc, u8 vector) +{ + ack_APIC_irq(); /* ACKTYPE_EOI */ +} + +/* + * IRQ chip for MSI PCI/PCI-X/PCI-Express devices, + * which implement the MSI or MSI-X capability structure. + */ +static hw_irq_controller pci_msi_maskable = { + .typename = "PCI-MSI/-X", + .startup = startup_msi_irq, + .shutdown = mask_msi_irq, + .enable = unmask_msi_irq, + .disable = mask_msi_irq, + .ack = ack_maskable_msi_irq, + .set_affinity = set_msi_affinity +}; + +/* As above, but without having masking capability. */ +static hw_irq_controller pci_msi_nonmaskable = { + .typename = "PCI-MSI", + .startup = irq_startup_none, + .shutdown = irq_shutdown_none, + .enable = irq_enable_none, + .disable = irq_disable_none, + .ack = ack_nonmaskable_msi_irq, + .end = end_nonmaskable_msi_irq, + .set_affinity = set_msi_affinity +}; + static struct msi_desc* alloc_msi_entry(void) { struct msi_desc *entry; @@ -412,15 +448,19 @@ return entry; } -int setup_msi_irq(struct msi_desc *msidesc, int irq) +void setup_msi_handler(struct irq_desc *desc, struct msi_desc *msidesc) +{ + desc->msi_desc = msidesc; + desc->handler = msi_maskable_irq(msidesc) ? &pci_msi_maskable + : &pci_msi_nonmaskable; +} + +void setup_msi_irq(struct irq_desc *desc) { struct msi_msg msg; - msi_compose_msg(irq, &msg); - set_irq_msi(msidesc); - write_msi_msg(irq_desc[irq].msi_desc, &msg); - - return 0; + msi_compose_msg(desc, &msg); + write_msi_msg(desc->msi_desc, &msg); } int msi_free_irq(struct msi_desc *entry) @@ -1022,19 +1062,20 @@ { struct irq_desc *desc = irq_to_desc(irq); const struct msi_desc *entry; - u32 addr, data; + u32 addr, data, dest32; + int mask; + struct msi_attrib attr; unsigned long flags; char type; spin_lock_irqsave(&desc->lock, flags); entry = desc->msi_desc; - type = desc->handler == &pci_msi_type && entry; - - spin_unlock_irqrestore(&desc->lock, flags); - - if ( !type ) + if ( !entry ) + { + spin_unlock_irqrestore(&desc->lock, flags); continue; + } switch ( entry->msi_attrib.type ) { @@ -1045,6 +1086,11 @@ data = entry->msg.data; addr = entry->msg.address_lo; + dest32 = entry->msg.dest32; + attr = entry->msi_attrib; + mask = msi_get_mask_bit(entry); + + spin_unlock_irqrestore(&desc->lock, flags); printk(" MSI%c %4u vec=%02x%7s%6s%3sassert%5s%7s" " dest=%08x mask=%d/%d/%d\n", @@ -1055,9 +1101,7 @@ data & MSI_DATA_LEVEL_ASSERT ? "" : "de", addr & MSI_ADDR_DESTMODE_LOGIC ? "log" : "phys", addr & MSI_ADDR_REDIRECTION_LOWPRI ? "lowest" : "cpu", - entry->msg.dest32, - entry->msi_attrib.maskbit, entry->msi_attrib.masked, - msi_get_mask_bit(entry)); + dest32, attr.maskbit, attr.masked, mask); } } diff -r 2dab09bcec81 -r a422e2a4451e xen/include/asm-x86/msi.h --- a/xen/include/asm-x86/msi.h Sun Sep 18 00:25:57 2011 +0100 +++ b/xen/include/asm-x86/msi.h Sun Sep 18 00:26:52 2011 +0100 @@ -74,15 +74,14 @@ u32 dest32; /* used when Interrupt Remapping with EIM is enabled */ }; +struct irq_desc; struct msi_desc; /* Helper functions */ -extern void mask_msi_irq(struct irq_desc *); -extern void unmask_msi_irq(struct irq_desc *); -extern void set_msi_affinity(struct irq_desc *, const cpumask_t *); extern int pci_enable_msi(struct msi_info *msi, struct msi_desc **desc); extern void pci_disable_msi(struct msi_desc *desc); extern void pci_cleanup_msi(struct pci_dev *pdev); -extern int setup_msi_irq(struct msi_desc *desc, int irq); +extern void setup_msi_handler(struct irq_desc *, struct msi_desc *); +extern void setup_msi_irq(struct irq_desc *); extern void teardown_msi_irq(int irq); extern int msi_free_vector(struct msi_desc *entry); extern int pci_restore_msi_state(struct pci_dev *pdev); @@ -90,14 +89,14 @@ extern unsigned int pci_msix_get_table_len(struct pci_dev *pdev); struct msi_desc { - struct { + struct msi_attrib { __u8 type : 5; /* {0: unused, 5h:MSI, 11h:MSI-X} */ __u8 maskbit : 1; /* mask-pending bit supported ? */ __u8 masked : 1; __u8 is_64 : 1; /* Address size: 0=32bit 1=64bit */ __u8 pos; /* Location of the msi capability */ __u16 entry_nr; /* specific enabled entry */ - }msi_attrib; + } msi_attrib; struct list_head list; @@ -123,8 +122,6 @@ */ #define NR_HP_RESERVED_VECTORS 20 -extern const struct hw_interrupt_type pci_msi_type; - #define PCI_MSIX_ENTRY_SIZE 16 #define PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET 0 #define PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET 4 @@ -222,5 +219,6 @@ __u32 hi_address; } __attribute__ ((packed)); -void msi_compose_msg(int irq, struct msi_msg *); +void msi_compose_msg(struct irq_desc *, struct msi_msg *); + #endif /* __ASM_MSI_H */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |