aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2006-10-04 05:16:41 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-04 10:55:28 -0400
commit1ce03373a7f4b5fa8ca5be02ff35229800a6e12b (patch)
tree918fd844d371ec0fd9d19ac16a7798e361cb5583
parentc4fa0bbf384496ae4acc0a150719d9d8fa8d11b3 (diff)
[PATCH] genirq: msi: make the msi code irq based and not vector based
The msi currently allocates irqs backwards. First it allocates a platform dependent routing value for an interrupt the ``vector'' and then it figures out from the vector which irq you are on. For ia64 this is fine. For x86 and x86_64 this is complete nonsense and makes an enourmous mess of the irq handling code and prevents some pretty significant cleanups in the code for handling large numbers of irqs. This patch refactors msi.c to work in terms of irqs and create_irq/destroy_irq for dynamically managing irqs. Hopefully this is finally a version of msi.c that is useful on more than just x86 derivatives. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Rajesh Shah <rajesh.shah@intel.com> Cc: Andi Kleen <ak@muc.de> Cc: "Protasevich, Natalie" <Natalie.Protasevich@UNISYS.com> Cc: "Luck, Tony" <tony.luck@intel.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/pci/msi.c425
-rw-r--r--drivers/pci/msi.h7
2 files changed, 168 insertions, 264 deletions
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index a32e75a4417..da2c6c2b6b1 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -6,6 +6,7 @@
6 * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com) 6 * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
7 */ 7 */
8 8
9#include <linux/err.h>
9#include <linux/mm.h> 10#include <linux/mm.h>
10#include <linux/irq.h> 11#include <linux/irq.h>
11#include <linux/interrupt.h> 12#include <linux/interrupt.h>
@@ -27,12 +28,6 @@ static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL };
27static kmem_cache_t* msi_cachep; 28static kmem_cache_t* msi_cachep;
28 29
29static int pci_msi_enable = 1; 30static int pci_msi_enable = 1;
30static int last_alloc_vector;
31static int nr_released_vectors;
32
33#ifndef CONFIG_X86_IO_APIC
34int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1};
35#endif
36 31
37static struct msi_ops *msi_ops; 32static struct msi_ops *msi_ops;
38 33
@@ -53,11 +48,11 @@ static int msi_cache_init(void)
53 return 0; 48 return 0;
54} 49}
55 50
56static void msi_set_mask_bit(unsigned int vector, int flag) 51static void msi_set_mask_bit(unsigned int irq, int flag)
57{ 52{
58 struct msi_desc *entry; 53 struct msi_desc *entry;
59 54
60 entry = (struct msi_desc *)msi_desc[vector]; 55 entry = msi_desc[irq];
61 if (!entry || !entry->dev || !entry->mask_base) 56 if (!entry || !entry->dev || !entry->mask_base)
62 return; 57 return;
63 switch (entry->msi_attrib.type) { 58 switch (entry->msi_attrib.type) {
@@ -181,23 +176,23 @@ static void set_msi_affinity(unsigned int irq, cpumask_t cpu_mask)
181#define set_msi_affinity NULL 176#define set_msi_affinity NULL
182#endif /* CONFIG_SMP */ 177#endif /* CONFIG_SMP */
183 178
184static void mask_MSI_irq(unsigned int vector) 179static void mask_MSI_irq(unsigned int irq)
185{ 180{
186 msi_set_mask_bit(vector, 1); 181 msi_set_mask_bit(irq, 1);
187} 182}
188 183
189static void unmask_MSI_irq(unsigned int vector) 184static void unmask_MSI_irq(unsigned int irq)
190{ 185{
191 msi_set_mask_bit(vector, 0); 186 msi_set_mask_bit(irq, 0);
192} 187}
193 188
194static unsigned int startup_msi_irq_wo_maskbit(unsigned int vector) 189static unsigned int startup_msi_irq_wo_maskbit(unsigned int irq)
195{ 190{
196 struct msi_desc *entry; 191 struct msi_desc *entry;
197 unsigned long flags; 192 unsigned long flags;
198 193
199 spin_lock_irqsave(&msi_lock, flags); 194 spin_lock_irqsave(&msi_lock, flags);
200 entry = msi_desc[vector]; 195 entry = msi_desc[irq];
201 if (!entry || !entry->dev) { 196 if (!entry || !entry->dev) {
202 spin_unlock_irqrestore(&msi_lock, flags); 197 spin_unlock_irqrestore(&msi_lock, flags);
203 return 0; 198 return 0;
@@ -208,39 +203,39 @@ static unsigned int startup_msi_irq_wo_maskbit(unsigned int vector)
208 return 0; /* never anything pending */ 203 return 0; /* never anything pending */
209} 204}
210 205
211static unsigned int startup_msi_irq_w_maskbit(unsigned int vector) 206static unsigned int startup_msi_irq_w_maskbit(unsigned int irq)
212{ 207{
213 startup_msi_irq_wo_maskbit(vector); 208 startup_msi_irq_wo_maskbit(irq);
214 unmask_MSI_irq(vector); 209 unmask_MSI_irq(irq);
215 return 0; /* never anything pending */ 210 return 0; /* never anything pending */
216} 211}
217 212
218static void shutdown_msi_irq(unsigned int vector) 213static void shutdown_msi_irq(unsigned int irq)
219{ 214{
220 struct msi_desc *entry; 215 struct msi_desc *entry;
221 unsigned long flags; 216 unsigned long flags;
222 217
223 spin_lock_irqsave(&msi_lock, flags); 218 spin_lock_irqsave(&msi_lock, flags);
224 entry = msi_desc[vector]; 219 entry = msi_desc[irq];
225 if (entry && entry->dev) 220 if (entry && entry->dev)
226 entry->msi_attrib.state = 0; /* Mark it not active */ 221 entry->msi_attrib.state = 0; /* Mark it not active */
227 spin_unlock_irqrestore(&msi_lock, flags); 222 spin_unlock_irqrestore(&msi_lock, flags);
228} 223}
229 224
230static void end_msi_irq_wo_maskbit(unsigned int vector) 225static void end_msi_irq_wo_maskbit(unsigned int irq)
231{ 226{
232 move_native_irq(vector); 227 move_native_irq(irq);
233 ack_APIC_irq(); 228 ack_APIC_irq();
234} 229}
235 230
236static void end_msi_irq_w_maskbit(unsigned int vector) 231static void end_msi_irq_w_maskbit(unsigned int irq)
237{ 232{
238 move_native_irq(vector); 233 move_native_irq(irq);
239 unmask_MSI_irq(vector); 234 unmask_MSI_irq(irq);
240 ack_APIC_irq(); 235 ack_APIC_irq();
241} 236}
242 237
243static void do_nothing(unsigned int vector) 238static void do_nothing(unsigned int irq)
244{ 239{
245} 240}
246 241
@@ -291,86 +286,7 @@ static struct hw_interrupt_type msi_irq_wo_maskbit_type = {
291 .set_affinity = set_msi_affinity 286 .set_affinity = set_msi_affinity
292}; 287};
293 288
294static int msi_free_vector(struct pci_dev* dev, int vector, int reassign); 289static int msi_free_irq(struct pci_dev* dev, int irq);
295static int assign_msi_vector(void)
296{
297 static int new_vector_avail = 1;
298 int vector;
299 unsigned long flags;
300
301 /*
302 * msi_lock is provided to ensure that successful allocation of MSI
303 * vector is assigned unique among drivers.
304 */
305 spin_lock_irqsave(&msi_lock, flags);
306
307 if (!new_vector_avail) {
308 int free_vector = 0;
309
310 /*
311 * vector_irq[] = -1 indicates that this specific vector is:
312 * - assigned for MSI (since MSI have no associated IRQ) or
313 * - assigned for legacy if less than 16, or
314 * - having no corresponding 1:1 vector-to-IOxAPIC IRQ mapping
315 * vector_irq[] = 0 indicates that this vector, previously
316 * assigned for MSI, is freed by hotplug removed operations.
317 * This vector will be reused for any subsequent hotplug added
318 * operations.
319 * vector_irq[] > 0 indicates that this vector is assigned for
320 * IOxAPIC IRQs. This vector and its value provides a 1-to-1
321 * vector-to-IOxAPIC IRQ mapping.
322 */
323 for (vector = FIRST_DEVICE_VECTOR; vector < NR_IRQS; vector++) {
324 if (vector_irq[vector] != 0)
325 continue;
326 free_vector = vector;
327 if (!msi_desc[vector])
328 break;
329 else
330 continue;
331 }
332 if (!free_vector) {
333 spin_unlock_irqrestore(&msi_lock, flags);
334 return -EBUSY;
335 }
336 vector_irq[free_vector] = -1;
337 nr_released_vectors--;
338 spin_unlock_irqrestore(&msi_lock, flags);
339 if (msi_desc[free_vector] != NULL) {
340 struct pci_dev *dev;
341 int tail;
342
343 /* free all linked vectors before re-assign */
344 do {
345 spin_lock_irqsave(&msi_lock, flags);
346 dev = msi_desc[free_vector]->dev;
347 tail = msi_desc[free_vector]->link.tail;
348 spin_unlock_irqrestore(&msi_lock, flags);
349 msi_free_vector(dev, tail, 1);
350 } while (free_vector != tail);
351 }
352
353 return free_vector;
354 }
355 vector = assign_irq_vector(AUTO_ASSIGN);
356 last_alloc_vector = vector;
357 if (vector == LAST_DEVICE_VECTOR)
358 new_vector_avail = 0;
359
360 spin_unlock_irqrestore(&msi_lock, flags);
361 return vector;
362}
363
364static int get_new_vector(void)
365{
366 int vector = assign_msi_vector();
367
368 if (vector > 0)
369 set_intr_gate(vector, interrupt[vector]);
370
371 return vector;
372}
373
374static int msi_init(void) 290static int msi_init(void)
375{ 291{
376 static int status = -ENOMEM; 292 static int status = -ENOMEM;
@@ -394,13 +310,13 @@ static int msi_init(void)
394 } 310 }
395 311
396 if (! msi_ops) { 312 if (! msi_ops) {
313 pci_msi_enable = 0;
397 printk(KERN_WARNING 314 printk(KERN_WARNING
398 "PCI: MSI ops not registered. MSI disabled.\n"); 315 "PCI: MSI ops not registered. MSI disabled.\n");
399 status = -EINVAL; 316 status = -EINVAL;
400 return status; 317 return status;
401 } 318 }
402 319
403 last_alloc_vector = assign_irq_vector(AUTO_ASSIGN);
404 status = msi_cache_init(); 320 status = msi_cache_init();
405 if (status < 0) { 321 if (status < 0) {
406 pci_msi_enable = 0; 322 pci_msi_enable = 0;
@@ -408,23 +324,9 @@ static int msi_init(void)
408 return status; 324 return status;
409 } 325 }
410 326
411 if (last_alloc_vector < 0) {
412 pci_msi_enable = 0;
413 printk(KERN_WARNING "PCI: No interrupt vectors available for MSI\n");
414 status = -EBUSY;
415 return status;
416 }
417 vector_irq[last_alloc_vector] = 0;
418 nr_released_vectors++;
419
420 return status; 327 return status;
421} 328}
422 329
423static int get_msi_vector(struct pci_dev *dev)
424{
425 return get_new_vector();
426}
427
428static struct msi_desc* alloc_msi_entry(void) 330static struct msi_desc* alloc_msi_entry(void)
429{ 331{
430 struct msi_desc *entry; 332 struct msi_desc *entry;
@@ -439,29 +341,45 @@ static struct msi_desc* alloc_msi_entry(void)
439 return entry; 341 return entry;
440} 342}
441 343
442static void attach_msi_entry(struct msi_desc *entry, int vector) 344static void attach_msi_entry(struct msi_desc *entry, int irq)
443{ 345{
444 unsigned long flags; 346 unsigned long flags;
445 347
446 spin_lock_irqsave(&msi_lock, flags); 348 spin_lock_irqsave(&msi_lock, flags);
447 msi_desc[vector] = entry; 349 msi_desc[irq] = entry;
448 spin_unlock_irqrestore(&msi_lock, flags); 350 spin_unlock_irqrestore(&msi_lock, flags);
449} 351}
450 352
451static void irq_handler_init(int cap_id, int pos, int mask) 353static int create_msi_irq(struct hw_interrupt_type *handler)
452{ 354{
453 unsigned long flags; 355 struct msi_desc *entry;
356 int irq;
357
358 entry = alloc_msi_entry();
359 if (!entry)
360 return -ENOMEM;
454 361
455 spin_lock_irqsave(&irq_desc[pos].lock, flags); 362 irq = create_irq();
456 if (cap_id == PCI_CAP_ID_MSIX) 363 if (irq < 0) {
457 irq_desc[pos].chip = &msix_irq_type; 364 kmem_cache_free(msi_cachep, entry);
458 else { 365 return -EBUSY;
459 if (!mask)
460 irq_desc[pos].chip = &msi_irq_wo_maskbit_type;
461 else
462 irq_desc[pos].chip = &msi_irq_w_maskbit_type;
463 } 366 }
464 spin_unlock_irqrestore(&irq_desc[pos].lock, flags); 367
368 set_irq_chip(irq, handler);
369 set_irq_data(irq, entry);
370
371 return irq;
372}
373
374static void destroy_msi_irq(unsigned int irq)
375{
376 struct msi_desc *entry;
377
378 entry = get_irq_data(irq);
379 set_irq_chip(irq, NULL);
380 set_irq_data(irq, NULL);
381 destroy_irq(irq);
382 kmem_cache_free(msi_cachep, entry);
465} 383}
466 384
467static void enable_msi_mode(struct pci_dev *dev, int pos, int type) 385static void enable_msi_mode(struct pci_dev *dev, int pos, int type)
@@ -506,21 +424,21 @@ void disable_msi_mode(struct pci_dev *dev, int pos, int type)
506 } 424 }
507} 425}
508 426
509static int msi_lookup_vector(struct pci_dev *dev, int type) 427static int msi_lookup_irq(struct pci_dev *dev, int type)
510{ 428{
511 int vector; 429 int irq;
512 unsigned long flags; 430 unsigned long flags;
513 431
514 spin_lock_irqsave(&msi_lock, flags); 432 spin_lock_irqsave(&msi_lock, flags);
515 for (vector = FIRST_DEVICE_VECTOR; vector < NR_IRQS; vector++) { 433 for (irq = 0; irq < NR_IRQS; irq++) {
516 if (!msi_desc[vector] || msi_desc[vector]->dev != dev || 434 if (!msi_desc[irq] || msi_desc[irq]->dev != dev ||
517 msi_desc[vector]->msi_attrib.type != type || 435 msi_desc[irq]->msi_attrib.type != type ||
518 msi_desc[vector]->msi_attrib.default_vector != dev->irq) 436 msi_desc[irq]->msi_attrib.default_irq != dev->irq)
519 continue; 437 continue;
520 spin_unlock_irqrestore(&msi_lock, flags); 438 spin_unlock_irqrestore(&msi_lock, flags);
521 /* This pre-assigned MSI vector for this device 439 /* This pre-assigned MSI irq for this device
522 already exits. Override dev->irq with this vector */ 440 already exits. Override dev->irq with this irq */
523 dev->irq = vector; 441 dev->irq = irq;
524 return 0; 442 return 0;
525 } 443 }
526 spin_unlock_irqrestore(&msi_lock, flags); 444 spin_unlock_irqrestore(&msi_lock, flags);
@@ -605,7 +523,7 @@ int pci_save_msix_state(struct pci_dev *dev)
605{ 523{
606 int pos; 524 int pos;
607 int temp; 525 int temp;
608 int vector, head, tail = 0; 526 int irq, head, tail = 0;
609 u16 control; 527 u16 control;
610 struct pci_cap_saved_state *save_state; 528 struct pci_cap_saved_state *save_state;
611 529
@@ -627,20 +545,20 @@ int pci_save_msix_state(struct pci_dev *dev)
627 545
628 /* save the table */ 546 /* save the table */
629 temp = dev->irq; 547 temp = dev->irq;
630 if (msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) { 548 if (msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) {
631 kfree(save_state); 549 kfree(save_state);
632 return -EINVAL; 550 return -EINVAL;
633 } 551 }
634 552
635 vector = head = dev->irq; 553 irq = head = dev->irq;
636 while (head != tail) { 554 while (head != tail) {
637 struct msi_desc *entry; 555 struct msi_desc *entry;
638 556
639 entry = msi_desc[vector]; 557 entry = msi_desc[irq];
640 read_msi_msg(entry, &entry->msg_save); 558 read_msi_msg(entry, &entry->msg_save);
641 559
642 tail = msi_desc[vector]->link.tail; 560 tail = msi_desc[irq]->link.tail;
643 vector = tail; 561 irq = tail;
644 } 562 }
645 dev->irq = temp; 563 dev->irq = temp;
646 564
@@ -653,7 +571,7 @@ void pci_restore_msix_state(struct pci_dev *dev)
653{ 571{
654 u16 save; 572 u16 save;
655 int pos; 573 int pos;
656 int vector, head, tail = 0; 574 int irq, head, tail = 0;
657 struct msi_desc *entry; 575 struct msi_desc *entry;
658 int temp; 576 int temp;
659 struct pci_cap_saved_state *save_state; 577 struct pci_cap_saved_state *save_state;
@@ -671,15 +589,15 @@ void pci_restore_msix_state(struct pci_dev *dev)
671 589
672 /* route the table */ 590 /* route the table */
673 temp = dev->irq; 591 temp = dev->irq;
674 if (msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) 592 if (msi_lookup_irq(dev, PCI_CAP_ID_MSIX))
675 return; 593 return;
676 vector = head = dev->irq; 594 irq = head = dev->irq;
677 while (head != tail) { 595 while (head != tail) {
678 entry = msi_desc[vector]; 596 entry = msi_desc[irq];
679 write_msi_msg(entry, &entry->msg_save); 597 write_msi_msg(entry, &entry->msg_save);
680 598
681 tail = msi_desc[vector]->link.tail; 599 tail = msi_desc[irq]->link.tail;
682 vector = tail; 600 irq = tail;
683 } 601 }
684 dev->irq = temp; 602 dev->irq = temp;
685 603
@@ -726,55 +644,54 @@ static int msi_register_init(struct pci_dev *dev, struct msi_desc *entry)
726 * @dev: pointer to the pci_dev data structure of MSI device function 644 * @dev: pointer to the pci_dev data structure of MSI device function
727 * 645 *
728 * Setup the MSI capability structure of device function with a single 646 * Setup the MSI capability structure of device function with a single
729 * MSI vector, regardless of device function is capable of handling 647 * MSI irq, regardless of device function is capable of handling
730 * multiple messages. A return of zero indicates the successful setup 648 * multiple messages. A return of zero indicates the successful setup
731 * of an entry zero with the new MSI vector or non-zero for otherwise. 649 * of an entry zero with the new MSI irq or non-zero for otherwise.
732 **/ 650 **/
733static int msi_capability_init(struct pci_dev *dev) 651static int msi_capability_init(struct pci_dev *dev)
734{ 652{
735 int status; 653 int status;
736 struct msi_desc *entry; 654 struct msi_desc *entry;
737 int pos, vector; 655 int pos, irq;
738 u16 control; 656 u16 control;
657 struct hw_interrupt_type *handler;
739 658
740 pos = pci_find_capability(dev, PCI_CAP_ID_MSI); 659 pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
741 pci_read_config_word(dev, msi_control_reg(pos), &control); 660 pci_read_config_word(dev, msi_control_reg(pos), &control);
742 /* MSI Entry Initialization */ 661 /* MSI Entry Initialization */
743 entry = alloc_msi_entry(); 662 handler = &msi_irq_wo_maskbit_type;
744 if (!entry) 663 if (is_mask_bit_support(control))
745 return -ENOMEM; 664 handler = &msi_irq_w_maskbit_type;
746 665
747 vector = get_msi_vector(dev); 666 irq = create_msi_irq(handler);
748 if (vector < 0) { 667 if (irq < 0)
749 kmem_cache_free(msi_cachep, entry); 668 return irq;
750 return -EBUSY; 669
751 } 670 entry = get_irq_data(irq);
752 entry->link.head = vector; 671 entry->link.head = irq;
753 entry->link.tail = vector; 672 entry->link.tail = irq;
754 entry->msi_attrib.type = PCI_CAP_ID_MSI; 673 entry->msi_attrib.type = PCI_CAP_ID_MSI;
755 entry->msi_attrib.state = 0; /* Mark it not active */ 674 entry->msi_attrib.state = 0; /* Mark it not active */
756 entry->msi_attrib.is_64 = is_64bit_address(control); 675 entry->msi_attrib.is_64 = is_64bit_address(control);
757 entry->msi_attrib.entry_nr = 0; 676 entry->msi_attrib.entry_nr = 0;
758 entry->msi_attrib.maskbit = is_mask_bit_support(control); 677 entry->msi_attrib.maskbit = is_mask_bit_support(control);
759 entry->msi_attrib.default_vector = dev->irq; /* Save IOAPIC IRQ */ 678 entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */
760 entry->msi_attrib.pos = pos; 679 entry->msi_attrib.pos = pos;
761 dev->irq = vector; 680 dev->irq = irq;
762 entry->dev = dev; 681 entry->dev = dev;
763 if (is_mask_bit_support(control)) { 682 if (is_mask_bit_support(control)) {
764 entry->mask_base = (void __iomem *)(long)msi_mask_bits_reg(pos, 683 entry->mask_base = (void __iomem *)(long)msi_mask_bits_reg(pos,
765 is_64bit_address(control)); 684 is_64bit_address(control));
766 } 685 }
767 /* Replace with MSI handler */
768 irq_handler_init(PCI_CAP_ID_MSI, vector, entry->msi_attrib.maskbit);
769 /* Configure MSI capability structure */ 686 /* Configure MSI capability structure */
770 status = msi_register_init(dev, entry); 687 status = msi_register_init(dev, entry);
771 if (status != 0) { 688 if (status != 0) {
772 dev->irq = entry->msi_attrib.default_vector; 689 dev->irq = entry->msi_attrib.default_irq;
773 kmem_cache_free(msi_cachep, entry); 690 destroy_msi_irq(irq);
774 return status; 691 return status;
775 } 692 }
776 693
777 attach_msi_entry(entry, vector); 694 attach_msi_entry(entry, irq);
778 /* Set MSI enabled bits */ 695 /* Set MSI enabled bits */
779 enable_msi_mode(dev, pos, PCI_CAP_ID_MSI); 696 enable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
780 697
@@ -788,8 +705,8 @@ static int msi_capability_init(struct pci_dev *dev)
788 * @nvec: number of @entries 705 * @nvec: number of @entries
789 * 706 *
790 * Setup the MSI-X capability structure of device function with a 707 * Setup the MSI-X capability structure of device function with a
791 * single MSI-X vector. A return of zero indicates the successful setup of 708 * single MSI-X irq. A return of zero indicates the successful setup of
792 * requested MSI-X entries with allocated vectors or non-zero for otherwise. 709 * requested MSI-X entries with allocated irqs or non-zero for otherwise.
793 **/ 710 **/
794static int msix_capability_init(struct pci_dev *dev, 711static int msix_capability_init(struct pci_dev *dev,
795 struct msix_entry *entries, int nvec) 712 struct msix_entry *entries, int nvec)
@@ -797,7 +714,7 @@ static int msix_capability_init(struct pci_dev *dev,
797 struct msi_desc *head = NULL, *tail = NULL, *entry = NULL; 714 struct msi_desc *head = NULL, *tail = NULL, *entry = NULL;
798 struct msi_msg msg; 715 struct msi_msg msg;
799 int status; 716 int status;
800 int vector, pos, i, j, nr_entries, temp = 0; 717 int irq, pos, i, j, nr_entries, temp = 0;
801 unsigned long phys_addr; 718 unsigned long phys_addr;
802 u32 table_offset; 719 u32 table_offset;
803 u16 control; 720 u16 control;
@@ -819,54 +736,50 @@ static int msix_capability_init(struct pci_dev *dev,
819 736
820 /* MSI-X Table Initialization */ 737 /* MSI-X Table Initialization */
821 for (i = 0; i < nvec; i++) { 738 for (i = 0; i < nvec; i++) {
822 entry = alloc_msi_entry(); 739 irq = create_msi_irq(&msix_irq_type);
823 if (!entry) 740 if (irq < 0)
824 break; 741 break;
825 vector = get_msi_vector(dev);
826 if (vector < 0) {
827 kmem_cache_free(msi_cachep, entry);
828 break;
829 }
830 742
743 entry = get_irq_data(irq);
831 j = entries[i].entry; 744 j = entries[i].entry;
832 entries[i].vector = vector; 745 entries[i].vector = irq;
833 entry->msi_attrib.type = PCI_CAP_ID_MSIX; 746 entry->msi_attrib.type = PCI_CAP_ID_MSIX;
834 entry->msi_attrib.state = 0; /* Mark it not active */ 747 entry->msi_attrib.state = 0; /* Mark it not active */
835 entry->msi_attrib.is_64 = 1; 748 entry->msi_attrib.is_64 = 1;
836 entry->msi_attrib.entry_nr = j; 749 entry->msi_attrib.entry_nr = j;
837 entry->msi_attrib.maskbit = 1; 750 entry->msi_attrib.maskbit = 1;
838 entry->msi_attrib.default_vector = dev->irq; 751 entry->msi_attrib.default_irq = dev->irq;
839 entry->msi_attrib.pos = pos; 752 entry->msi_attrib.pos = pos;
840 entry->dev = dev; 753 entry->dev = dev;
841 entry->mask_base = base; 754 entry->mask_base = base;
842 if (!head) { 755 if (!head) {
843 entry->link.head = vector; 756 entry->link.head = irq;
844 entry->link.tail = vector; 757 entry->link.tail = irq;
845 head = entry; 758 head = entry;
846 } else { 759 } else {
847 entry->link.head = temp; 760 entry->link.head = temp;
848 entry->link.tail = tail->link.tail; 761 entry->link.tail = tail->link.tail;
849 tail->link.tail = vector; 762 tail->link.tail = irq;
850 head->link.head = vector; 763 head->link.head = irq;
851 } 764 }
852 temp = vector; 765 temp = irq;
853 tail = entry; 766 tail = entry;
854 /* Replace with MSI-X handler */
855 irq_handler_init(PCI_CAP_ID_MSIX, vector, 1);
856 /* Configure MSI-X capability structure */ 767 /* Configure MSI-X capability structure */
857 status = msi_ops->setup(dev, vector, &msg); 768 status = msi_ops->setup(dev, irq, &msg);
858 if (status < 0) 769 if (status < 0) {
770 destroy_msi_irq(irq);
859 break; 771 break;
772 }
860 773
861 write_msi_msg(entry, &msg); 774 write_msi_msg(entry, &msg);
862 attach_msi_entry(entry, vector); 775 attach_msi_entry(entry, irq);
863 } 776 }
864 if (i != nvec) { 777 if (i != nvec) {
865 int avail = i - 1; 778 int avail = i - 1;
866 i--; 779 i--;
867 for (; i >= 0; i--) { 780 for (; i >= 0; i--) {
868 vector = (entries + i)->vector; 781 irq = (entries + i)->vector;
869 msi_free_vector(dev, vector, 0); 782 msi_free_irq(dev, irq);
870 (entries + i)->vector = 0; 783 (entries + i)->vector = 0;
871 } 784 }
872 /* If we had some success report the number of irqs 785 /* If we had some success report the number of irqs
@@ -914,10 +827,10 @@ int pci_msi_supported(struct pci_dev * dev)
914 * @dev: pointer to the pci_dev data structure of MSI device function 827 * @dev: pointer to the pci_dev data structure of MSI device function
915 * 828 *
916 * Setup the MSI capability structure of device function with 829 * Setup the MSI capability structure of device function with
917 * a single MSI vector upon its software driver call to request for 830 * a single MSI irq upon its software driver call to request for
918 * MSI mode enabled on its hardware device function. A return of zero 831 * MSI mode enabled on its hardware device function. A return of zero
919 * indicates the successful setup of an entry zero with the new MSI 832 * indicates the successful setup of an entry zero with the new MSI
920 * vector or non-zero for otherwise. 833 * irq or non-zero for otherwise.
921 **/ 834 **/
922int pci_enable_msi(struct pci_dev* dev) 835int pci_enable_msi(struct pci_dev* dev)
923{ 836{
@@ -941,13 +854,13 @@ int pci_enable_msi(struct pci_dev* dev)
941 if (!is_64bit_address(control) && msi_ops->needs_64bit_address) 854 if (!is_64bit_address(control) && msi_ops->needs_64bit_address)
942 return -EINVAL; 855 return -EINVAL;
943 856
944 WARN_ON(!msi_lookup_vector(dev, PCI_CAP_ID_MSI)); 857 WARN_ON(!msi_lookup_irq(dev, PCI_CAP_ID_MSI));
945 858
946 /* Check whether driver already requested for MSI-X vectors */ 859 /* Check whether driver already requested for MSI-X irqs */
947 pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); 860 pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
948 if (pos > 0 && !msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) { 861 if (pos > 0 && !msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) {
949 printk(KERN_INFO "PCI: %s: Can't enable MSI. " 862 printk(KERN_INFO "PCI: %s: Can't enable MSI. "
950 "Device already has MSI-X vectors assigned\n", 863 "Device already has MSI-X irq assigned\n",
951 pci_name(dev)); 864 pci_name(dev));
952 dev->irq = temp; 865 dev->irq = temp;
953 return -EINVAL; 866 return -EINVAL;
@@ -959,7 +872,7 @@ int pci_enable_msi(struct pci_dev* dev)
959void pci_disable_msi(struct pci_dev* dev) 872void pci_disable_msi(struct pci_dev* dev)
960{ 873{
961 struct msi_desc *entry; 874 struct msi_desc *entry;
962 int pos, default_vector; 875 int pos, default_irq;
963 u16 control; 876 u16 control;
964 unsigned long flags; 877 unsigned long flags;
965 878
@@ -987,30 +900,30 @@ void pci_disable_msi(struct pci_dev* dev)
987 if (entry->msi_attrib.state) { 900 if (entry->msi_attrib.state) {
988 spin_unlock_irqrestore(&msi_lock, flags); 901 spin_unlock_irqrestore(&msi_lock, flags);
989 printk(KERN_WARNING "PCI: %s: pci_disable_msi() called without " 902 printk(KERN_WARNING "PCI: %s: pci_disable_msi() called without "
990 "free_irq() on MSI vector %d\n", 903 "free_irq() on MSI irq %d\n",
991 pci_name(dev), dev->irq); 904 pci_name(dev), dev->irq);
992 BUG_ON(entry->msi_attrib.state > 0); 905 BUG_ON(entry->msi_attrib.state > 0);
993 } else { 906 } else {
994 default_vector = entry->msi_attrib.default_vector; 907 default_irq = entry->msi_attrib.default_irq;
995 spin_unlock_irqrestore(&msi_lock, flags); 908 spin_unlock_irqrestore(&msi_lock, flags);
996 msi_free_vector(dev, dev->irq, 0); 909 msi_free_irq(dev, dev->irq);
997 910
998 /* Restore dev->irq to its default pin-assertion vector */ 911 /* Restore dev->irq to its default pin-assertion irq */
999 dev->irq = default_vector; 912 dev->irq = default_irq;
1000 } 913 }
1001} 914}
1002 915
1003static int msi_free_vector(struct pci_dev* dev, int vector, int reassign) 916static int msi_free_irq(struct pci_dev* dev, int irq)
1004{ 917{
1005 struct msi_desc *entry; 918 struct msi_desc *entry;
1006 int head, entry_nr, type; 919 int head, entry_nr, type;
1007 void __iomem *base; 920 void __iomem *base;
1008 unsigned long flags; 921 unsigned long flags;
1009 922
1010 msi_ops->teardown(vector); 923 msi_ops->teardown(irq);
1011 924
1012 spin_lock_irqsave(&msi_lock, flags); 925 spin_lock_irqsave(&msi_lock, flags);
1013 entry = msi_desc[vector]; 926 entry = msi_desc[irq];
1014 if (!entry || entry->dev != dev) { 927 if (!entry || entry->dev != dev) {
1015 spin_unlock_irqrestore(&msi_lock, flags); 928 spin_unlock_irqrestore(&msi_lock, flags);
1016 return -EINVAL; 929 return -EINVAL;
@@ -1022,22 +935,16 @@ static int msi_free_vector(struct pci_dev* dev, int vector, int reassign)
1022 msi_desc[entry->link.head]->link.tail = entry->link.tail; 935 msi_desc[entry->link.head]->link.tail = entry->link.tail;
1023 msi_desc[entry->link.tail]->link.head = entry->link.head; 936 msi_desc[entry->link.tail]->link.head = entry->link.head;
1024 entry->dev = NULL; 937 entry->dev = NULL;
1025 if (!reassign) { 938 msi_desc[irq] = NULL;
1026 vector_irq[vector] = 0;
1027 nr_released_vectors++;
1028 }
1029 msi_desc[vector] = NULL;
1030 spin_unlock_irqrestore(&msi_lock, flags); 939 spin_unlock_irqrestore(&msi_lock, flags);
1031 940
1032 kmem_cache_free(msi_cachep, entry); 941 destroy_msi_irq(irq);
1033 942
1034 if (type == PCI_CAP_ID_MSIX) { 943 if (type == PCI_CAP_ID_MSIX) {
1035 if (!reassign) 944 writel(1, base + entry_nr * PCI_MSIX_ENTRY_SIZE +
1036 writel(1, base + 945 PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
1037 entry_nr * PCI_MSIX_ENTRY_SIZE +
1038 PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
1039 946
1040 if (head == vector) 947 if (head == irq)
1041 iounmap(base); 948 iounmap(base);
1042 } 949 }
1043 950
@@ -1048,15 +955,15 @@ static int msi_free_vector(struct pci_dev* dev, int vector, int reassign)
1048 * pci_enable_msix - configure device's MSI-X capability structure 955 * pci_enable_msix - configure device's MSI-X capability structure
1049 * @dev: pointer to the pci_dev data structure of MSI-X device function 956 * @dev: pointer to the pci_dev data structure of MSI-X device function
1050 * @entries: pointer to an array of MSI-X entries 957 * @entries: pointer to an array of MSI-X entries
1051 * @nvec: number of MSI-X vectors requested for allocation by device driver 958 * @nvec: number of MSI-X irqs requested for allocation by device driver
1052 * 959 *
1053 * Setup the MSI-X capability structure of device function with the number 960 * Setup the MSI-X capability structure of device function with the number
1054 * of requested vectors upon its software driver call to request for 961 * of requested irqs upon its software driver call to request for
1055 * MSI-X mode enabled on its hardware device function. A return of zero 962 * MSI-X mode enabled on its hardware device function. A return of zero
1056 * indicates the successful configuration of MSI-X capability structure 963 * indicates the successful configuration of MSI-X capability structure
1057 * with new allocated MSI-X vectors. A return of < 0 indicates a failure. 964 * with new allocated MSI-X irqs. A return of < 0 indicates a failure.
1058 * Or a return of > 0 indicates that driver request is exceeding the number 965 * Or a return of > 0 indicates that driver request is exceeding the number
1059 * of vectors available. Driver should use the returned value to re-send 966 * of irqs available. Driver should use the returned value to re-send
1060 * its request. 967 * its request.
1061 **/ 968 **/
1062int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) 969int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
@@ -1091,13 +998,13 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
1091 } 998 }
1092 } 999 }
1093 temp = dev->irq; 1000 temp = dev->irq;
1094 WARN_ON(!msi_lookup_vector(dev, PCI_CAP_ID_MSIX)); 1001 WARN_ON(!msi_lookup_irq(dev, PCI_CAP_ID_MSIX));
1095 1002
1096 /* Check whether driver already requested for MSI vector */ 1003 /* Check whether driver already requested for MSI irq */
1097 if (pci_find_capability(dev, PCI_CAP_ID_MSI) > 0 && 1004 if (pci_find_capability(dev, PCI_CAP_ID_MSI) > 0 &&
1098 !msi_lookup_vector(dev, PCI_CAP_ID_MSI)) { 1005 !msi_lookup_irq(dev, PCI_CAP_ID_MSI)) {
1099 printk(KERN_INFO "PCI: %s: Can't enable MSI-X. " 1006 printk(KERN_INFO "PCI: %s: Can't enable MSI-X. "
1100 "Device already has an MSI vector assigned\n", 1007 "Device already has an MSI irq assigned\n",
1101 pci_name(dev)); 1008 pci_name(dev));
1102 dev->irq = temp; 1009 dev->irq = temp;
1103 return -EINVAL; 1010 return -EINVAL;
@@ -1127,27 +1034,27 @@ void pci_disable_msix(struct pci_dev* dev)
1127 disable_msi_mode(dev, pos, PCI_CAP_ID_MSIX); 1034 disable_msi_mode(dev, pos, PCI_CAP_ID_MSIX);
1128 1035
1129 temp = dev->irq; 1036 temp = dev->irq;
1130 if (!msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) { 1037 if (!msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) {
1131 int state, vector, head, tail = 0, warning = 0; 1038 int state, irq, head, tail = 0, warning = 0;
1132 unsigned long flags; 1039 unsigned long flags;
1133 1040
1134 vector = head = dev->irq; 1041 irq = head = dev->irq;
1135 dev->irq = temp; /* Restore pin IRQ */ 1042 dev->irq = temp; /* Restore pin IRQ */
1136 while (head != tail) { 1043 while (head != tail) {
1137 spin_lock_irqsave(&msi_lock, flags); 1044 spin_lock_irqsave(&msi_lock, flags);
1138 state = msi_desc[vector]->msi_attrib.state; 1045 state = msi_desc[irq]->msi_attrib.state;
1139 tail = msi_desc[vector]->link.tail; 1046 tail = msi_desc[irq]->link.tail;
1140 spin_unlock_irqrestore(&msi_lock, flags); 1047 spin_unlock_irqrestore(&msi_lock, flags);
1141 if (state) 1048 if (state)
1142 warning = 1; 1049 warning = 1;
1143 else if (vector != head) /* Release MSI-X vector */ 1050 else if (irq != head) /* Release MSI-X irq */
1144 msi_free_vector(dev, vector, 0); 1051 msi_free_irq(dev, irq);
1145 vector = tail; 1052 irq = tail;
1146 } 1053 }
1147 msi_free_vector(dev, vector, 0); 1054 msi_free_irq(dev, irq);
1148 if (warning) { 1055 if (warning) {
1149 printk(KERN_WARNING "PCI: %s: pci_disable_msix() called without " 1056 printk(KERN_WARNING "PCI: %s: pci_disable_msix() called without "
1150 "free_irq() on all MSI-X vectors\n", 1057 "free_irq() on all MSI-X irqs\n",
1151 pci_name(dev)); 1058 pci_name(dev));
1152 BUG_ON(warning > 0); 1059 BUG_ON(warning > 0);
1153 } 1060 }
@@ -1155,11 +1062,11 @@ void pci_disable_msix(struct pci_dev* dev)
1155} 1062}
1156 1063
1157/** 1064/**
1158 * msi_remove_pci_irq_vectors - reclaim MSI(X) vectors to unused state 1065 * msi_remove_pci_irq_vectors - reclaim MSI(X) irqs to unused state
1159 * @dev: pointer to the pci_dev data structure of MSI(X) device function 1066 * @dev: pointer to the pci_dev data structure of MSI(X) device function
1160 * 1067 *
1161 * Being called during hotplug remove, from which the device function 1068 * Being called during hotplug remove, from which the device function
1162 * is hot-removed. All previous assigned MSI/MSI-X vectors, if 1069 * is hot-removed. All previous assigned MSI/MSI-X irqs, if
1163 * allocated for this device function, are reclaimed to unused state, 1070 * allocated for this device function, are reclaimed to unused state,
1164 * which may be used later on. 1071 * which may be used later on.
1165 **/ 1072 **/
@@ -1173,42 +1080,42 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev)
1173 1080
1174 temp = dev->irq; /* Save IOAPIC IRQ */ 1081 temp = dev->irq; /* Save IOAPIC IRQ */
1175 pos = pci_find_capability(dev, PCI_CAP_ID_MSI); 1082 pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
1176 if (pos > 0 && !msi_lookup_vector(dev, PCI_CAP_ID_MSI)) { 1083 if (pos > 0 && !msi_lookup_irq(dev, PCI_CAP_ID_MSI)) {
1177 spin_lock_irqsave(&msi_lock, flags); 1084 spin_lock_irqsave(&msi_lock, flags);
1178 state = msi_desc[dev->irq]->msi_attrib.state; 1085 state = msi_desc[dev->irq]->msi_attrib.state;
1179 spin_unlock_irqrestore(&msi_lock, flags); 1086 spin_unlock_irqrestore(&msi_lock, flags);
1180 if (state) { 1087 if (state) {
1181 printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() " 1088 printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() "
1182 "called without free_irq() on MSI vector %d\n", 1089 "called without free_irq() on MSI irq %d\n",
1183 pci_name(dev), dev->irq); 1090 pci_name(dev), dev->irq);
1184 BUG_ON(state > 0); 1091 BUG_ON(state > 0);
1185 } else /* Release MSI vector assigned to this device */ 1092 } else /* Release MSI irq assigned to this device */
1186 msi_free_vector(dev, dev->irq, 0); 1093 msi_free_irq(dev, dev->irq);
1187 dev->irq = temp; /* Restore IOAPIC IRQ */ 1094 dev->irq = temp; /* Restore IOAPIC IRQ */
1188 } 1095 }
1189 pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); 1096 pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
1190 if (pos > 0 && !msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) { 1097 if (pos > 0 && !msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) {
1191 int vector, head, tail = 0, warning = 0; 1098 int irq, head, tail = 0, warning = 0;
1192 void __iomem *base = NULL; 1099 void __iomem *base = NULL;
1193 1100
1194 vector = head = dev->irq; 1101 irq = head = dev->irq;
1195 while (head != tail) { 1102 while (head != tail) {
1196 spin_lock_irqsave(&msi_lock, flags); 1103 spin_lock_irqsave(&msi_lock, flags);
1197 state = msi_desc[vector]->msi_attrib.state; 1104 state = msi_desc[irq]->msi_attrib.state;
1198 tail = msi_desc[vector]->link.tail; 1105 tail = msi_desc[irq]->link.tail;
1199 base = msi_desc[vector]->mask_base; 1106 base = msi_desc[irq]->mask_base;
1200 spin_unlock_irqrestore(&msi_lock, flags); 1107 spin_unlock_irqrestore(&msi_lock, flags);
1201 if (state) 1108 if (state)
1202 warning = 1; 1109 warning = 1;
1203 else if (vector != head) /* Release MSI-X vector */ 1110 else if (irq != head) /* Release MSI-X irq */
1204 msi_free_vector(dev, vector, 0); 1111 msi_free_irq(dev, irq);
1205 vector = tail; 1112 irq = tail;
1206 } 1113 }
1207 msi_free_vector(dev, vector, 0); 1114 msi_free_irq(dev, irq);
1208 if (warning) { 1115 if (warning) {
1209 iounmap(base); 1116 iounmap(base);
1210 printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() " 1117 printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() "
1211 "called without free_irq() on all MSI-X vectors\n", 1118 "called without free_irq() on all MSI-X irqs\n",
1212 pci_name(dev)); 1119 pci_name(dev));
1213 BUG_ON(warning > 0); 1120 BUG_ON(warning > 0);
1214 } 1121 }
diff --git a/drivers/pci/msi.h b/drivers/pci/msi.h
index 6793241f388..435d05aae4b 100644
--- a/drivers/pci/msi.h
+++ b/drivers/pci/msi.h
@@ -8,9 +8,6 @@
8 8
9#include <asm/msi.h> 9#include <asm/msi.h>
10 10
11extern int vector_irq[NR_VECTORS];
12extern void (*interrupt[NR_IRQS])(void);
13
14/* 11/*
15 * MSI-X Address Register 12 * MSI-X Address Register
16 */ 13 */
@@ -58,9 +55,9 @@ struct msi_desc {
58 __u8 maskbit : 1; /* mask-pending bit supported ? */ 55 __u8 maskbit : 1; /* mask-pending bit supported ? */
59 __u8 state : 1; /* {0: free, 1: busy} */ 56 __u8 state : 1; /* {0: free, 1: busy} */
60 __u8 is_64 : 1; /* Address size: 0=32bit 1=64bit */ 57 __u8 is_64 : 1; /* Address size: 0=32bit 1=64bit */
61 __u8 entry_nr; /* specific enabled entry */
62 __u8 default_vector; /* default pre-assigned vector */
63 __u8 pos; /* Location of the msi capability */ 58 __u8 pos; /* Location of the msi capability */
59 __u16 entry_nr; /* specific enabled entry */
60 unsigned default_irq; /* default pre-assigned irq */
64 }msi_attrib; 61 }msi_attrib;
65 62
66 struct { 63 struct {