aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/msi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/msi.c')
-rw-r--r--drivers/pci/msi.c105
1 files changed, 72 insertions, 33 deletions
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 48723d6fa60f..a77e79c8c82e 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -103,9 +103,9 @@ static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask)
103 switch (entry->msi_attrib.type) { 103 switch (entry->msi_attrib.type) {
104 case PCI_CAP_ID_MSI: 104 case PCI_CAP_ID_MSI:
105 { 105 {
106 int pos; 106 int pos = pci_find_capability(entry->dev, PCI_CAP_ID_MSI);
107 107
108 if (!(pos = pci_find_capability(entry->dev, PCI_CAP_ID_MSI))) 108 if (!pos)
109 return; 109 return;
110 110
111 pci_read_config_dword(entry->dev, msi_lower_address_reg(pos), 111 pci_read_config_dword(entry->dev, msi_lower_address_reg(pos),
@@ -347,9 +347,9 @@ static int assign_msi_vector(void)
347 347
348static int get_new_vector(void) 348static int get_new_vector(void)
349{ 349{
350 int vector; 350 int vector = assign_msi_vector();
351 351
352 if ((vector = assign_msi_vector()) > 0) 352 if (vector > 0)
353 set_intr_gate(vector, interrupt[vector]); 353 set_intr_gate(vector, interrupt[vector]);
354 354
355 return vector; 355 return vector;
@@ -369,7 +369,8 @@ static int msi_init(void)
369 return status; 369 return status;
370 } 370 }
371 371
372 if ((status = msi_cache_init()) < 0) { 372 status = msi_cache_init();
373 if (status < 0) {
373 pci_msi_enable = 0; 374 pci_msi_enable = 0;
374 printk(KERN_WARNING "PCI: MSI cache init failed\n"); 375 printk(KERN_WARNING "PCI: MSI cache init failed\n");
375 return status; 376 return status;
@@ -523,10 +524,12 @@ static int msi_capability_init(struct pci_dev *dev)
523 pos = pci_find_capability(dev, PCI_CAP_ID_MSI); 524 pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
524 pci_read_config_word(dev, msi_control_reg(pos), &control); 525 pci_read_config_word(dev, msi_control_reg(pos), &control);
525 /* MSI Entry Initialization */ 526 /* MSI Entry Initialization */
526 if (!(entry = alloc_msi_entry())) 527 entry = alloc_msi_entry();
528 if (!entry)
527 return -ENOMEM; 529 return -ENOMEM;
528 530
529 if ((vector = get_msi_vector(dev)) < 0) { 531 vector = get_msi_vector(dev);
532 if (vector < 0) {
530 kmem_cache_free(msi_cachep, entry); 533 kmem_cache_free(msi_cachep, entry);
531 return -EBUSY; 534 return -EBUSY;
532 } 535 }
@@ -597,7 +600,8 @@ static int msix_capability_init(struct pci_dev *dev,
597 struct msg_address address; 600 struct msg_address address;
598 struct msg_data data; 601 struct msg_data data;
599 int vector, pos, i, j, nr_entries, temp = 0; 602 int vector, pos, i, j, nr_entries, temp = 0;
600 u32 phys_addr, table_offset; 603 unsigned long phys_addr;
604 u32 table_offset;
601 u16 control; 605 u16 control;
602 u8 bir; 606 u8 bir;
603 void __iomem *base; 607 void __iomem *base;
@@ -606,11 +610,11 @@ static int msix_capability_init(struct pci_dev *dev,
606 /* Request & Map MSI-X table region */ 610 /* Request & Map MSI-X table region */
607 pci_read_config_word(dev, msi_control_reg(pos), &control); 611 pci_read_config_word(dev, msi_control_reg(pos), &control);
608 nr_entries = multi_msix_capable(control); 612 nr_entries = multi_msix_capable(control);
609 pci_read_config_dword(dev, msix_table_offset_reg(pos), 613
610 &table_offset); 614 pci_read_config_dword(dev, msix_table_offset_reg(pos), &table_offset);
611 bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK); 615 bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK);
612 phys_addr = pci_resource_start (dev, bir); 616 table_offset &= ~PCI_MSIX_FLAGS_BIRMASK;
613 phys_addr += (u32)(table_offset & ~PCI_MSIX_FLAGS_BIRMASK); 617 phys_addr = pci_resource_start (dev, bir) + table_offset;
614 base = ioremap_nocache(phys_addr, nr_entries * PCI_MSIX_ENTRY_SIZE); 618 base = ioremap_nocache(phys_addr, nr_entries * PCI_MSIX_ENTRY_SIZE);
615 if (base == NULL) 619 if (base == NULL)
616 return -ENOMEM; 620 return -ENOMEM;
@@ -620,7 +624,8 @@ static int msix_capability_init(struct pci_dev *dev,
620 entry = alloc_msi_entry(); 624 entry = alloc_msi_entry();
621 if (!entry) 625 if (!entry)
622 break; 626 break;
623 if ((vector = get_msi_vector(dev)) < 0) 627 vector = get_msi_vector(dev);
628 if (vector < 0)
624 break; 629 break;
625 630
626 j = entries[i].entry; 631 j = entries[i].entry;
@@ -699,12 +704,17 @@ int pci_enable_msi(struct pci_dev* dev)
699 if (dev->no_msi) 704 if (dev->no_msi)
700 return status; 705 return status;
701 706
707 if (dev->bus->bus_flags & PCI_BUS_FLAGS_NO_MSI)
708 return -EINVAL;
709
702 temp = dev->irq; 710 temp = dev->irq;
703 711
704 if ((status = msi_init()) < 0) 712 status = msi_init();
713 if (status < 0)
705 return status; 714 return status;
706 715
707 if (!(pos = pci_find_capability(dev, PCI_CAP_ID_MSI))) 716 pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
717 if (!pos)
708 return -EINVAL; 718 return -EINVAL;
709 719
710 pci_read_config_word(dev, msi_control_reg(pos), &control); 720 pci_read_config_word(dev, msi_control_reg(pos), &control);
@@ -728,8 +738,8 @@ int pci_enable_msi(struct pci_dev* dev)
728 dev->irq = temp; 738 dev->irq = temp;
729 } 739 }
730 /* Check whether driver already requested for MSI-X vectors */ 740 /* Check whether driver already requested for MSI-X vectors */
731 if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSIX)) > 0 && 741 pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
732 !msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) { 742 if (pos > 0 && !msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) {
733 printk(KERN_INFO "PCI: %s: Can't enable MSI. " 743 printk(KERN_INFO "PCI: %s: Can't enable MSI. "
734 "Device already has MSI-X vectors assigned\n", 744 "Device already has MSI-X vectors assigned\n",
735 pci_name(dev)); 745 pci_name(dev));
@@ -755,7 +765,13 @@ void pci_disable_msi(struct pci_dev* dev)
755 u16 control; 765 u16 control;
756 unsigned long flags; 766 unsigned long flags;
757 767
758 if (!dev || !(pos = pci_find_capability(dev, PCI_CAP_ID_MSI))) 768 if (!pci_msi_enable)
769 return;
770 if (!dev)
771 return;
772
773 pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
774 if (!pos)
759 return; 775 return;
760 776
761 pci_read_config_word(dev, msi_control_reg(pos), &control); 777 pci_read_config_word(dev, msi_control_reg(pos), &control);
@@ -826,8 +842,10 @@ static int msi_free_vector(struct pci_dev* dev, int vector, int reassign)
826 * Detect last MSI-X vector to be released. 842 * Detect last MSI-X vector to be released.
827 * Release the MSI-X memory-mapped table. 843 * Release the MSI-X memory-mapped table.
828 */ 844 */
845#if 0
829 int pos, nr_entries; 846 int pos, nr_entries;
830 u32 phys_addr, table_offset; 847 unsigned long phys_addr;
848 u32 table_offset;
831 u16 control; 849 u16 control;
832 u8 bir; 850 u8 bir;
833 851
@@ -838,9 +856,12 @@ static int msi_free_vector(struct pci_dev* dev, int vector, int reassign)
838 pci_read_config_dword(dev, msix_table_offset_reg(pos), 856 pci_read_config_dword(dev, msix_table_offset_reg(pos),
839 &table_offset); 857 &table_offset);
840 bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK); 858 bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK);
841 phys_addr = pci_resource_start (dev, bir); 859 table_offset &= ~PCI_MSIX_FLAGS_BIRMASK;
842 phys_addr += (u32)(table_offset & 860 phys_addr = pci_resource_start(dev, bir) + table_offset;
843 ~PCI_MSIX_FLAGS_BIRMASK); 861/*
862 * FIXME! and what did you want to do with phys_addr?
863 */
864#endif
844 iounmap(base); 865 iounmap(base);
845 } 866 }
846 } 867 }
@@ -924,10 +945,12 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
924 if (!pci_msi_enable || !dev || !entries) 945 if (!pci_msi_enable || !dev || !entries)
925 return -EINVAL; 946 return -EINVAL;
926 947
927 if ((status = msi_init()) < 0) 948 status = msi_init();
949 if (status < 0)
928 return status; 950 return status;
929 951
930 if (!(pos = pci_find_capability(dev, PCI_CAP_ID_MSIX))) 952 pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
953 if (!pos)
931 return -EINVAL; 954 return -EINVAL;
932 955
933 pci_read_config_word(dev, msi_control_reg(pos), &control); 956 pci_read_config_word(dev, msi_control_reg(pos), &control);
@@ -1006,7 +1029,13 @@ void pci_disable_msix(struct pci_dev* dev)
1006 int pos, temp; 1029 int pos, temp;
1007 u16 control; 1030 u16 control;
1008 1031
1009 if (!dev || !(pos = pci_find_capability(dev, PCI_CAP_ID_MSIX))) 1032 if (!pci_msi_enable)
1033 return;
1034 if (!dev)
1035 return;
1036
1037 pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
1038 if (!pos)
1010 return; 1039 return;
1011 1040
1012 pci_read_config_word(dev, msi_control_reg(pos), &control); 1041 pci_read_config_word(dev, msi_control_reg(pos), &control);
@@ -1066,8 +1095,8 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev)
1066 return; 1095 return;
1067 1096
1068 temp = dev->irq; /* Save IOAPIC IRQ */ 1097 temp = dev->irq; /* Save IOAPIC IRQ */
1069 if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSI)) > 0 && 1098 pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
1070 !msi_lookup_vector(dev, PCI_CAP_ID_MSI)) { 1099 if (pos > 0 && !msi_lookup_vector(dev, PCI_CAP_ID_MSI)) {
1071 spin_lock_irqsave(&msi_lock, flags); 1100 spin_lock_irqsave(&msi_lock, flags);
1072 state = msi_desc[dev->irq]->msi_attrib.state; 1101 state = msi_desc[dev->irq]->msi_attrib.state;
1073 spin_unlock_irqrestore(&msi_lock, flags); 1102 spin_unlock_irqrestore(&msi_lock, flags);
@@ -1080,8 +1109,8 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev)
1080 msi_free_vector(dev, dev->irq, 0); 1109 msi_free_vector(dev, dev->irq, 0);
1081 dev->irq = temp; /* Restore IOAPIC IRQ */ 1110 dev->irq = temp; /* Restore IOAPIC IRQ */
1082 } 1111 }
1083 if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSIX)) > 0 && 1112 pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
1084 !msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) { 1113 if (pos > 0 && !msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) {
1085 int vector, head, tail = 0, warning = 0; 1114 int vector, head, tail = 0, warning = 0;
1086 void __iomem *base = NULL; 1115 void __iomem *base = NULL;
1087 1116
@@ -1101,7 +1130,9 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev)
1101 msi_free_vector(dev, vector, 0); 1130 msi_free_vector(dev, vector, 0);
1102 if (warning) { 1131 if (warning) {
1103 /* Force to release the MSI-X memory-mapped table */ 1132 /* Force to release the MSI-X memory-mapped table */
1104 u32 phys_addr, table_offset; 1133#if 0
1134 unsigned long phys_addr;
1135 u32 table_offset;
1105 u16 control; 1136 u16 control;
1106 u8 bir; 1137 u8 bir;
1107 1138
@@ -1110,9 +1141,12 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev)
1110 pci_read_config_dword(dev, msix_table_offset_reg(pos), 1141 pci_read_config_dword(dev, msix_table_offset_reg(pos),
1111 &table_offset); 1142 &table_offset);
1112 bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK); 1143 bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK);
1113 phys_addr = pci_resource_start (dev, bir); 1144 table_offset &= ~PCI_MSIX_FLAGS_BIRMASK;
1114 phys_addr += (u32)(table_offset & 1145 phys_addr = pci_resource_start(dev, bir) + table_offset;
1115 ~PCI_MSIX_FLAGS_BIRMASK); 1146/*
1147 * FIXME! and what did you want to do with phys_addr?
1148 */
1149#endif
1116 iounmap(base); 1150 iounmap(base);
1117 printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() " 1151 printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() "
1118 "called without free_irq() on all MSI-X vectors\n", 1152 "called without free_irq() on all MSI-X vectors\n",
@@ -1123,6 +1157,11 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev)
1123 } 1157 }
1124} 1158}
1125 1159
1160void pci_no_msi(void)
1161{
1162 pci_msi_enable = 0;
1163}
1164
1126EXPORT_SYMBOL(pci_enable_msi); 1165EXPORT_SYMBOL(pci_enable_msi);
1127EXPORT_SYMBOL(pci_disable_msi); 1166EXPORT_SYMBOL(pci_disable_msi);
1128EXPORT_SYMBOL(pci_enable_msix); 1167EXPORT_SYMBOL(pci_enable_msix);