From: long After testing this patch, I discovered a kernel-built break in UP mode. I am attaching a fix to this issue and minor update as described below: 1. Remove unnecessary header file out of msi.c file 2. Fix a kernel-built break when configuring the kernel in UP mode with - CONFIG_X86_LOCAL_APIC=y - CONFIG_X86_IO_APIC=n 3. Resolve the issue when encountering dev->irq = 0 4. Fix a bug discovered when doing hot-add/hot-remove operations on MSI device drivers/pci/msi.c | 24 +++++++++++++++--------- 1 files changed, 15 insertions(+), 9 deletions(-) diff -puN drivers/pci/msi.c~msi-various-fixes drivers/pci/msi.c --- 25/drivers/pci/msi.c~msi-various-fixes 2003-11-18 20:56:38.000000000 -0800 +++ 25-akpm/drivers/pci/msi.c 2003-11-18 20:56:46.000000000 -0800 @@ -11,7 +11,6 @@ #include #include #include -#include #include #include @@ -36,7 +35,7 @@ static int nr_msix_devices = 0; #ifndef CONFIG_X86_IO_APIC int vector_irq[NR_IRQS] = { [0 ... NR_IRQS -1] = -1}; -int irq_vector[NR_IRQS] = { FIRST_DEVICE_VECTOR , 0 }; +u8 irq_vector[NR_IRQS] = { FIRST_DEVICE_VECTOR , 0 }; #endif static void msi_cache_ctor(void *p, kmem_cache_t *cache, unsigned long flags) @@ -548,8 +547,7 @@ static int msi_capability_init(struct pc if (control & PCI_MSI_FLAGS_ENABLE) return 0; - vector = dev->irq; - if (vector > 0 && !msi_lookup_vector(dev)) { + if (!msi_lookup_vector(dev)) { /* Lookup Sucess */ enable_msi_mode(dev, pos, PCI_CAP_ID_MSI); return 0; @@ -627,7 +625,7 @@ static int msix_capability_init(struct p struct msi_desc *entry; struct msg_address address; struct msg_data data; - int vector, pos, dev_msi_cap; + int vector = 0, pos, dev_msi_cap; u32 phys_addr, table_offset; u32 control; u8 bir; @@ -643,8 +641,7 @@ static int msix_capability_init(struct p if (control & PCI_MSIX_FLAGS_ENABLE) return 0; - vector = dev->irq; - if (vector > 0 && !msi_lookup_vector(dev)) { + if (!msi_lookup_vector(dev)) { /* Lookup Sucess */ enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX); return 0; @@ -1011,12 +1008,20 @@ int msi_free_vectors(struct pci_dev* dev void msi_remove_pci_irq_vectors(struct pci_dev* dev) { struct msi_desc *entry; - int type; + int type, temp; unsigned long flags; - if (!pci_msi_enable) + if (!pci_msi_enable || !dev) return; + if (!pci_find_capability(dev, PCI_CAP_ID_MSI)) { + if (!pci_find_capability(dev, PCI_CAP_ID_MSIX)) + return; + } + temp = dev->irq; + if (msi_lookup_vector(dev)) + return; + spin_lock_irqsave(&msi_lock, flags); entry = msi_desc[dev->irq]; if (!entry || entry->dev != dev) { @@ -1054,6 +1059,7 @@ void msi_remove_pci_irq_vectors(struct p iounmap((void*)entry->mask_base); release_mem_region(phys_addr, dev_msi_cap * PCI_MSIX_ENTRY_SIZE); } + dev->irq = temp; nr_reserved_vectors++; } _