| @@ -192,6 +192,9 @@ static void msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag) · 191 unmodified lines |
| 192 | | 192 | |
| 193 | static void __iomem *pci_msix_desc_addr(struct msi_desc *desc) | 193 | static void __iomem *pci_msix_desc_addr(struct msi_desc *desc) |
| 194 | { | 194 | { |
| | 195 | if (desc->msi_attrib.is_virtual) |
| | 196 | return NULL; |
| | 197 | |
| 195 | return desc->mask_base + | 198 | return desc->mask_base + |
| 196 | desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE; | 199 | desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE; |
| 197 | } | 200 | } |
| @@ -206,14 +209,19 @@ static void __iomem *pci_msix_desc_addr(struct msi_desc *desc) · 8 unmodified lines |
| 206 | u32 __pci_msix_desc_mask_irq(struct msi_desc *desc, u32 flag) | 209 | u32 __pci_msix_desc_mask_irq(struct msi_desc *desc, u32 flag) |
| 207 | { | 210 | { |
| 208 | u32 mask_bits = desc->masked; | 211 | u32 mask_bits = desc->masked; |
| | 212 | void __iomem *desc_addr; |
| 209 | | 213 | |
| 210 | if (pci_msi_ignore_mask) | 214 | if (pci_msi_ignore_mask) |
| 211 | return 0; | 215 | return 0; |
| | 216 | desc_addr = pci_msix_desc_addr(desc); |
| | 217 | if (!desc_addr) |
| | 218 | return 0; |
| 212 | | 219 | |
| 213 | mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT; | 220 | mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT; |
| 214 | if (flag) | 221 | if (flag) |
| 215 | mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT; | 222 | mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT; |
| 216 | writel(mask_bits, pci_msix_desc_addr(desc) + PCI_MSIX_ENTRY_VECTOR_CTRL); | 223 | |
| | 224 | writel(mask_bits, desc_addr + PCI_MSIX_ENTRY_VECTOR_CTRL); |
| 217 | | 225 | |
| 218 | return mask_bits; | 226 | return mask_bits; |
| 219 | } | 227 | } |
| @@ -273,6 +281,11 @@ void __pci_read_msi_msg(struct msi_desc *entry, struct msi_msg *msg) · 53 unmodified lines |
| 273 | if (entry->msi_attrib.is_msix) { | 281 | if (entry->msi_attrib.is_msix) { |
| 274 | void __iomem *base = pci_msix_desc_addr(entry); | 282 | void __iomem *base = pci_msix_desc_addr(entry); |
| 275 | | 283 | |
| | 284 | if (!base) { |
| | 285 | WARN_ON(1); |
| | 286 | return; |
| | 287 | } |
| | 288 | |
| 276 | msg->address_lo = readl(base + PCI_MSIX_ENTRY_LOWER_ADDR); | 289 | msg->address_lo = readl(base + PCI_MSIX_ENTRY_LOWER_ADDR); |
| 277 | msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR); | 290 | msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR); |
| 278 | msg->data = readl(base + PCI_MSIX_ENTRY_DATA); | 291 | msg->data = readl(base + PCI_MSIX_ENTRY_DATA); |
| @@ -303,6 +316,9 @@ void __pci_write_msi_msg(struct msi_desc *entry, struct msi_msg *msg) · 24 unmodified lines |
| 303 | } else if (entry->msi_attrib.is_msix) { | 316 | } else if (entry->msi_attrib.is_msix) { |
| 304 | void __iomem *base = pci_msix_desc_addr(entry); | 317 | void __iomem *base = pci_msix_desc_addr(entry); |
| 305 | | 318 | |
| | 319 | if (!base) |
| | 320 | goto skip; |
| | 321 | |
| 306 | writel(msg->address_lo, base + PCI_MSIX_ENTRY_LOWER_ADDR); | 322 | writel(msg->address_lo, base + PCI_MSIX_ENTRY_LOWER_ADDR); |
| 307 | writel(msg->address_hi, base + PCI_MSIX_ENTRY_UPPER_ADDR); | 323 | writel(msg->address_hi, base + PCI_MSIX_ENTRY_UPPER_ADDR); |
| 308 | writel(msg->data, base + PCI_MSIX_ENTRY_DATA); | 324 | writel(msg->data, base + PCI_MSIX_ENTRY_DATA); |
| @@ -327,7 +343,13 @@ void __pci_write_msi_msg(struct msi_desc *entry, struct msi_msg *msg) · 18 unmodified lines |
| 327 | msg->data); | 343 | msg->data); |
| 328 | } | 344 | } |
| 329 | } | 345 | } |
| | 346 | |
| | 347 | skip: |
| 330 | entry->msg = *msg; | 348 | entry->msg = *msg; |
| | 349 | |
| | 350 | if (entry->write_msi_msg) |
| | 351 | entry->write_msi_msg(entry, entry->write_msi_msg_data); |
| | 352 | |
| 331 | } | 353 | } |
| 332 | | 354 | |
| 333 | void pci_write_msi_msg(unsigned int irq, struct msi_msg *msg) | 355 | void pci_write_msi_msg(unsigned int irq, struct msi_msg *msg) |
| @@ -550,6 +572,7 @@ msi_setup_entry(struct pci_dev *dev, int nvec, struct irq_affinity *affd) · 216 unmodified lines |
| 550 | | 572 | |
| 551 | entry->msi_attrib.is_msix = 0; | 573 | entry->msi_attrib.is_msix = 0; |
| 552 | entry->msi_attrib.is_64 = !!(control & PCI_MSI_FLAGS_64BIT); | 574 | entry->msi_attrib.is_64 = !!(control & PCI_MSI_FLAGS_64BIT); |
| | 575 | entry->msi_attrib.is_virtual = 0; |
| 553 | entry->msi_attrib.entry_nr = 0; | 576 | entry->msi_attrib.entry_nr = 0; |
| 554 | entry->msi_attrib.maskbit = !!(control & PCI_MSI_FLAGS_MASKBIT); | 577 | entry->msi_attrib.maskbit = !!(control & PCI_MSI_FLAGS_MASKBIT); |
| 555 | entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */ | 578 | entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */ |
| @@ -674,6 +697,7 @@ static int msix_setup_entries(struct pci_dev *dev, void __iomem *base, · 118 unmodified lines |
| 674 | struct irq_affinity_desc *curmsk, *masks = NULL; | 697 | struct irq_affinity_desc *curmsk, *masks = NULL; |
| 675 | struct msi_desc *entry; | 698 | struct msi_desc *entry; |
| 676 | int ret, i; | 699 | int ret, i; |
| | 700 | int vec_count = pci_msix_vec_count(dev); |
| 677 | | 701 | |
| 678 | if (affd) | 702 | if (affd) |
| 679 | masks = irq_create_affinity_masks(nvec, affd); | 703 | masks = irq_create_affinity_masks(nvec, affd); |
| @@ -696,6 +720,10 @@ static int msix_setup_entries(struct pci_dev *dev, void __iomem *base, · 16 unmodified lines |
| 696 | entry->msi_attrib.entry_nr = entries[i].entry; | 720 | entry->msi_attrib.entry_nr = entries[i].entry; |
| 697 | else | 721 | else |
| 698 | entry->msi_attrib.entry_nr = i; | 722 | entry->msi_attrib.entry_nr = i; |
| | 723 | |
| | 724 | entry->msi_attrib.is_virtual = |
| | 725 | entry->msi_attrib.entry_nr >= vec_count; |
| | 726 | |
| 699 | entry->msi_attrib.default_irq = dev->irq; | 727 | entry->msi_attrib.default_irq = dev->irq; |
| 700 | entry->mask_base = base; | 728 | entry->mask_base = base; |
| 701 | | 729 | |
| @@ -714,12 +742,19 @@ static void msix_program_entries(struct pci_dev *dev, · 12 unmodified lines |
| 714 | { | 742 | { |
| 715 | struct msi_desc *entry; | 743 | struct msi_desc *entry; |
| 716 | int i = 0; | 744 | int i = 0; |
| | 745 | void __iomem *desc_addr; |
| 717 | | 746 | |
| 718 | for_each_pci_msi_entry(entry, dev) { | 747 | for_each_pci_msi_entry(entry, dev) { |
| 719 | if (entries) | 748 | if (entries) |
| 720 | entries[i++].vector = entry->irq; | 749 | entries[i++].vector = entry->irq; |
| 721 | entry->masked = readl(pci_msix_desc_addr(entry) + | 750 | |
| 722 | PCI_MSIX_ENTRY_VECTOR_CTRL); | 751 | desc_addr = pci_msix_desc_addr(entry); |
| | 752 | if (desc_addr) |
| | 753 | entry->masked = readl(desc_addr + |
| | 754 | PCI_MSIX_ENTRY_VECTOR_CTRL); |
| | 755 | else |
| | 756 | entry->masked = 0; |
| | 757 | |
| 723 | msix_mask_irq(entry, 1); | 758 | msix_mask_irq(entry, 1); |
| 724 | } | 759 | } |
| 725 | } | 760 | } |
| @@ -932,7 +967,7 @@ int pci_msix_vec_count(struct pci_dev *dev) · 206 unmodified lines |
| 932 | EXPORT_SYMBOL(pci_msix_vec_count); | 967 | EXPORT_SYMBOL(pci_msix_vec_count); |
| 933 | | 968 | |
| 934 | static int __pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, | 969 | static int __pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, |
| 935 | int nvec, struct irq_affinity *affd) | 970 | int nvec, struct irq_affinity *affd, int flags) |
| 936 | { | 971 | { |
| 937 | int nr_entries; | 972 | int nr_entries; |
| 938 | int i, j; | 973 | int i, j; |
| @@ -943,7 +978,7 @@ static int __pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, · 4 unmodified lines |
| 943 | nr_entries = pci_msix_vec_count(dev); | 978 | nr_entries = pci_msix_vec_count(dev); |
| 944 | if (nr_entries < 0) | 979 | if (nr_entries < 0) |
| 945 | return nr_entries; | 980 | return nr_entries; |
| 946 | if (nvec > nr_entries) | 981 | if (nvec > nr_entries && !(flags & PCI_IRQ_VIRTUAL)) |
| 947 | return nr_entries; | 982 | return nr_entries; |
| 948 | | 983 | |
| 949 | if (entries) { | 984 | if (entries) { |
| @@ -1079,7 +1114,8 @@ EXPORT_SYMBOL(pci_enable_msi); · 129 unmodified lines |
| 1079 | | 1114 | |
| 1080 | static int __pci_enable_msix_range(struct pci_dev *dev, | 1115 | static int __pci_enable_msix_range(struct pci_dev *dev, |
| 1081 | struct msix_entry *entries, int minvec, | 1116 | struct msix_entry *entries, int minvec, |
| 1082 | int maxvec, struct irq_affinity *affd) | 1117 | int maxvec, struct irq_affinity *affd, |
| | 1118 | int flags) |
| 1083 | { | 1119 | { |
| 1084 | int rc, nvec = maxvec; | 1120 | int rc, nvec = maxvec; |
| 1085 | | 1121 | |
| @@ -1096,7 +1132,7 @@ static int __pci_enable_msix_range(struct pci_dev *dev, · 10 unmodified lines |
| 1096 | return -ENOSPC; | 1132 | return -ENOSPC; |
| 1097 | } | 1133 | } |
| 1098 | | 1134 | |
| 1099 | rc = __pci_enable_msix(dev, entries, nvec, affd); | 1135 | rc = __pci_enable_msix(dev, entries, nvec, affd, flags); |
| 1100 | if (rc == 0) | 1136 | if (rc == 0) |
| 1101 | return nvec; | 1137 | return nvec; |
| 1102 | | 1138 | |
| @@ -1127,7 +1163,7 @@ static int __pci_enable_msix_range(struct pci_dev *dev, · 24 unmodified lines |
| 1127 | int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, | 1163 | int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, |
| 1128 | int minvec, int maxvec) | 1164 | int minvec, int maxvec) |
| 1129 | { | 1165 | { |
| 1130 | return __pci_enable_msix_range(dev, entries, minvec, maxvec, NULL); | 1166 | return __pci_enable_msix_range(dev, entries, minvec, maxvec, NULL, 0); |
| 1131 | } | 1167 | } |
| 1132 | EXPORT_SYMBOL(pci_enable_msix_range); | 1168 | EXPORT_SYMBOL(pci_enable_msix_range); |
| 1133 | | 1169 | |
| @@ -1167,7 +1203,7 @@ int pci_alloc_irq_vectors_affinity(struct pci_dev *dev, unsigned int min_vecs, · 33 unmodified lines |
| 1167 | | 1203 | |
| 1168 | if (flags & PCI_IRQ_MSIX) { | 1204 | if (flags & PCI_IRQ_MSIX) { |
| 1169 | msix_vecs = __pci_enable_msix_range(dev, NULL, min_vecs, | 1205 | msix_vecs = __pci_enable_msix_range(dev, NULL, min_vecs, |
| 1170 | max_vecs, affd); | 1206 | max_vecs, affd, flags); |
| 1171 | if (msix_vecs > 0) | 1207 | if (msix_vecs > 0) |
| 1172 | return msix_vecs; | 1208 | return msix_vecs; |
| 1173 | } | 1209 | } |