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.c325
1 files changed, 117 insertions, 208 deletions
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index ed3f7e1a563c..68555c11f556 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -24,8 +24,6 @@
24#include "pci.h" 24#include "pci.h"
25#include "msi.h" 25#include "msi.h"
26 26
27static DEFINE_SPINLOCK(msi_lock);
28static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL };
29static struct kmem_cache* msi_cachep; 27static struct kmem_cache* msi_cachep;
30 28
31static int pci_msi_enable = 1; 29static int pci_msi_enable = 1;
@@ -44,13 +42,13 @@ static void msi_set_mask_bit(unsigned int irq, int flag)
44{ 42{
45 struct msi_desc *entry; 43 struct msi_desc *entry;
46 44
47 entry = msi_desc[irq]; 45 entry = get_irq_msi(irq);
48 BUG_ON(!entry || !entry->dev); 46 BUG_ON(!entry || !entry->dev);
49 switch (entry->msi_attrib.type) { 47 switch (entry->msi_attrib.type) {
50 case PCI_CAP_ID_MSI: 48 case PCI_CAP_ID_MSI:
51 if (entry->msi_attrib.maskbit) { 49 if (entry->msi_attrib.maskbit) {
52 int pos; 50 int pos;
53 u32 mask_bits; 51 u32 mask_bits;
54 52
55 pos = (long)entry->mask_base; 53 pos = (long)entry->mask_base;
56 pci_read_config_dword(entry->dev, pos, &mask_bits); 54 pci_read_config_dword(entry->dev, pos, &mask_bits);
@@ -74,7 +72,7 @@ static void msi_set_mask_bit(unsigned int irq, int flag)
74 72
75void read_msi_msg(unsigned int irq, struct msi_msg *msg) 73void read_msi_msg(unsigned int irq, struct msi_msg *msg)
76{ 74{
77 struct msi_desc *entry = get_irq_data(irq); 75 struct msi_desc *entry = get_irq_msi(irq);
78 switch(entry->msi_attrib.type) { 76 switch(entry->msi_attrib.type) {
79 case PCI_CAP_ID_MSI: 77 case PCI_CAP_ID_MSI:
80 { 78 {
@@ -113,7 +111,7 @@ void read_msi_msg(unsigned int irq, struct msi_msg *msg)
113 111
114void write_msi_msg(unsigned int irq, struct msi_msg *msg) 112void write_msi_msg(unsigned int irq, struct msi_msg *msg)
115{ 113{
116 struct msi_desc *entry = get_irq_data(irq); 114 struct msi_desc *entry = get_irq_msi(irq);
117 switch (entry->msi_attrib.type) { 115 switch (entry->msi_attrib.type) {
118 case PCI_CAP_ID_MSI: 116 case PCI_CAP_ID_MSI:
119 { 117 {
@@ -162,6 +160,7 @@ void unmask_msi_irq(unsigned int irq)
162} 160}
163 161
164static int msi_free_irq(struct pci_dev* dev, int irq); 162static int msi_free_irq(struct pci_dev* dev, int irq);
163
165static int msi_init(void) 164static int msi_init(void)
166{ 165{
167 static int status = -ENOMEM; 166 static int status = -ENOMEM;
@@ -169,13 +168,6 @@ static int msi_init(void)
169 if (!status) 168 if (!status)
170 return status; 169 return status;
171 170
172 if (pci_msi_quirk) {
173 pci_msi_enable = 0;
174 printk(KERN_WARNING "PCI: MSI quirk detected. MSI disabled.\n");
175 status = -EINVAL;
176 return status;
177 }
178
179 status = msi_cache_init(); 171 status = msi_cache_init();
180 if (status < 0) { 172 if (status < 0) {
181 pci_msi_enable = 0; 173 pci_msi_enable = 0;
@@ -200,46 +192,6 @@ static struct msi_desc* alloc_msi_entry(void)
200 return entry; 192 return entry;
201} 193}
202 194
203static void attach_msi_entry(struct msi_desc *entry, int irq)
204{
205 unsigned long flags;
206
207 spin_lock_irqsave(&msi_lock, flags);
208 msi_desc[irq] = entry;
209 spin_unlock_irqrestore(&msi_lock, flags);
210}
211
212static int create_msi_irq(void)
213{
214 struct msi_desc *entry;
215 int irq;
216
217 entry = alloc_msi_entry();
218 if (!entry)
219 return -ENOMEM;
220
221 irq = create_irq();
222 if (irq < 0) {
223 kmem_cache_free(msi_cachep, entry);
224 return -EBUSY;
225 }
226
227 set_irq_data(irq, entry);
228
229 return irq;
230}
231
232static void destroy_msi_irq(unsigned int irq)
233{
234 struct msi_desc *entry;
235
236 entry = get_irq_data(irq);
237 set_irq_chip(irq, NULL);
238 set_irq_data(irq, NULL);
239 destroy_irq(irq);
240 kmem_cache_free(msi_cachep, entry);
241}
242
243static void enable_msi_mode(struct pci_dev *dev, int pos, int type) 195static void enable_msi_mode(struct pci_dev *dev, int pos, int type)
244{ 196{
245 u16 control; 197 u16 control;
@@ -278,36 +230,8 @@ void disable_msi_mode(struct pci_dev *dev, int pos, int type)
278 pci_intx(dev, 1); /* enable intx */ 230 pci_intx(dev, 1); /* enable intx */
279} 231}
280 232
281static int msi_lookup_irq(struct pci_dev *dev, int type)
282{
283 int irq;
284 unsigned long flags;
285
286 spin_lock_irqsave(&msi_lock, flags);
287 for (irq = 0; irq < NR_IRQS; irq++) {
288 if (!msi_desc[irq] || msi_desc[irq]->dev != dev ||
289 msi_desc[irq]->msi_attrib.type != type ||
290 msi_desc[irq]->msi_attrib.default_irq != dev->irq)
291 continue;
292 spin_unlock_irqrestore(&msi_lock, flags);
293 /* This pre-assigned MSI irq for this device
294 already exits. Override dev->irq with this irq */
295 dev->irq = irq;
296 return 0;
297 }
298 spin_unlock_irqrestore(&msi_lock, flags);
299
300 return -EACCES;
301}
302
303void pci_scan_msi_device(struct pci_dev *dev)
304{
305 if (!dev)
306 return;
307}
308
309#ifdef CONFIG_PM 233#ifdef CONFIG_PM
310int pci_save_msi_state(struct pci_dev *dev) 234static int __pci_save_msi_state(struct pci_dev *dev)
311{ 235{
312 int pos, i = 0; 236 int pos, i = 0;
313 u16 control; 237 u16 control;
@@ -345,7 +269,7 @@ int pci_save_msi_state(struct pci_dev *dev)
345 return 0; 269 return 0;
346} 270}
347 271
348void pci_restore_msi_state(struct pci_dev *dev) 272static void __pci_restore_msi_state(struct pci_dev *dev)
349{ 273{
350 int i = 0, pos; 274 int i = 0, pos;
351 u16 control; 275 u16 control;
@@ -373,14 +297,16 @@ void pci_restore_msi_state(struct pci_dev *dev)
373 kfree(save_state); 297 kfree(save_state);
374} 298}
375 299
376int pci_save_msix_state(struct pci_dev *dev) 300static int __pci_save_msix_state(struct pci_dev *dev)
377{ 301{
378 int pos; 302 int pos;
379 int temp;
380 int irq, head, tail = 0; 303 int irq, head, tail = 0;
381 u16 control; 304 u16 control;
382 struct pci_cap_saved_state *save_state; 305 struct pci_cap_saved_state *save_state;
383 306
307 if (!dev->msix_enabled)
308 return 0;
309
384 pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); 310 pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
385 if (pos <= 0 || dev->no_msi) 311 if (pos <= 0 || dev->no_msi)
386 return 0; 312 return 0;
@@ -398,38 +324,46 @@ int pci_save_msix_state(struct pci_dev *dev)
398 *((u16 *)&save_state->data[0]) = control; 324 *((u16 *)&save_state->data[0]) = control;
399 325
400 /* save the table */ 326 /* save the table */
401 temp = dev->irq; 327 irq = head = dev->first_msi_irq;
402 if (msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) {
403 kfree(save_state);
404 return -EINVAL;
405 }
406
407 irq = head = dev->irq;
408 while (head != tail) { 328 while (head != tail) {
409 struct msi_desc *entry; 329 struct msi_desc *entry;
410 330
411 entry = msi_desc[irq]; 331 entry = get_irq_msi(irq);
412 read_msi_msg(irq, &entry->msg_save); 332 read_msi_msg(irq, &entry->msg_save);
413 333
414 tail = msi_desc[irq]->link.tail; 334 tail = entry->link.tail;
415 irq = tail; 335 irq = tail;
416 } 336 }
417 dev->irq = temp;
418 337
419 save_state->cap_nr = PCI_CAP_ID_MSIX; 338 save_state->cap_nr = PCI_CAP_ID_MSIX;
420 pci_add_saved_cap(dev, save_state); 339 pci_add_saved_cap(dev, save_state);
421 return 0; 340 return 0;
422} 341}
423 342
424void pci_restore_msix_state(struct pci_dev *dev) 343int pci_save_msi_state(struct pci_dev *dev)
344{
345 int rc;
346
347 rc = __pci_save_msi_state(dev);
348 if (rc)
349 return rc;
350
351 rc = __pci_save_msix_state(dev);
352
353 return rc;
354}
355
356static void __pci_restore_msix_state(struct pci_dev *dev)
425{ 357{
426 u16 save; 358 u16 save;
427 int pos; 359 int pos;
428 int irq, head, tail = 0; 360 int irq, head, tail = 0;
429 struct msi_desc *entry; 361 struct msi_desc *entry;
430 int temp;
431 struct pci_cap_saved_state *save_state; 362 struct pci_cap_saved_state *save_state;
432 363
364 if (!dev->msix_enabled)
365 return;
366
433 save_state = pci_find_saved_cap(dev, PCI_CAP_ID_MSIX); 367 save_state = pci_find_saved_cap(dev, PCI_CAP_ID_MSIX);
434 if (!save_state) 368 if (!save_state)
435 return; 369 return;
@@ -442,23 +376,25 @@ void pci_restore_msix_state(struct pci_dev *dev)
442 return; 376 return;
443 377
444 /* route the table */ 378 /* route the table */
445 temp = dev->irq; 379 irq = head = dev->first_msi_irq;
446 if (msi_lookup_irq(dev, PCI_CAP_ID_MSIX))
447 return;
448 irq = head = dev->irq;
449 while (head != tail) { 380 while (head != tail) {
450 entry = msi_desc[irq]; 381 entry = get_irq_msi(irq);
451 write_msi_msg(irq, &entry->msg_save); 382 write_msi_msg(irq, &entry->msg_save);
452 383
453 tail = msi_desc[irq]->link.tail; 384 tail = entry->link.tail;
454 irq = tail; 385 irq = tail;
455 } 386 }
456 dev->irq = temp;
457 387
458 pci_write_config_word(dev, msi_control_reg(pos), save); 388 pci_write_config_word(dev, msi_control_reg(pos), save);
459 enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX); 389 enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX);
460} 390}
461#endif 391
392void pci_restore_msi_state(struct pci_dev *dev)
393{
394 __pci_restore_msi_state(dev);
395 __pci_restore_msix_state(dev);
396}
397#endif /* CONFIG_PM */
462 398
463/** 399/**
464 * msi_capability_init - configure device's MSI capability structure 400 * msi_capability_init - configure device's MSI capability structure
@@ -471,7 +407,6 @@ void pci_restore_msix_state(struct pci_dev *dev)
471 **/ 407 **/
472static int msi_capability_init(struct pci_dev *dev) 408static int msi_capability_init(struct pci_dev *dev)
473{ 409{
474 int status;
475 struct msi_desc *entry; 410 struct msi_desc *entry;
476 int pos, irq; 411 int pos, irq;
477 u16 control; 412 u16 control;
@@ -479,13 +414,10 @@ static int msi_capability_init(struct pci_dev *dev)
479 pos = pci_find_capability(dev, PCI_CAP_ID_MSI); 414 pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
480 pci_read_config_word(dev, msi_control_reg(pos), &control); 415 pci_read_config_word(dev, msi_control_reg(pos), &control);
481 /* MSI Entry Initialization */ 416 /* MSI Entry Initialization */
482 irq = create_msi_irq(); 417 entry = alloc_msi_entry();
483 if (irq < 0) 418 if (!entry)
484 return irq; 419 return -ENOMEM;
485 420
486 entry = get_irq_data(irq);
487 entry->link.head = irq;
488 entry->link.tail = irq;
489 entry->msi_attrib.type = PCI_CAP_ID_MSI; 421 entry->msi_attrib.type = PCI_CAP_ID_MSI;
490 entry->msi_attrib.is_64 = is_64bit_address(control); 422 entry->msi_attrib.is_64 = is_64bit_address(control);
491 entry->msi_attrib.entry_nr = 0; 423 entry->msi_attrib.entry_nr = 0;
@@ -511,13 +443,16 @@ static int msi_capability_init(struct pci_dev *dev)
511 maskbits); 443 maskbits);
512 } 444 }
513 /* Configure MSI capability structure */ 445 /* Configure MSI capability structure */
514 status = arch_setup_msi_irq(irq, dev); 446 irq = arch_setup_msi_irq(dev, entry);
515 if (status < 0) { 447 if (irq < 0) {
516 destroy_msi_irq(irq); 448 kmem_cache_free(msi_cachep, entry);
517 return status; 449 return irq;
518 } 450 }
451 entry->link.head = irq;
452 entry->link.tail = irq;
453 dev->first_msi_irq = irq;
454 set_irq_msi(irq, entry);
519 455
520 attach_msi_entry(entry, irq);
521 /* Set MSI enabled bits */ 456 /* Set MSI enabled bits */
522 enable_msi_mode(dev, pos, PCI_CAP_ID_MSI); 457 enable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
523 458
@@ -539,7 +474,6 @@ static int msix_capability_init(struct pci_dev *dev,
539 struct msix_entry *entries, int nvec) 474 struct msix_entry *entries, int nvec)
540{ 475{
541 struct msi_desc *head = NULL, *tail = NULL, *entry = NULL; 476 struct msi_desc *head = NULL, *tail = NULL, *entry = NULL;
542 int status;
543 int irq, pos, i, j, nr_entries, temp = 0; 477 int irq, pos, i, j, nr_entries, temp = 0;
544 unsigned long phys_addr; 478 unsigned long phys_addr;
545 u32 table_offset; 479 u32 table_offset;
@@ -562,13 +496,11 @@ static int msix_capability_init(struct pci_dev *dev,
562 496
563 /* MSI-X Table Initialization */ 497 /* MSI-X Table Initialization */
564 for (i = 0; i < nvec; i++) { 498 for (i = 0; i < nvec; i++) {
565 irq = create_msi_irq(); 499 entry = alloc_msi_entry();
566 if (irq < 0) 500 if (!entry)
567 break; 501 break;
568 502
569 entry = get_irq_data(irq);
570 j = entries[i].entry; 503 j = entries[i].entry;
571 entries[i].vector = irq;
572 entry->msi_attrib.type = PCI_CAP_ID_MSIX; 504 entry->msi_attrib.type = PCI_CAP_ID_MSIX;
573 entry->msi_attrib.is_64 = 1; 505 entry->msi_attrib.is_64 = 1;
574 entry->msi_attrib.entry_nr = j; 506 entry->msi_attrib.entry_nr = j;
@@ -577,6 +509,14 @@ static int msix_capability_init(struct pci_dev *dev,
577 entry->msi_attrib.pos = pos; 509 entry->msi_attrib.pos = pos;
578 entry->dev = dev; 510 entry->dev = dev;
579 entry->mask_base = base; 511 entry->mask_base = base;
512
513 /* Configure MSI-X capability structure */
514 irq = arch_setup_msi_irq(dev, entry);
515 if (irq < 0) {
516 kmem_cache_free(msi_cachep, entry);
517 break;
518 }
519 entries[i].vector = irq;
580 if (!head) { 520 if (!head) {
581 entry->link.head = irq; 521 entry->link.head = irq;
582 entry->link.tail = irq; 522 entry->link.tail = irq;
@@ -589,14 +529,8 @@ static int msix_capability_init(struct pci_dev *dev,
589 } 529 }
590 temp = irq; 530 temp = irq;
591 tail = entry; 531 tail = entry;
592 /* Configure MSI-X capability structure */
593 status = arch_setup_msi_irq(irq, dev);
594 if (status < 0) {
595 destroy_msi_irq(irq);
596 break;
597 }
598 532
599 attach_msi_entry(entry, irq); 533 set_irq_msi(irq, entry);
600 } 534 }
601 if (i != nvec) { 535 if (i != nvec) {
602 int avail = i - 1; 536 int avail = i - 1;
@@ -613,6 +547,7 @@ static int msix_capability_init(struct pci_dev *dev,
613 avail = -EBUSY; 547 avail = -EBUSY;
614 return avail; 548 return avail;
615 } 549 }
550 dev->first_msi_irq = entries[0].vector;
616 /* Set MSI-X enabled bits */ 551 /* Set MSI-X enabled bits */
617 enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX); 552 enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX);
618 553
@@ -660,13 +595,11 @@ int pci_msi_supported(struct pci_dev * dev)
660 **/ 595 **/
661int pci_enable_msi(struct pci_dev* dev) 596int pci_enable_msi(struct pci_dev* dev)
662{ 597{
663 int pos, temp, status; 598 int pos, status;
664 599
665 if (pci_msi_supported(dev) < 0) 600 if (pci_msi_supported(dev) < 0)
666 return -EINVAL; 601 return -EINVAL;
667 602
668 temp = dev->irq;
669
670 status = msi_init(); 603 status = msi_init();
671 if (status < 0) 604 if (status < 0)
672 return status; 605 return status;
@@ -675,15 +608,14 @@ int pci_enable_msi(struct pci_dev* dev)
675 if (!pos) 608 if (!pos)
676 return -EINVAL; 609 return -EINVAL;
677 610
678 WARN_ON(!msi_lookup_irq(dev, PCI_CAP_ID_MSI)); 611 WARN_ON(!!dev->msi_enabled);
679 612
680 /* Check whether driver already requested for MSI-X irqs */ 613 /* Check whether driver already requested for MSI-X irqs */
681 pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); 614 pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
682 if (pos > 0 && !msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) { 615 if (pos > 0 && dev->msix_enabled) {
683 printk(KERN_INFO "PCI: %s: Can't enable MSI. " 616 printk(KERN_INFO "PCI: %s: Can't enable MSI. "
684 "Device already has MSI-X irq assigned\n", 617 "Device already has MSI-X enabled\n",
685 pci_name(dev)); 618 pci_name(dev));
686 dev->irq = temp;
687 return -EINVAL; 619 return -EINVAL;
688 } 620 }
689 status = msi_capability_init(dev); 621 status = msi_capability_init(dev);
@@ -695,13 +627,15 @@ void pci_disable_msi(struct pci_dev* dev)
695 struct msi_desc *entry; 627 struct msi_desc *entry;
696 int pos, default_irq; 628 int pos, default_irq;
697 u16 control; 629 u16 control;
698 unsigned long flags;
699 630
700 if (!pci_msi_enable) 631 if (!pci_msi_enable)
701 return; 632 return;
702 if (!dev) 633 if (!dev)
703 return; 634 return;
704 635
636 if (!dev->msi_enabled)
637 return;
638
705 pos = pci_find_capability(dev, PCI_CAP_ID_MSI); 639 pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
706 if (!pos) 640 if (!pos)
707 return; 641 return;
@@ -710,28 +644,26 @@ void pci_disable_msi(struct pci_dev* dev)
710 if (!(control & PCI_MSI_FLAGS_ENABLE)) 644 if (!(control & PCI_MSI_FLAGS_ENABLE))
711 return; 645 return;
712 646
647
713 disable_msi_mode(dev, pos, PCI_CAP_ID_MSI); 648 disable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
714 649
715 spin_lock_irqsave(&msi_lock, flags); 650 entry = get_irq_msi(dev->first_msi_irq);
716 entry = msi_desc[dev->irq];
717 if (!entry || !entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) { 651 if (!entry || !entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) {
718 spin_unlock_irqrestore(&msi_lock, flags);
719 return; 652 return;
720 } 653 }
721 if (irq_has_action(dev->irq)) { 654 if (irq_has_action(dev->first_msi_irq)) {
722 spin_unlock_irqrestore(&msi_lock, flags);
723 printk(KERN_WARNING "PCI: %s: pci_disable_msi() called without " 655 printk(KERN_WARNING "PCI: %s: pci_disable_msi() called without "
724 "free_irq() on MSI irq %d\n", 656 "free_irq() on MSI irq %d\n",
725 pci_name(dev), dev->irq); 657 pci_name(dev), dev->first_msi_irq);
726 BUG_ON(irq_has_action(dev->irq)); 658 BUG_ON(irq_has_action(dev->first_msi_irq));
727 } else { 659 } else {
728 default_irq = entry->msi_attrib.default_irq; 660 default_irq = entry->msi_attrib.default_irq;
729 spin_unlock_irqrestore(&msi_lock, flags); 661 msi_free_irq(dev, dev->first_msi_irq);
730 msi_free_irq(dev, dev->irq);
731 662
732 /* Restore dev->irq to its default pin-assertion irq */ 663 /* Restore dev->irq to its default pin-assertion irq */
733 dev->irq = default_irq; 664 dev->irq = default_irq;
734 } 665 }
666 dev->first_msi_irq = 0;
735} 667}
736 668
737static int msi_free_irq(struct pci_dev* dev, int irq) 669static int msi_free_irq(struct pci_dev* dev, int irq)
@@ -739,27 +671,20 @@ static int msi_free_irq(struct pci_dev* dev, int irq)
739 struct msi_desc *entry; 671 struct msi_desc *entry;
740 int head, entry_nr, type; 672 int head, entry_nr, type;
741 void __iomem *base; 673 void __iomem *base;
742 unsigned long flags;
743 674
744 arch_teardown_msi_irq(irq); 675 entry = get_irq_msi(irq);
745
746 spin_lock_irqsave(&msi_lock, flags);
747 entry = msi_desc[irq];
748 if (!entry || entry->dev != dev) { 676 if (!entry || entry->dev != dev) {
749 spin_unlock_irqrestore(&msi_lock, flags);
750 return -EINVAL; 677 return -EINVAL;
751 } 678 }
752 type = entry->msi_attrib.type; 679 type = entry->msi_attrib.type;
753 entry_nr = entry->msi_attrib.entry_nr; 680 entry_nr = entry->msi_attrib.entry_nr;
754 head = entry->link.head; 681 head = entry->link.head;
755 base = entry->mask_base; 682 base = entry->mask_base;
756 msi_desc[entry->link.head]->link.tail = entry->link.tail; 683 get_irq_msi(entry->link.head)->link.tail = entry->link.tail;
757 msi_desc[entry->link.tail]->link.head = entry->link.head; 684 get_irq_msi(entry->link.tail)->link.head = entry->link.head;
758 entry->dev = NULL;
759 msi_desc[irq] = NULL;
760 spin_unlock_irqrestore(&msi_lock, flags);
761 685
762 destroy_msi_irq(irq); 686 arch_teardown_msi_irq(irq);
687 kmem_cache_free(msi_cachep, entry);
763 688
764 if (type == PCI_CAP_ID_MSIX) { 689 if (type == PCI_CAP_ID_MSIX) {
765 writel(1, base + entry_nr * PCI_MSIX_ENTRY_SIZE + 690 writel(1, base + entry_nr * PCI_MSIX_ENTRY_SIZE +
@@ -790,7 +715,7 @@ static int msi_free_irq(struct pci_dev* dev, int irq)
790int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) 715int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
791{ 716{
792 int status, pos, nr_entries; 717 int status, pos, nr_entries;
793 int i, j, temp; 718 int i, j;
794 u16 control; 719 u16 control;
795 720
796 if (!entries || pci_msi_supported(dev) < 0) 721 if (!entries || pci_msi_supported(dev) < 0)
@@ -818,16 +743,14 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
818 return -EINVAL; /* duplicate entry */ 743 return -EINVAL; /* duplicate entry */
819 } 744 }
820 } 745 }
821 temp = dev->irq; 746 WARN_ON(!!dev->msix_enabled);
822 WARN_ON(!msi_lookup_irq(dev, PCI_CAP_ID_MSIX));
823 747
824 /* Check whether driver already requested for MSI irq */ 748 /* Check whether driver already requested for MSI irq */
825 if (pci_find_capability(dev, PCI_CAP_ID_MSI) > 0 && 749 if (pci_find_capability(dev, PCI_CAP_ID_MSI) > 0 &&
826 !msi_lookup_irq(dev, PCI_CAP_ID_MSI)) { 750 dev->msi_enabled) {
827 printk(KERN_INFO "PCI: %s: Can't enable MSI-X. " 751 printk(KERN_INFO "PCI: %s: Can't enable MSI-X. "
828 "Device already has an MSI irq assigned\n", 752 "Device already has an MSI irq assigned\n",
829 pci_name(dev)); 753 pci_name(dev));
830 dev->irq = temp;
831 return -EINVAL; 754 return -EINVAL;
832 } 755 }
833 status = msix_capability_init(dev, entries, nvec); 756 status = msix_capability_init(dev, entries, nvec);
@@ -836,7 +759,8 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
836 759
837void pci_disable_msix(struct pci_dev* dev) 760void pci_disable_msix(struct pci_dev* dev)
838{ 761{
839 int pos, temp; 762 int irq, head, tail = 0, warning = 0;
763 int pos;
840 u16 control; 764 u16 control;
841 765
842 if (!pci_msi_enable) 766 if (!pci_msi_enable)
@@ -844,6 +768,9 @@ void pci_disable_msix(struct pci_dev* dev)
844 if (!dev) 768 if (!dev)
845 return; 769 return;
846 770
771 if (!dev->msix_enabled)
772 return;
773
847 pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); 774 pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
848 if (!pos) 775 if (!pos)
849 return; 776 return;
@@ -854,31 +781,23 @@ void pci_disable_msix(struct pci_dev* dev)
854 781
855 disable_msi_mode(dev, pos, PCI_CAP_ID_MSIX); 782 disable_msi_mode(dev, pos, PCI_CAP_ID_MSIX);
856 783
857 temp = dev->irq; 784 irq = head = dev->first_msi_irq;
858 if (!msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) { 785 while (head != tail) {
859 int irq, head, tail = 0, warning = 0; 786 tail = get_irq_msi(irq)->link.tail;
860 unsigned long flags; 787 if (irq_has_action(irq))
861 788 warning = 1;
862 irq = head = dev->irq; 789 else if (irq != head) /* Release MSI-X irq */
863 dev->irq = temp; /* Restore pin IRQ */ 790 msi_free_irq(dev, irq);
864 while (head != tail) { 791 irq = tail;
865 spin_lock_irqsave(&msi_lock, flags); 792 }
866 tail = msi_desc[irq]->link.tail; 793 msi_free_irq(dev, irq);
867 spin_unlock_irqrestore(&msi_lock, flags); 794 if (warning) {
868 if (irq_has_action(irq)) 795 printk(KERN_WARNING "PCI: %s: pci_disable_msix() called without "
869 warning = 1; 796 "free_irq() on all MSI-X irqs\n",
870 else if (irq != head) /* Release MSI-X irq */ 797 pci_name(dev));
871 msi_free_irq(dev, irq); 798 BUG_ON(warning > 0);
872 irq = tail;
873 }
874 msi_free_irq(dev, irq);
875 if (warning) {
876 printk(KERN_WARNING "PCI: %s: pci_disable_msix() called without "
877 "free_irq() on all MSI-X irqs\n",
878 pci_name(dev));
879 BUG_ON(warning > 0);
880 }
881 } 799 }
800 dev->first_msi_irq = 0;
882} 801}
883 802
884/** 803/**
@@ -892,35 +811,26 @@ void pci_disable_msix(struct pci_dev* dev)
892 **/ 811 **/
893void msi_remove_pci_irq_vectors(struct pci_dev* dev) 812void msi_remove_pci_irq_vectors(struct pci_dev* dev)
894{ 813{
895 int pos, temp;
896 unsigned long flags;
897
898 if (!pci_msi_enable || !dev) 814 if (!pci_msi_enable || !dev)
899 return; 815 return;
900 816
901 temp = dev->irq; /* Save IOAPIC IRQ */ 817 if (dev->msi_enabled) {
902 pos = pci_find_capability(dev, PCI_CAP_ID_MSI); 818 if (irq_has_action(dev->first_msi_irq)) {
903 if (pos > 0 && !msi_lookup_irq(dev, PCI_CAP_ID_MSI)) {
904 if (irq_has_action(dev->irq)) {
905 printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() " 819 printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() "
906 "called without free_irq() on MSI irq %d\n", 820 "called without free_irq() on MSI irq %d\n",
907 pci_name(dev), dev->irq); 821 pci_name(dev), dev->first_msi_irq);
908 BUG_ON(irq_has_action(dev->irq)); 822 BUG_ON(irq_has_action(dev->first_msi_irq));
909 } else /* Release MSI irq assigned to this device */ 823 } else /* Release MSI irq assigned to this device */
910 msi_free_irq(dev, dev->irq); 824 msi_free_irq(dev, dev->first_msi_irq);
911 dev->irq = temp; /* Restore IOAPIC IRQ */
912 } 825 }
913 pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); 826 if (dev->msix_enabled) {
914 if (pos > 0 && !msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) {
915 int irq, head, tail = 0, warning = 0; 827 int irq, head, tail = 0, warning = 0;
916 void __iomem *base = NULL; 828 void __iomem *base = NULL;
917 829
918 irq = head = dev->irq; 830 irq = head = dev->first_msi_irq;
919 while (head != tail) { 831 while (head != tail) {
920 spin_lock_irqsave(&msi_lock, flags); 832 tail = get_irq_msi(irq)->link.tail;
921 tail = msi_desc[irq]->link.tail; 833 base = get_irq_msi(irq)->mask_base;
922 base = msi_desc[irq]->mask_base;
923 spin_unlock_irqrestore(&msi_lock, flags);
924 if (irq_has_action(irq)) 834 if (irq_has_action(irq))
925 warning = 1; 835 warning = 1;
926 else if (irq != head) /* Release MSI-X irq */ 836 else if (irq != head) /* Release MSI-X irq */
@@ -935,7 +845,6 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev)
935 pci_name(dev)); 845 pci_name(dev));
936 BUG_ON(warning > 0); 846 BUG_ON(warning > 0);
937 } 847 }
938 dev->irq = temp; /* Restore IOAPIC IRQ */
939 } 848 }
940} 849}
941 850