Commit 9938e2c2 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] ia64 MSI support

From: "Nguyen, Tom L" <tom.l.nguyen@intel.com>

Adds MSI support for ia64.

- Modified existing code in drivers/pci/msi.c and drivers/pci/msi.h to
  include MSI support on IA64 platform.

- Based on the comments received from Zwane Mwaikambo and David Mosberger,
  this patch consolidates the vector allocators as
  assign_irq_vector(AUTO_ASSIGN) has the same semantics as
  ia64_alloc_vector() by converting the existing uses of ia64_alloc_vector()
  to assign_irq_vector(AUTO_ASSIGN).

- Based on the comments received from Zwane Mwaikambo, this patch
  consolidates the semantics of vector allocator assign_irq_vector() in
  drivers/pci/msi.c into the relevant architecture's vector allocator
  assign_irq_vector() in arch/i386/kernel/io_apic.c.

- Regarding vector allocation, this patch modifies the existing function
  assign_irq_vector() to maximize the number of allocated vectors to 188
  before going -ENOSPC.

- Based on your comments, this patch creates <asm-i386/msi.h>,
  <asm-ia64/msi.h> and <asm-x86_64/msi.h>, includes <asm/msi.h> from within
  drivers/pci/msi.h and then places all the code which is currently under
  ifdef in msi.h into the relevant architecture's <asm/msi.h> file.

- Based on your comments, this patch places pci_vector_resources() in
  existing drivers/pci/msi.c in the relevant architecture implementations
  such as into arch/.../pci/irq.c.
parent 27b5c750
...@@ -76,8 +76,8 @@ static struct irq_pin_list { ...@@ -76,8 +76,8 @@ static struct irq_pin_list {
int apic, pin, next; int apic, pin, next;
} irq_2_pin[PIN_MAP_SIZE]; } irq_2_pin[PIN_MAP_SIZE];
int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1};
#ifdef CONFIG_PCI_USE_VECTOR #ifdef CONFIG_PCI_USE_VECTOR
int vector_irq[NR_IRQS] = { [0 ... NR_IRQS -1] = -1};
#define vector_to_irq(vector) \ #define vector_to_irq(vector) \
(platform_legacy_irq(vector) ? vector : vector_irq[vector]) (platform_legacy_irq(vector) ? vector : vector_irq[vector])
#else #else
...@@ -1149,12 +1149,16 @@ static inline int IO_APIC_irq_trigger(int irq) ...@@ -1149,12 +1149,16 @@ static inline int IO_APIC_irq_trigger(int irq)
/* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */ /* 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 }; 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) int __init assign_irq_vector(int irq)
#endif
{ {
static int current_vector = FIRST_DEVICE_VECTOR, offset = 0; static int current_vector = FIRST_DEVICE_VECTOR, offset = 0;
BUG_ON(irq >= NR_IRQ_VECTORS); 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); return IO_APIC_VECTOR(irq);
next: next:
current_vector += 8; current_vector += 8;
...@@ -1162,15 +1166,18 @@ int __init assign_irq_vector(int irq) ...@@ -1162,15 +1166,18 @@ int __init assign_irq_vector(int irq)
goto next; goto next;
if (current_vector >= FIRST_SYSTEM_VECTOR) { if (current_vector >= FIRST_SYSTEM_VECTOR) {
offset = (offset + 1) & 7; offset++;
if (!(offset%8))
return -ENOSPC;
current_vector = FIRST_DEVICE_VECTOR + offset; 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; return current_vector;
} }
#endif
static struct hw_interrupt_type ioapic_level_type; static struct hw_interrupt_type ioapic_level_type;
static struct hw_interrupt_type ioapic_edge_type; static struct hw_interrupt_type ioapic_edge_type;
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/smp.h> #include <asm/smp.h>
#include <asm/io_apic.h> #include <asm/io_apic.h>
#include <asm/hw_irq.h>
#include "pci.h" #include "pci.h"
...@@ -1005,3 +1006,33 @@ int pirq_enable_irq(struct pci_dev *dev) ...@@ -1005,3 +1006,33 @@ int pirq_enable_irq(struct pci_dev *dev)
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
return 0; 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;
#ifdef CONFIG_X86_64
if (next == IA32_SYSCALL_VECTOR)
continue;
#else
if (next == SYSCALL_VECTOR)
continue;
#endif
count++;
if (next >= FIRST_SYSTEM_VECTOR) {
if (offset%8) {
next = FIRST_DEVICE_VECTOR + offset;
offset++;
continue;
}
count--;
}
}
return count;
}
...@@ -361,6 +361,16 @@ config PCI ...@@ -361,6 +361,16 @@ config PCI
information about which PCI hardware does work under Linux and which information about which PCI hardware does work under Linux and which
doesn't. 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 config PCI_DOMAINS
bool bool
default PCI default PCI
......
...@@ -228,7 +228,7 @@ simeth_probe1(void) ...@@ -228,7 +228,7 @@ simeth_probe1(void)
return err; return err;
} }
dev->irq = ia64_alloc_vector(); dev->irq = assign_irq_vector(AUTO_ASSIGN);
/* /*
* attach the interrupt in the simulator, this does enable interrupts * attach the interrupt in the simulator, this does enable interrupts
......
...@@ -1051,7 +1051,7 @@ simrs_init (void) ...@@ -1051,7 +1051,7 @@ simrs_init (void)
if (state->type == PORT_UNKNOWN) continue; if (state->type == PORT_UNKNOWN) continue;
if (!state->irq) { if (!state->irq) {
state->irq = ia64_alloc_vector(); state->irq = assign_irq_vector(AUTO_ASSIGN);
ia64_ssc_connect_irq(KEYBOARD_INTR, state->irq); ia64_ssc_connect_irq(KEYBOARD_INTR, state->irq);
} }
......
...@@ -435,7 +435,7 @@ iosapic_reassign_vector (int vector) ...@@ -435,7 +435,7 @@ iosapic_reassign_vector (int vector)
|| iosapic_intr_info[vector].gsi_base || iosapic_intr_info[vector].dmode || iosapic_intr_info[vector].gsi_base || iosapic_intr_info[vector].dmode
|| iosapic_intr_info[vector].polarity || iosapic_intr_info[vector].trigger) || 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); printk(KERN_INFO "Reassigning vector %d to %d\n", vector, new_vector);
memcpy(&iosapic_intr_info[new_vector], &iosapic_intr_info[vector], memcpy(&iosapic_intr_info[new_vector], &iosapic_intr_info[vector],
sizeof(struct iosapic_intr_info)); sizeof(struct iosapic_intr_info));
...@@ -500,7 +500,7 @@ iosapic_register_intr (unsigned int gsi, ...@@ -500,7 +500,7 @@ iosapic_register_intr (unsigned int gsi,
vector = gsi_to_vector(gsi); vector = gsi_to_vector(gsi);
if (vector < 0) if (vector < 0)
vector = ia64_alloc_vector(); vector = assign_irq_vector(AUTO_ASSIGN);
register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY,
polarity, trigger); polarity, trigger);
...@@ -538,7 +538,7 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi, ...@@ -538,7 +538,7 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi,
delivery = IOSAPIC_PMI; delivery = IOSAPIC_PMI;
break; break;
case ACPI_INTERRUPT_INIT: case ACPI_INTERRUPT_INIT:
vector = ia64_alloc_vector(); vector = assign_irq_vector(AUTO_ASSIGN);
delivery = IOSAPIC_INIT; delivery = IOSAPIC_INIT;
break; break;
case ACPI_INTERRUPT_CPEI: case ACPI_INTERRUPT_CPEI:
...@@ -708,7 +708,7 @@ iosapic_parse_prt (void) ...@@ -708,7 +708,7 @@ iosapic_parse_prt (void)
vector = isa_irq_to_vector(gsi); vector = isa_irq_to_vector(gsi);
else else
/* new GSI; allocate a vector for it */ /* 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, register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, IOSAPIC_POL_LOW,
IOSAPIC_LEVEL); IOSAPIC_LEVEL);
......
...@@ -73,13 +73,13 @@ irq_exit (void) ...@@ -73,13 +73,13 @@ irq_exit (void)
} }
int int
ia64_alloc_vector (void) assign_irq_vector (int irq)
{ {
static int next_vector = IA64_FIRST_DEVICE_VECTOR; static int next_vector = IA64_FIRST_DEVICE_VECTOR;
if (next_vector > IA64_LAST_DEVICE_VECTOR) if (next_vector > IA64_LAST_DEVICE_VECTOR)
/* XXX could look for sharable vectors instead of panic'ing... */ /* 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++; return next_vector++;
} }
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
# include <asm/smp.h> # include <asm/smp.h>
#endif #endif
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/hw_irq.h>
#undef DEBUG #undef DEBUG
...@@ -567,3 +568,12 @@ pcibios_prep_mwi (struct pci_dev *dev) ...@@ -567,3 +568,12 @@ pcibios_prep_mwi (struct pci_dev *dev)
} }
return rc; return rc;
} }
int pci_vector_resources(int last, int nr_released)
{
int count = nr_released;
count += (IA64_LAST_DEVICE_VECTOR - last);
return count;
}
...@@ -19,26 +19,22 @@ ...@@ -19,26 +19,22 @@
#include <asm/errno.h> #include <asm/errno.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/smp.h> #include <asm/smp.h>
#include <asm/desc.h>
#include <asm/io_apic.h>
#include <mach_apic.h>
#include "msi.h" #include "msi.h"
static spinlock_t msi_lock = SPIN_LOCK_UNLOCKED; static spinlock_t msi_lock = SPIN_LOCK_UNLOCKED;
static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL }; static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL };
static kmem_cache_t* msi_cachep; static kmem_cache_t* msi_cachep;
static int pci_msi_enable = 1; 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_released_vectors = 0;
static int nr_reserved_vectors = NR_HP_RESERVED_VECTORS; static int nr_reserved_vectors = NR_HP_RESERVED_VECTORS;
static int nr_msix_devices = 0; static int nr_msix_devices = 0;
#ifndef CONFIG_X86_IO_APIC #ifndef CONFIG_X86_IO_APIC
int vector_irq[NR_IRQS] = { [0 ... NR_IRQS -1] = -1}; int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1};
u8 irq_vector[NR_IRQS] = { FIRST_DEVICE_VECTOR , 0 }; u8 irq_vector[NR_IRQ_VECTORS] = { FIRST_DEVICE_VECTOR , 0 };
#endif #endif
static void msi_cache_ctor(void *p, kmem_cache_t *cache, unsigned long flags) static void msi_cache_ctor(void *p, kmem_cache_t *cache, unsigned long flags)
...@@ -96,7 +92,6 @@ static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask) ...@@ -96,7 +92,6 @@ static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask)
{ {
struct msi_desc *entry; struct msi_desc *entry;
struct msg_address address; struct msg_address address;
unsigned int dest_id;
entry = (struct msi_desc *)msi_desc[vector]; entry = (struct msi_desc *)msi_desc[vector];
if (!entry || !entry->dev) if (!entry || !entry->dev)
...@@ -113,10 +108,9 @@ static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask) ...@@ -113,10 +108,9 @@ static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask)
entry->dev->bus->ops->read(entry->dev->bus, entry->dev->devfn, entry->dev->bus->ops->read(entry->dev->bus, entry->dev->devfn,
msi_lower_address_reg(pos), 4, msi_lower_address_reg(pos), 4,
&address.lo_address.value); &address.lo_address.value);
dest_id = (address.lo_address.u.dest_id & address.lo_address.value &= MSI_ADDRESS_DEST_ID_MASK;
MSI_ADDRESS_HEADER_MASK) | address.lo_address.value |= (cpu_mask_to_apicid(cpu_mask) <<
(cpu_mask_to_apicid(cpu_mask) << MSI_TARGET_CPU_SHIFT); MSI_TARGET_CPU_SHIFT);
address.lo_address.u.dest_id = dest_id;
entry->msi_attrib.current_cpu = cpu_mask_to_apicid(cpu_mask); entry->msi_attrib.current_cpu = cpu_mask_to_apicid(cpu_mask);
entry->dev->bus->ops->write(entry->dev->bus, entry->dev->devfn, entry->dev->bus->ops->write(entry->dev->bus, entry->dev->devfn,
msi_lower_address_reg(pos), 4, msi_lower_address_reg(pos), 4,
...@@ -129,10 +123,9 @@ static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask) ...@@ -129,10 +123,9 @@ static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask)
PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET; PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET;
address.lo_address.value = readl(entry->mask_base + offset); address.lo_address.value = readl(entry->mask_base + offset);
dest_id = (address.lo_address.u.dest_id & address.lo_address.value &= MSI_ADDRESS_DEST_ID_MASK;
MSI_ADDRESS_HEADER_MASK) | address.lo_address.value |= (cpu_mask_to_apicid(cpu_mask) <<
(cpu_mask_to_apicid(cpu_mask) << MSI_TARGET_CPU_SHIFT); MSI_TARGET_CPU_SHIFT);
address.lo_address.u.dest_id = dest_id;
entry->msi_attrib.current_cpu = cpu_mask_to_apicid(cpu_mask); entry->msi_attrib.current_cpu = cpu_mask_to_apicid(cpu_mask);
writel(address.lo_address.value, entry->mask_base + offset); writel(address.lo_address.value, entry->mask_base + offset);
break; break;
...@@ -265,61 +258,11 @@ static void msi_address_init(struct msg_address *msi_address) ...@@ -265,61 +258,11 @@ static void msi_address_init(struct msg_address *msi_address)
memset(msi_address, 0, sizeof(struct msg_address)); memset(msi_address, 0, sizeof(struct msg_address));
msi_address->hi_address = (u32)0; msi_address->hi_address = (u32)0;
dest_id = (MSI_ADDRESS_HEADER << MSI_ADDRESS_HEADER_SHIFT) | dest_id = (MSI_ADDRESS_HEADER << MSI_ADDRESS_HEADER_SHIFT);
(MSI_TARGET_CPU << MSI_TARGET_CPU_SHIFT); msi_address->lo_address.u.dest_mode = MSI_DEST_MODE;
msi_address->lo_address.u.dest_mode = MSI_LOGICAL_MODE;
msi_address->lo_address.u.redirection_hint = MSI_REDIRECTION_HINT_MODE; msi_address->lo_address.u.redirection_hint = MSI_REDIRECTION_HINT_MODE;
msi_address->lo_address.u.dest_id = dest_id; msi_address->lo_address.u.dest_id = dest_id;
} msi_address->lo_address.value |= (MSI_TARGET_CPU << MSI_TARGET_CPU_SHIFT);
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;
} }
static int assign_msi_vector(void) static int assign_msi_vector(void)
...@@ -333,10 +276,6 @@ static int assign_msi_vector(void) ...@@ -333,10 +276,6 @@ static int assign_msi_vector(void)
* vector is assigned unique among drivers. * vector is assigned unique among drivers.
*/ */
spin_lock_irqsave(&msi_lock, flags); spin_lock_irqsave(&msi_lock, flags);
if (!(pci_vector_resources() > 0)) {
spin_unlock_irqrestore(&msi_lock, flags);
return -EBUSY;
}
if (!new_vector_avail) { if (!new_vector_avail) {
/* /*
...@@ -363,9 +302,9 @@ static int assign_msi_vector(void) ...@@ -363,9 +302,9 @@ static int assign_msi_vector(void)
spin_unlock_irqrestore(&msi_lock, flags); spin_unlock_irqrestore(&msi_lock, flags);
return -EBUSY; return -EBUSY;
} }
vector = assign_irq_vector(AUTO_ASSIGN);
vector = assign_irq_vector(MSI_AUTO); last_alloc_vector = vector;
if (vector == (FIRST_SYSTEM_VECTOR - 8)) if (vector == LAST_DEVICE_VECTOR)
new_vector_avail = 0; new_vector_avail = 0;
spin_unlock_irqrestore(&msi_lock, flags); spin_unlock_irqrestore(&msi_lock, flags);
...@@ -924,7 +863,8 @@ int msi_alloc_vectors(struct pci_dev* dev, int *vector, int nvec) ...@@ -924,7 +863,8 @@ int msi_alloc_vectors(struct pci_dev* dev, int *vector, int nvec)
* msi_lock is provided to ensure that enough vectors resources are * msi_lock is provided to ensure that enough vectors resources are
* available before granting. * 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 /* Ensure that each MSI/MSI-X device has one vector reserved by
default to avoid any MSI-X driver to take all available default to avoid any MSI-X driver to take all available
resources */ resources */
......
/* /*
* File: msi.h
*
* Copyright (C) 2003-2004 Intel * Copyright (C) 2003-2004 Intel
* Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com) * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
*/ */
...@@ -8,9 +6,7 @@ ...@@ -8,9 +6,7 @@
#ifndef MSI_H #ifndef MSI_H
#define MSI_H #define MSI_H
#define MSI_AUTO -1 #include <asm/msi.h>
#define NR_REPEATS 23
#define NR_RESERVED_VECTORS 3 /*FIRST_DEVICE_VECTOR,FIRST_SYSTEM_VECTOR,0x80 */
/* /*
* Assume the maximum number of hot plug slots supported by the system is about * Assume the maximum number of hot plug slots supported by the system is about
...@@ -22,9 +18,10 @@ ...@@ -22,9 +18,10 @@
*/ */
#define NR_HP_RESERVED_VECTORS 20 #define NR_HP_RESERVED_VECTORS 20
extern int vector_irq[NR_IRQS]; extern int vector_irq[NR_VECTORS];
extern cpumask_t pending_irq_balance_cpumask[NR_IRQS]; extern cpumask_t pending_irq_balance_cpumask[NR_IRQS];
extern void (*interrupt[NR_IRQS])(void); extern void (*interrupt[NR_IRQS])(void);
extern int pci_vector_resources(int last, int nr_released);
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
#define set_msi_irq_affinity set_msi_affinity #define set_msi_irq_affinity set_msi_affinity
...@@ -36,13 +33,6 @@ extern void (*interrupt[NR_IRQS])(void); ...@@ -36,13 +33,6 @@ extern void (*interrupt[NR_IRQS])(void);
static inline void move_msi(int vector) {} static inline void move_msi(int vector) {}
#endif #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 * MSI-X Address Register
*/ */
...@@ -85,25 +75,20 @@ extern void restore_ioapic_irq_handler(int irq); ...@@ -85,25 +75,20 @@ extern void restore_ioapic_irq_handler(int irq);
#define msix_mask(address) (address | PCI_MSIX_FLAGS_BITMASK) #define msix_mask(address) (address | PCI_MSIX_FLAGS_BITMASK)
#define msix_is_pending(address) (address & PCI_MSIX_FLAGS_PENDMASK) #define msix_is_pending(address) (address & PCI_MSIX_FLAGS_PENDMASK)
/* /*
* MSI Defined Data Structures * MSI Defined Data Structures
*/ */
#define MSI_ADDRESS_HEADER 0xfee #define MSI_ADDRESS_HEADER 0xfee
#define MSI_ADDRESS_HEADER_SHIFT 12 #define MSI_ADDRESS_HEADER_SHIFT 12
#define MSI_ADDRESS_HEADER_MASK 0xfff000 #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_TARGET_CPU_MASK 0xff
#define MSI_DELIVERY_MODE 0 #define MSI_DELIVERY_MODE 0
#define MSI_LEVEL_MODE 1 /* Edge always assert */ #define MSI_LEVEL_MODE 1 /* Edge always assert */
#define MSI_TRIGGER_MODE 0 /* MSI is edge sensitive */ #define MSI_TRIGGER_MODE 0 /* MSI is edge sensitive */
#define MSI_PHYSICAL_MODE 0
#define MSI_LOGICAL_MODE 1 #define MSI_LOGICAL_MODE 1
#define MSI_REDIRECTION_HINT_MODE 0 #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 { struct msg_data {
#if defined(__LITTLE_ENDIAN_BITFIELD) #if defined(__LITTLE_ENDIAN_BITFIELD)
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
extern u8 irq_vector[NR_IRQ_VECTORS]; extern u8 irq_vector[NR_IRQ_VECTORS];
#define IO_APIC_VECTOR(irq) (irq_vector[irq]) #define IO_APIC_VECTOR(irq) (irq_vector[irq])
#define AUTO_ASSIGN -1
extern void (*interrupt[NR_IRQS])(void); extern void (*interrupt[NR_IRQS])(void);
......
/*
* Copyright (C) 2003-2004 Intel
* Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
*/
#ifndef ASM_MSI_H
#define ASM_MSI_H
#include <asm/desc.h>
#include <mach_apic.h>
#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 */
...@@ -34,6 +34,8 @@ typedef u8 ia64_vector; ...@@ -34,6 +34,8 @@ typedef u8 ia64_vector;
#define IA64_MAX_VECTORED_IRQ 255 #define IA64_MAX_VECTORED_IRQ 255
#define IA64_NUM_VECTORS 256 #define IA64_NUM_VECTORS 256
#define AUTO_ASSIGN -1
#define IA64_SPURIOUS_INT_VECTOR 0x0f #define IA64_SPURIOUS_INT_VECTOR 0x0f
/* /*
...@@ -80,7 +82,7 @@ extern unsigned long ipi_base_addr; ...@@ -80,7 +82,7 @@ extern unsigned long ipi_base_addr;
extern struct hw_interrupt_type irq_type_ia64_lsapic; /* CPU-internal interrupt controller */ 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 ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect);
extern void register_percpu_irq (ia64_vector vec, struct irqaction *action); extern void register_percpu_irq (ia64_vector vec, struct irqaction *action);
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
*/ */
#define NR_IRQS 256 #define NR_IRQS 256
#define NR_IRQ_VECTORS NR_IRQS
static __inline__ int static __inline__ int
irq_canonicalize (int irq) irq_canonicalize (int irq)
......
/*
* 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 */
/*
* Copyright (C) 2003-2004 Intel
* Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
*/
#ifndef ASM_MSI_H
#define ASM_MSI_H
#include <asm/desc.h>
#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 */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment