From: "Nguyen, Tom L" Adds MSI support for ia64. To support this, drivers/pci/msi.h was refactored and , and were created. These hold the arch-specific parts of MSI support. pci_vector_resources() was uninlined and was placed in arch/.../pci/irq.c. --- 25-akpm/arch/i386/kernel/io_apic.c | 19 ++++--- 25-akpm/arch/i386/pci/irq.c | 25 +++++++++ 25-akpm/arch/ia64/Kconfig | 10 +++ 25-akpm/arch/ia64/hp/sim/simeth.c | 2 25-akpm/arch/ia64/hp/sim/simserial.c | 2 25-akpm/arch/ia64/kernel/iosapic.c | 8 +- 25-akpm/arch/ia64/kernel/irq_ia64.c | 4 - 25-akpm/arch/ia64/pci/pci.c | 10 +++ 25-akpm/drivers/pci/msi.c | 95 ++++++----------------------------- 25-akpm/drivers/pci/msi.h | 25 +-------- 25-akpm/include/asm-i386/hw_irq.h | 1 25-akpm/include/asm-i386/msi.h | 22 ++++++++ 25-akpm/include/asm-ia64/hw_irq.h | 4 + 25-akpm/include/asm-ia64/irq.h | 1 25-akpm/include/asm-ia64/msi.h | 20 +++++++ 25-akpm/include/asm-x86_64/msi.h | 21 +++++++ 16 files changed, 157 insertions(+), 112 deletions(-) diff -puN arch/i386/kernel/io_apic.c~msi-ia64 arch/i386/kernel/io_apic.c --- 25/arch/i386/kernel/io_apic.c~msi-ia64 Tue Apr 6 14:31:10 2004 +++ 25-akpm/arch/i386/kernel/io_apic.c Tue Apr 6 14:31:10 2004 @@ -76,8 +76,8 @@ static struct irq_pin_list { int apic, pin, next; } irq_2_pin[PIN_MAP_SIZE]; +int vector_irq[NR_IRQ_VECTORS] = { [0 ... NR_IRQ_VECTORS - 1] = -1}; #ifdef CONFIG_PCI_USE_VECTOR -int vector_irq[NR_IRQS] = { [0 ... NR_IRQS -1] = -1}; #define vector_to_irq(vector) \ (platform_legacy_irq(vector) ? vector : vector_irq[vector]) #else @@ -1154,12 +1154,16 @@ static inline int IO_APIC_irq_trigger(in /* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */ u8 irq_vector[NR_IRQ_VECTORS] = { FIRST_DEVICE_VECTOR , 0 }; -#ifndef CONFIG_PCI_USE_VECTOR +#ifdef CONFIG_PCI_USE_VECTOR +int assign_irq_vector(int irq) +#else int __init assign_irq_vector(int irq) +#endif { static int current_vector = FIRST_DEVICE_VECTOR, offset = 0; + BUG_ON(irq >= NR_IRQ_VECTORS); - if (IO_APIC_VECTOR(irq) > 0) + if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) return IO_APIC_VECTOR(irq); next: current_vector += 8; @@ -1167,15 +1171,18 @@ next: goto next; if (current_vector >= FIRST_SYSTEM_VECTOR) { - offset = (offset + 1) & 7; + offset++; + if (!(offset%8)) + return -ENOSPC; current_vector = FIRST_DEVICE_VECTOR + offset; } - IO_APIC_VECTOR(irq) = current_vector; + vector_irq[current_vector] = irq; + if (irq != AUTO_ASSIGN) + IO_APIC_VECTOR(irq) = current_vector; return current_vector; } -#endif static struct hw_interrupt_type ioapic_level_type; static struct hw_interrupt_type ioapic_edge_type; diff -puN arch/i386/pci/irq.c~msi-ia64 arch/i386/pci/irq.c --- 25/arch/i386/pci/irq.c~msi-ia64 Tue Apr 6 14:31:10 2004 +++ 25-akpm/arch/i386/pci/irq.c Tue Apr 6 14:31:10 2004 @@ -1006,3 +1006,28 @@ int pirq_enable_irq(struct pci_dev *dev) pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); return 0; } + +int pci_vector_resources(int last, int nr_released) +{ + int count = nr_released; + + int next = last; + int offset = (last % 8); + + while (next < FIRST_SYSTEM_VECTOR) { + next += 8; + if (next == SYSCALL_VECTOR) + continue; + count++; + if (next >= FIRST_SYSTEM_VECTOR) { + if (offset%8) { + next = FIRST_DEVICE_VECTOR + offset; + offset++; + continue; + } + count--; + } + } + + return count; +} diff -puN arch/ia64/hp/sim/simeth.c~msi-ia64 arch/ia64/hp/sim/simeth.c --- 25/arch/ia64/hp/sim/simeth.c~msi-ia64 Tue Apr 6 14:31:10 2004 +++ 25-akpm/arch/ia64/hp/sim/simeth.c Tue Apr 6 14:31:10 2004 @@ -228,7 +228,7 @@ simeth_probe1(void) return err; } - dev->irq = ia64_alloc_vector(); + dev->irq = assign_irq_vector(AUTO_ASSIGN); /* * attach the interrupt in the simulator, this does enable interrupts diff -puN arch/ia64/hp/sim/simserial.c~msi-ia64 arch/ia64/hp/sim/simserial.c --- 25/arch/ia64/hp/sim/simserial.c~msi-ia64 Tue Apr 6 14:31:10 2004 +++ 25-akpm/arch/ia64/hp/sim/simserial.c Tue Apr 6 14:31:10 2004 @@ -1051,7 +1051,7 @@ simrs_init (void) if (state->type == PORT_UNKNOWN) continue; if (!state->irq) { - state->irq = ia64_alloc_vector(); + state->irq = assign_irq_vector(AUTO_ASSIGN); ia64_ssc_connect_irq(KEYBOARD_INTR, state->irq); } diff -puN arch/ia64/Kconfig~msi-ia64 arch/ia64/Kconfig --- 25/arch/ia64/Kconfig~msi-ia64 Tue Apr 6 14:31:10 2004 +++ 25-akpm/arch/ia64/Kconfig Tue Apr 6 14:31:10 2004 @@ -361,6 +361,16 @@ config PCI information about which PCI hardware does work under Linux and which doesn't. +config PCI_USE_VECTOR + bool + default y if IA64 + help + This enables MSI, Message Signaled Interrupt, on specific + MSI capable device functions detected upon requests from the + device drivers. Message Signal Interrupt enables an MSI-capable + hardware device to send an inbound Memory Write on its PCI bus + instead of asserting IRQ signal on device IRQ pin. + config PCI_DOMAINS bool default PCI diff -puN arch/ia64/kernel/iosapic.c~msi-ia64 arch/ia64/kernel/iosapic.c --- 25/arch/ia64/kernel/iosapic.c~msi-ia64 Tue Apr 6 14:31:10 2004 +++ 25-akpm/arch/ia64/kernel/iosapic.c Tue Apr 6 14:31:10 2004 @@ -435,7 +435,7 @@ iosapic_reassign_vector (int vector) || iosapic_intr_info[vector].gsi_base || iosapic_intr_info[vector].dmode || iosapic_intr_info[vector].polarity || iosapic_intr_info[vector].trigger) { - new_vector = ia64_alloc_vector(); + new_vector = assign_irq_vector(AUTO_ASSIGN); printk(KERN_INFO "Reassigning vector %d to %d\n", vector, new_vector); memcpy(&iosapic_intr_info[new_vector], &iosapic_intr_info[vector], sizeof(struct iosapic_intr_info)); @@ -500,7 +500,7 @@ iosapic_register_intr (unsigned int gsi, vector = gsi_to_vector(gsi); if (vector < 0) - vector = ia64_alloc_vector(); + vector = assign_irq_vector(AUTO_ASSIGN); register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, polarity, trigger); @@ -538,7 +538,7 @@ iosapic_register_platform_intr (u32 int_ delivery = IOSAPIC_PMI; break; case ACPI_INTERRUPT_INIT: - vector = ia64_alloc_vector(); + vector = assign_irq_vector(AUTO_ASSIGN); delivery = IOSAPIC_INIT; break; case ACPI_INTERRUPT_CPEI: @@ -708,7 +708,7 @@ iosapic_parse_prt (void) vector = isa_irq_to_vector(gsi); else /* new GSI; allocate a vector for it */ - vector = ia64_alloc_vector(); + vector = assign_irq_vector(AUTO_ASSIGN); register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, IOSAPIC_POL_LOW, IOSAPIC_LEVEL); diff -puN arch/ia64/kernel/irq_ia64.c~msi-ia64 arch/ia64/kernel/irq_ia64.c --- 25/arch/ia64/kernel/irq_ia64.c~msi-ia64 Tue Apr 6 14:31:10 2004 +++ 25-akpm/arch/ia64/kernel/irq_ia64.c Tue Apr 6 14:31:10 2004 @@ -73,13 +73,13 @@ irq_exit (void) } int -ia64_alloc_vector (void) +assign_irq_vector (int irq) { static int next_vector = IA64_FIRST_DEVICE_VECTOR; if (next_vector > IA64_LAST_DEVICE_VECTOR) /* XXX could look for sharable vectors instead of panic'ing... */ - panic("ia64_alloc_vector: out of interrupt vectors!"); + panic("assign_irq_vector: out of interrupt vectors!"); return next_vector++; } diff -puN arch/ia64/pci/pci.c~msi-ia64 arch/ia64/pci/pci.c --- 25/arch/ia64/pci/pci.c~msi-ia64 Tue Apr 6 14:31:10 2004 +++ 25-akpm/arch/ia64/pci/pci.c Tue Apr 6 14:31:10 2004 @@ -34,6 +34,7 @@ # include #endif #include +#include #undef DEBUG @@ -567,3 +568,12 @@ pcibios_prep_mwi (struct pci_dev *dev) } return rc; } + +int pci_vector_resources(int last, int nr_released) +{ + int count = nr_released; + + count += (IA64_LAST_DEVICE_VECTOR - last); + + return count; +} diff -puN drivers/pci/msi.c~msi-ia64 drivers/pci/msi.c --- 25/drivers/pci/msi.c~msi-ia64 Tue Apr 6 14:31:10 2004 +++ 25-akpm/drivers/pci/msi.c Tue Apr 6 14:31:10 2004 @@ -19,26 +19,23 @@ #include #include #include -#include -#include -#include +static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask); #include "msi.h" - static spinlock_t msi_lock = SPIN_LOCK_UNLOCKED; static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL }; static kmem_cache_t* msi_cachep; static int pci_msi_enable = 1; -static int nr_alloc_vectors = 0; +static int last_alloc_vector = 0; static int nr_released_vectors = 0; static int nr_reserved_vectors = NR_HP_RESERVED_VECTORS; static int nr_msix_devices = 0; #ifndef CONFIG_X86_IO_APIC -int vector_irq[NR_IRQS] = { [0 ... NR_IRQS -1] = -1}; -u8 irq_vector[NR_IRQS] = { FIRST_DEVICE_VECTOR , 0 }; +int vector_irq[NR_IRQ_VECTORS] = { [0 ... NR_IRQ_VECTORS - 1] = -1}; +u8 irq_vector[NR_IRQ_VECTORS] = { FIRST_DEVICE_VECTOR , 0 }; #endif static void msi_cache_ctor(void *p, kmem_cache_t *cache, unsigned long flags) @@ -96,7 +93,6 @@ static void set_msi_affinity(unsigned in { struct msi_desc *entry; struct msg_address address; - unsigned int dest_id; entry = (struct msi_desc *)msi_desc[vector]; if (!entry || !entry->dev) @@ -113,10 +109,9 @@ static void set_msi_affinity(unsigned in entry->dev->bus->ops->read(entry->dev->bus, entry->dev->devfn, msi_lower_address_reg(pos), 4, &address.lo_address.value); - dest_id = (address.lo_address.u.dest_id & - MSI_ADDRESS_HEADER_MASK) | - (cpu_mask_to_apicid(cpu_mask) << MSI_TARGET_CPU_SHIFT); - address.lo_address.u.dest_id = dest_id; + address.lo_address.value &= MSI_ADDRESS_DEST_ID_MASK; + address.lo_address.value |= (cpu_mask_to_apicid(cpu_mask) << + MSI_TARGET_CPU_SHIFT); entry->msi_attrib.current_cpu = cpu_mask_to_apicid(cpu_mask); entry->dev->bus->ops->write(entry->dev->bus, entry->dev->devfn, msi_lower_address_reg(pos), 4, @@ -129,10 +124,9 @@ static void set_msi_affinity(unsigned in PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET; address.lo_address.value = readl(entry->mask_base + offset); - dest_id = (address.lo_address.u.dest_id & - MSI_ADDRESS_HEADER_MASK) | - (cpu_mask_to_apicid(cpu_mask) << MSI_TARGET_CPU_SHIFT); - address.lo_address.u.dest_id = dest_id; + address.lo_address.value &= MSI_ADDRESS_DEST_ID_MASK; + address.lo_address.value |= (cpu_mask_to_apicid(cpu_mask) << + MSI_TARGET_CPU_SHIFT); entry->msi_attrib.current_cpu = cpu_mask_to_apicid(cpu_mask); writel(address.lo_address.value, entry->mask_base + offset); break; @@ -265,61 +259,11 @@ static void msi_address_init(struct msg_ memset(msi_address, 0, sizeof(struct msg_address)); msi_address->hi_address = (u32)0; - dest_id = (MSI_ADDRESS_HEADER << MSI_ADDRESS_HEADER_SHIFT) | - (MSI_TARGET_CPU << MSI_TARGET_CPU_SHIFT); - msi_address->lo_address.u.dest_mode = MSI_LOGICAL_MODE; + dest_id = (MSI_ADDRESS_HEADER << MSI_ADDRESS_HEADER_SHIFT); + msi_address->lo_address.u.dest_mode = MSI_DEST_MODE; msi_address->lo_address.u.redirection_hint = MSI_REDIRECTION_HINT_MODE; msi_address->lo_address.u.dest_id = dest_id; -} - -static int pci_vector_resources(void) -{ - static int res = -EINVAL; - int nr_free_vectors; - - if (res == -EINVAL) { - int i, repeat; - for (i = NR_REPEATS; i > 0; i--) { - if ((FIRST_DEVICE_VECTOR + i * 8) > FIRST_SYSTEM_VECTOR) - continue; - break; - } - i++; - repeat = (FIRST_SYSTEM_VECTOR - FIRST_DEVICE_VECTOR)/i; - res = i * repeat - NR_RESERVED_VECTORS + 1; - } - - nr_free_vectors = res + nr_released_vectors - nr_alloc_vectors; - - return nr_free_vectors; -} - -int assign_irq_vector(int irq) -{ - static int current_vector = FIRST_DEVICE_VECTOR, offset = 0; - - if (irq != MSI_AUTO && IO_APIC_VECTOR(irq) > 0) - return IO_APIC_VECTOR(irq); -next: - current_vector += 8; - if (current_vector == SYSCALL_VECTOR) - goto next; - - if (current_vector > FIRST_SYSTEM_VECTOR) { - offset++; - current_vector = FIRST_DEVICE_VECTOR + offset; - } - - if (current_vector == FIRST_SYSTEM_VECTOR) - return -ENOSPC; - - vector_irq[current_vector] = irq; - if (irq != MSI_AUTO) - IO_APIC_VECTOR(irq) = current_vector; - - nr_alloc_vectors++; - - return current_vector; + msi_address->lo_address.value |= (MSI_TARGET_CPU << MSI_TARGET_CPU_SHIFT); } static int assign_msi_vector(void) @@ -333,10 +277,6 @@ static int assign_msi_vector(void) * vector is assigned unique among drivers. */ spin_lock_irqsave(&msi_lock, flags); - if (!(pci_vector_resources() > 0)) { - spin_unlock_irqrestore(&msi_lock, flags); - return -EBUSY; - } if (!new_vector_avail) { /* @@ -363,9 +303,9 @@ static int assign_msi_vector(void) spin_unlock_irqrestore(&msi_lock, flags); return -EBUSY; } - - vector = assign_irq_vector(MSI_AUTO); - if (vector == (FIRST_SYSTEM_VECTOR - 8)) + 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); @@ -924,7 +864,8 @@ int msi_alloc_vectors(struct pci_dev* de * msi_lock is provided to ensure that enough vectors resources are * available before granting. */ - free_vectors = pci_vector_resources(); + free_vectors = pci_vector_resources(last_alloc_vector, + nr_released_vectors); /* Ensure that each MSI/MSI-X device has one vector reserved by default to avoid any MSI-X driver to take all available resources */ diff -puN drivers/pci/msi.h~msi-ia64 drivers/pci/msi.h --- 25/drivers/pci/msi.h~msi-ia64 Tue Apr 6 14:31:10 2004 +++ 25-akpm/drivers/pci/msi.h Tue Apr 6 14:31:10 2004 @@ -1,6 +1,4 @@ /* - * File: msi.h - * * Copyright (C) 2003-2004 Intel * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com) */ @@ -8,9 +6,7 @@ #ifndef MSI_H #define MSI_H -#define MSI_AUTO -1 -#define NR_REPEATS 23 -#define NR_RESERVED_VECTORS 3 /*FIRST_DEVICE_VECTOR,FIRST_SYSTEM_VECTOR,0x80 */ +#include /* * Assume the maximum number of hot plug slots supported by the system is about @@ -22,9 +18,10 @@ */ #define NR_HP_RESERVED_VECTORS 20 -extern int vector_irq[NR_IRQS]; +extern int vector_irq[NR_IRQ_VECTORS]; extern cpumask_t pending_irq_balance_cpumask[NR_IRQS]; extern void (*interrupt[NR_IRQS])(void); +extern int pci_vector_resources(int last, int nr_released); #ifdef CONFIG_SMP #define set_msi_irq_affinity set_msi_affinity @@ -36,13 +33,6 @@ extern void (*interrupt[NR_IRQS])(void); static inline void move_msi(int vector) {} #endif -#ifndef CONFIG_X86_IO_APIC -static inline int get_ioapic_vector(struct pci_dev *dev) { return -1;} -static inline void restore_ioapic_irq_handler(int irq) {} -#else -extern void restore_ioapic_irq_handler(int irq); -#endif - /* * MSI-X Address Register */ @@ -85,25 +75,20 @@ extern void restore_ioapic_irq_handler(i #define msix_mask(address) (address | PCI_MSIX_FLAGS_BITMASK) #define msix_is_pending(address) (address & PCI_MSIX_FLAGS_PENDMASK) - /* * MSI Defined Data Structures */ #define MSI_ADDRESS_HEADER 0xfee #define MSI_ADDRESS_HEADER_SHIFT 12 #define MSI_ADDRESS_HEADER_MASK 0xfff000 -#define MSI_TARGET_CPU_SHIFT 4 +#define MSI_ADDRESS_DEST_ID_MASK 0xfff0000f #define MSI_TARGET_CPU_MASK 0xff #define MSI_DELIVERY_MODE 0 #define MSI_LEVEL_MODE 1 /* Edge always assert */ #define MSI_TRIGGER_MODE 0 /* MSI is edge sensitive */ +#define MSI_PHYSICAL_MODE 0 #define MSI_LOGICAL_MODE 1 #define MSI_REDIRECTION_HINT_MODE 0 -#ifdef CONFIG_SMP -#define MSI_TARGET_CPU logical_smp_processor_id() -#else -#define MSI_TARGET_CPU TARGET_CPUS -#endif struct msg_data { #if defined(__LITTLE_ENDIAN_BITFIELD) diff -puN include/asm-i386/hw_irq.h~msi-ia64 include/asm-i386/hw_irq.h --- 25/include/asm-i386/hw_irq.h~msi-ia64 Tue Apr 6 14:31:10 2004 +++ 25-akpm/include/asm-i386/hw_irq.h Tue Apr 6 14:31:10 2004 @@ -27,6 +27,7 @@ extern u8 irq_vector[NR_IRQ_VECTORS]; #define IO_APIC_VECTOR(irq) (irq_vector[irq]) +#define AUTO_ASSIGN -1 extern void (*interrupt[NR_IRQS])(void); diff -puN /dev/null include/asm-i386/msi.h --- /dev/null Thu Apr 11 07:25:15 2002 +++ 25-akpm/include/asm-i386/msi.h Tue Apr 6 14:31:10 2004 @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2003-2004 Intel + * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com) + */ + +#ifndef ASM_MSI_H +#define ASM_MSI_H + +#include +#include + +#define LAST_DEVICE_VECTOR 232 +#define MSI_DEST_MODE MSI_LOGICAL_MODE +#define MSI_TARGET_CPU_SHIFT 12 + +#ifdef CONFIG_SMP +#define MSI_TARGET_CPU logical_smp_processor_id() +#else +#define MSI_TARGET_CPU TARGET_CPUS +#endif + +#endif /* ASM_MSI_H */ diff -puN include/asm-ia64/hw_irq.h~msi-ia64 include/asm-ia64/hw_irq.h --- 25/include/asm-ia64/hw_irq.h~msi-ia64 Tue Apr 6 14:31:10 2004 +++ 25-akpm/include/asm-ia64/hw_irq.h Tue Apr 6 14:31:10 2004 @@ -34,6 +34,8 @@ typedef u8 ia64_vector; #define IA64_MAX_VECTORED_IRQ 255 #define IA64_NUM_VECTORS 256 +#define AUTO_ASSIGN -1 + #define IA64_SPURIOUS_INT_VECTOR 0x0f /* @@ -80,7 +82,7 @@ extern unsigned long ipi_base_addr; extern struct hw_interrupt_type irq_type_ia64_lsapic; /* CPU-internal interrupt controller */ -extern int ia64_alloc_vector (void); /* allocate a free vector */ +extern int assign_irq_vector (int irq); /* allocate a free vector */ extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect); extern void register_percpu_irq (ia64_vector vec, struct irqaction *action); diff -puN include/asm-ia64/irq.h~msi-ia64 include/asm-ia64/irq.h --- 25/include/asm-ia64/irq.h~msi-ia64 Tue Apr 6 14:31:10 2004 +++ 25-akpm/include/asm-ia64/irq.h Tue Apr 6 14:31:10 2004 @@ -12,6 +12,7 @@ */ #define NR_IRQS 256 +#define NR_IRQ_VECTORS NR_IRQS static __inline__ int irq_canonicalize (int irq) diff -puN /dev/null include/asm-ia64/msi.h --- /dev/null Thu Apr 11 07:25:15 2002 +++ 25-akpm/include/asm-ia64/msi.h Tue Apr 6 14:31:10 2004 @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2003-2004 Intel + * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com) + */ + +#ifndef ASM_MSI_H +#define ASM_MSI_H + +#define FIRST_DEVICE_VECTOR IA64_FIRST_DEVICE_VECTOR +#define LAST_DEVICE_VECTOR IA64_LAST_DEVICE_VECTOR +static inline void set_intr_gate (int nr, void *func) {} +#define IO_APIC_VECTOR(irq) (irq) +#define ack_APIC_irq ia64_eoi +#define irq_desc _irq_desc +#define cpu_mask_to_apicid(mask) cpu_physical_id(first_cpu(mask)) +#define MSI_DEST_MODE MSI_PHYSICAL_MODE +#define MSI_TARGET_CPU ((ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff) +#define MSI_TARGET_CPU_SHIFT 4 + +#endif /* ASM_MSI_H */ diff -puN /dev/null include/asm-x86_64/msi.h --- /dev/null Thu Apr 11 07:25:15 2002 +++ 25-akpm/include/asm-x86_64/msi.h Tue Apr 6 14:31:10 2004 @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2003-2004 Intel + * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com) + */ + +#ifndef ASM_MSI_H +#define ASM_MSI_H + +#include + +#define LAST_DEVICE_VECTOR 232 +#define MSI_DEST_MODE MSI_LOGICAL_MODE +#define MSI_TARGET_CPU_SHIFT 12 + +#ifdef CONFIG_SMP +#define MSI_TARGET_CPU logical_smp_processor_id() +#else +#define MSI_TARGET_CPU TARGET_CPUS +#endif + +#endif /* ASM_MSI_H */ _