[PATCH] msi: synchronously mask and unmask msi-x irqs.
[linux-2.6.git] / drivers / pci / msi.c
1 /*
2  * File:        msi.c
3  * Purpose:     PCI Message Signaled Interrupt (MSI)
4  *
5  * Copyright (C) 2003-2004 Intel
6  * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
7  */
8
9 #include <linux/err.h>
10 #include <linux/mm.h>
11 #include <linux/irq.h>
12 #include <linux/interrupt.h>
13 #include <linux/init.h>
14 #include <linux/ioport.h>
15 #include <linux/smp_lock.h>
16 #include <linux/pci.h>
17 #include <linux/proc_fs.h>
18 #include <linux/msi.h>
19
20 #include <asm/errno.h>
21 #include <asm/io.h>
22 #include <asm/smp.h>
23
24 #include "pci.h"
25 #include "msi.h"
26
27 static struct kmem_cache* msi_cachep;
28
29 static int pci_msi_enable = 1;
30
31 static int msi_cache_init(void)
32 {
33         msi_cachep = kmem_cache_create("msi_cache", sizeof(struct msi_desc),
34                                         0, SLAB_HWCACHE_ALIGN, NULL, NULL);
35         if (!msi_cachep)
36                 return -ENOMEM;
37
38         return 0;
39 }
40
41 static void msi_set_enable(struct pci_dev *dev, int enable)
42 {
43         int pos;
44         u16 control;
45
46         pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
47         if (pos) {
48                 pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control);
49                 control &= ~PCI_MSI_FLAGS_ENABLE;
50                 if (enable)
51                         control |= PCI_MSI_FLAGS_ENABLE;
52                 pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control);
53         }
54 }
55
56 static void msix_set_enable(struct pci_dev *dev, int enable)
57 {
58         int pos;
59         u16 control;
60
61         pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
62         if (pos) {
63                 pci_read_config_word(dev, pos + PCI_MSIX_FLAGS, &control);
64                 control &= ~PCI_MSIX_FLAGS_ENABLE;
65                 if (enable)
66                         control |= PCI_MSIX_FLAGS_ENABLE;
67                 pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control);
68         }
69 }
70
71 static void msi_set_mask_bit(unsigned int irq, int flag)
72 {
73         struct msi_desc *entry;
74
75         entry = get_irq_msi(irq);
76         BUG_ON(!entry || !entry->dev);
77         switch (entry->msi_attrib.type) {
78         case PCI_CAP_ID_MSI:
79                 if (entry->msi_attrib.maskbit) {
80                         int pos;
81                         u32 mask_bits;
82
83                         pos = (long)entry->mask_base;
84                         pci_read_config_dword(entry->dev, pos, &mask_bits);
85                         mask_bits &= ~(1);
86                         mask_bits |= flag;
87                         pci_write_config_dword(entry->dev, pos, mask_bits);
88                 } else {
89                         msi_set_enable(entry->dev, !flag);
90                 }
91                 break;
92         case PCI_CAP_ID_MSIX:
93         {
94                 int offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
95                         PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET;
96                 writel(flag, entry->mask_base + offset);
97                 readl(entry->mask_base + offset);
98                 break;
99         }
100         default:
101                 BUG();
102                 break;
103         }
104         entry->msi_attrib.masked = !!flag;
105 }
106
107 void read_msi_msg(unsigned int irq, struct msi_msg *msg)
108 {
109         struct msi_desc *entry = get_irq_msi(irq);
110         switch(entry->msi_attrib.type) {
111         case PCI_CAP_ID_MSI:
112         {
113                 struct pci_dev *dev = entry->dev;
114                 int pos = entry->msi_attrib.pos;
115                 u16 data;
116
117                 pci_read_config_dword(dev, msi_lower_address_reg(pos),
118                                         &msg->address_lo);
119                 if (entry->msi_attrib.is_64) {
120                         pci_read_config_dword(dev, msi_upper_address_reg(pos),
121                                                 &msg->address_hi);
122                         pci_read_config_word(dev, msi_data_reg(pos, 1), &data);
123                 } else {
124                         msg->address_hi = 0;
125                         pci_read_config_word(dev, msi_data_reg(pos, 1), &data);
126                 }
127                 msg->data = data;
128                 break;
129         }
130         case PCI_CAP_ID_MSIX:
131         {
132                 void __iomem *base;
133                 base = entry->mask_base +
134                         entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE;
135
136                 msg->address_lo = readl(base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
137                 msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
138                 msg->data = readl(base + PCI_MSIX_ENTRY_DATA_OFFSET);
139                 break;
140         }
141         default:
142                 BUG();
143         }
144 }
145
146 void write_msi_msg(unsigned int irq, struct msi_msg *msg)
147 {
148         struct msi_desc *entry = get_irq_msi(irq);
149         switch (entry->msi_attrib.type) {
150         case PCI_CAP_ID_MSI:
151         {
152                 struct pci_dev *dev = entry->dev;
153                 int pos = entry->msi_attrib.pos;
154
155                 pci_write_config_dword(dev, msi_lower_address_reg(pos),
156                                         msg->address_lo);
157                 if (entry->msi_attrib.is_64) {
158                         pci_write_config_dword(dev, msi_upper_address_reg(pos),
159                                                 msg->address_hi);
160                         pci_write_config_word(dev, msi_data_reg(pos, 1),
161                                                 msg->data);
162                 } else {
163                         pci_write_config_word(dev, msi_data_reg(pos, 0),
164                                                 msg->data);
165                 }
166                 break;
167         }
168         case PCI_CAP_ID_MSIX:
169         {
170                 void __iomem *base;
171                 base = entry->mask_base +
172                         entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE;
173
174                 writel(msg->address_lo,
175                         base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
176                 writel(msg->address_hi,
177                         base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
178                 writel(msg->data, base + PCI_MSIX_ENTRY_DATA_OFFSET);
179                 break;
180         }
181         default:
182                 BUG();
183         }
184         entry->msg = *msg;
185 }
186
187 void mask_msi_irq(unsigned int irq)
188 {
189         msi_set_mask_bit(irq, 1);
190 }
191
192 void unmask_msi_irq(unsigned int irq)
193 {
194         msi_set_mask_bit(irq, 0);
195 }
196
197 static int msi_free_irq(struct pci_dev* dev, int irq);
198
199 static int msi_init(void)
200 {
201         static int status = -ENOMEM;
202
203         if (!status)
204                 return status;
205
206         status = msi_cache_init();
207         if (status < 0) {
208                 pci_msi_enable = 0;
209                 printk(KERN_WARNING "PCI: MSI cache init failed\n");
210                 return status;
211         }
212
213         return status;
214 }
215
216 static struct msi_desc* alloc_msi_entry(void)
217 {
218         struct msi_desc *entry;
219
220         entry = kmem_cache_zalloc(msi_cachep, GFP_KERNEL);
221         if (!entry)
222                 return NULL;
223
224         entry->link.tail = entry->link.head = 0;        /* single message */
225         entry->dev = NULL;
226
227         return entry;
228 }
229
230 #ifdef CONFIG_PM
231 static void __pci_restore_msi_state(struct pci_dev *dev)
232 {
233         int pos;
234         u16 control;
235         struct msi_desc *entry;
236
237         if (!dev->msi_enabled)
238                 return;
239
240         entry = get_irq_msi(dev->irq);
241         pos = entry->msi_attrib.pos;
242
243         pci_intx(dev, 0);               /* disable intx */
244         msi_set_enable(dev, 0);
245         write_msi_msg(dev->irq, &entry->msg);
246         if (entry->msi_attrib.maskbit)
247                 msi_set_mask_bit(dev->irq, entry->msi_attrib.masked);
248
249         pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control);
250         control &= ~(PCI_MSI_FLAGS_QSIZE | PCI_MSI_FLAGS_ENABLE);
251         if (entry->msi_attrib.maskbit || !entry->msi_attrib.masked)
252                 control |= PCI_MSI_FLAGS_ENABLE;
253         pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control);
254 }
255
256 static void __pci_restore_msix_state(struct pci_dev *dev)
257 {
258         int pos;
259         int irq, head, tail = 0;
260         struct msi_desc *entry;
261         u16 control;
262
263         if (!dev->msix_enabled)
264                 return;
265
266         /* route the table */
267         pci_intx(dev, 0);               /* disable intx */
268         msix_set_enable(dev, 0);
269         irq = head = dev->first_msi_irq;
270         entry = get_irq_msi(irq);
271         pos = entry->msi_attrib.pos;
272         while (head != tail) {
273                 entry = get_irq_msi(irq);
274                 write_msi_msg(irq, &entry->msg);
275                 msi_set_mask_bit(irq, entry->msi_attrib.masked);
276
277                 tail = entry->link.tail;
278                 irq = tail;
279         }
280
281         pci_read_config_word(dev, pos + PCI_MSIX_FLAGS, &control);
282         control &= ~PCI_MSIX_FLAGS_MASKALL;
283         control |= PCI_MSIX_FLAGS_ENABLE;
284         pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control);
285 }
286
287 void pci_restore_msi_state(struct pci_dev *dev)
288 {
289         __pci_restore_msi_state(dev);
290         __pci_restore_msix_state(dev);
291 }
292 #endif  /* CONFIG_PM */
293
294 /**
295  * msi_capability_init - configure device's MSI capability structure
296  * @dev: pointer to the pci_dev data structure of MSI device function
297  *
298  * Setup the MSI capability structure of device function with a single
299  * MSI irq, regardless of device function is capable of handling
300  * multiple messages. A return of zero indicates the successful setup
301  * of an entry zero with the new MSI irq or non-zero for otherwise.
302  **/
303 static int msi_capability_init(struct pci_dev *dev)
304 {
305         struct msi_desc *entry;
306         int pos, irq;
307         u16 control;
308
309         msi_set_enable(dev, 0); /* Ensure msi is disabled as I set it up */
310
311         pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
312         pci_read_config_word(dev, msi_control_reg(pos), &control);
313         /* MSI Entry Initialization */
314         entry = alloc_msi_entry();
315         if (!entry)
316                 return -ENOMEM;
317
318         entry->msi_attrib.type = PCI_CAP_ID_MSI;
319         entry->msi_attrib.is_64 = is_64bit_address(control);
320         entry->msi_attrib.entry_nr = 0;
321         entry->msi_attrib.maskbit = is_mask_bit_support(control);
322         entry->msi_attrib.masked = 1;
323         entry->msi_attrib.default_irq = dev->irq;       /* Save IOAPIC IRQ */
324         entry->msi_attrib.pos = pos;
325         if (is_mask_bit_support(control)) {
326                 entry->mask_base = (void __iomem *)(long)msi_mask_bits_reg(pos,
327                                 is_64bit_address(control));
328         }
329         entry->dev = dev;
330         if (entry->msi_attrib.maskbit) {
331                 unsigned int maskbits, temp;
332                 /* All MSIs are unmasked by default, Mask them all */
333                 pci_read_config_dword(dev,
334                         msi_mask_bits_reg(pos, is_64bit_address(control)),
335                         &maskbits);
336                 temp = (1 << multi_msi_capable(control));
337                 temp = ((temp - 1) & ~temp);
338                 maskbits |= temp;
339                 pci_write_config_dword(dev,
340                         msi_mask_bits_reg(pos, is_64bit_address(control)),
341                         maskbits);
342         }
343         /* Configure MSI capability structure */
344         irq = arch_setup_msi_irq(dev, entry);
345         if (irq < 0) {
346                 kmem_cache_free(msi_cachep, entry);
347                 return irq;
348         }
349         entry->link.head = irq;
350         entry->link.tail = irq;
351         dev->first_msi_irq = irq;
352         set_irq_msi(irq, entry);
353
354         /* Set MSI enabled bits  */
355         pci_intx(dev, 0);               /* disable intx */
356         msi_set_enable(dev, 1);
357         dev->msi_enabled = 1;
358
359         dev->irq = irq;
360         return 0;
361 }
362
363 /**
364  * msix_capability_init - configure device's MSI-X capability
365  * @dev: pointer to the pci_dev data structure of MSI-X device function
366  * @entries: pointer to an array of struct msix_entry entries
367  * @nvec: number of @entries
368  *
369  * Setup the MSI-X capability structure of device function with a
370  * single MSI-X irq. A return of zero indicates the successful setup of
371  * requested MSI-X entries with allocated irqs or non-zero for otherwise.
372  **/
373 static int msix_capability_init(struct pci_dev *dev,
374                                 struct msix_entry *entries, int nvec)
375 {
376         struct msi_desc *head = NULL, *tail = NULL, *entry = NULL;
377         int irq, pos, i, j, nr_entries, temp = 0;
378         unsigned long phys_addr;
379         u32 table_offset;
380         u16 control;
381         u8 bir;
382         void __iomem *base;
383
384         msix_set_enable(dev, 0);/* Ensure msix is disabled as I set it up */
385
386         pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
387         /* Request & Map MSI-X table region */
388         pci_read_config_word(dev, msi_control_reg(pos), &control);
389         nr_entries = multi_msix_capable(control);
390
391         pci_read_config_dword(dev, msix_table_offset_reg(pos), &table_offset);
392         bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK);
393         table_offset &= ~PCI_MSIX_FLAGS_BIRMASK;
394         phys_addr = pci_resource_start (dev, bir) + table_offset;
395         base = ioremap_nocache(phys_addr, nr_entries * PCI_MSIX_ENTRY_SIZE);
396         if (base == NULL)
397                 return -ENOMEM;
398
399         /* MSI-X Table Initialization */
400         for (i = 0; i < nvec; i++) {
401                 entry = alloc_msi_entry();
402                 if (!entry)
403                         break;
404
405                 j = entries[i].entry;
406                 entry->msi_attrib.type = PCI_CAP_ID_MSIX;
407                 entry->msi_attrib.is_64 = 1;
408                 entry->msi_attrib.entry_nr = j;
409                 entry->msi_attrib.maskbit = 1;
410                 entry->msi_attrib.masked = 1;
411                 entry->msi_attrib.default_irq = dev->irq;
412                 entry->msi_attrib.pos = pos;
413                 entry->dev = dev;
414                 entry->mask_base = base;
415
416                 /* Configure MSI-X capability structure */
417                 irq = arch_setup_msi_irq(dev, entry);
418                 if (irq < 0) {
419                         kmem_cache_free(msi_cachep, entry);
420                         break;
421                 }
422                 entries[i].vector = irq;
423                 if (!head) {
424                         entry->link.head = irq;
425                         entry->link.tail = irq;
426                         head = entry;
427                 } else {
428                         entry->link.head = temp;
429                         entry->link.tail = tail->link.tail;
430                         tail->link.tail = irq;
431                         head->link.head = irq;
432                 }
433                 temp = irq;
434                 tail = entry;
435
436                 set_irq_msi(irq, entry);
437         }
438         if (i != nvec) {
439                 int avail = i - 1;
440                 i--;
441                 for (; i >= 0; i--) {
442                         irq = (entries + i)->vector;
443                         msi_free_irq(dev, irq);
444                         (entries + i)->vector = 0;
445                 }
446                 /* If we had some success report the number of irqs
447                  * we succeeded in setting up.
448                  */
449                 if (avail <= 0)
450                         avail = -EBUSY;
451                 return avail;
452         }
453         dev->first_msi_irq = entries[0].vector;
454         /* Set MSI-X enabled bits */
455         pci_intx(dev, 0);               /* disable intx */
456         msix_set_enable(dev, 1);
457         dev->msix_enabled = 1;
458
459         return 0;
460 }
461
462 /**
463  * pci_msi_supported - check whether MSI may be enabled on device
464  * @dev: pointer to the pci_dev data structure of MSI device function
465  *
466  * Look at global flags, the device itself, and its parent busses
467  * to return 0 if MSI are supported for the device.
468  **/
469 static
470 int pci_msi_supported(struct pci_dev * dev)
471 {
472         struct pci_bus *bus;
473
474         /* MSI must be globally enabled and supported by the device */
475         if (!pci_msi_enable || !dev || dev->no_msi)
476                 return -EINVAL;
477
478         /* Any bridge which does NOT route MSI transactions from it's
479          * secondary bus to it's primary bus must set NO_MSI flag on
480          * the secondary pci_bus.
481          * We expect only arch-specific PCI host bus controller driver
482          * or quirks for specific PCI bridges to be setting NO_MSI.
483          */
484         for (bus = dev->bus; bus; bus = bus->parent)
485                 if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI)
486                         return -EINVAL;
487
488         return 0;
489 }
490
491 /**
492  * pci_enable_msi - configure device's MSI capability structure
493  * @dev: pointer to the pci_dev data structure of MSI device function
494  *
495  * Setup the MSI capability structure of device function with
496  * a single MSI irq upon its software driver call to request for
497  * MSI mode enabled on its hardware device function. A return of zero
498  * indicates the successful setup of an entry zero with the new MSI
499  * irq or non-zero for otherwise.
500  **/
501 int pci_enable_msi(struct pci_dev* dev)
502 {
503         int pos, status;
504
505         if (pci_msi_supported(dev) < 0)
506                 return -EINVAL;
507
508         status = msi_init();
509         if (status < 0)
510                 return status;
511
512         pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
513         if (!pos)
514                 return -EINVAL;
515
516         WARN_ON(!!dev->msi_enabled);
517
518         /* Check whether driver already requested for MSI-X irqs */
519         if (dev->msix_enabled) {
520                 printk(KERN_INFO "PCI: %s: Can't enable MSI.  "
521                         "Device already has MSI-X enabled\n",
522                         pci_name(dev));
523                 return -EINVAL;
524         }
525         status = msi_capability_init(dev);
526         return status;
527 }
528
529 void pci_disable_msi(struct pci_dev* dev)
530 {
531         struct msi_desc *entry;
532         int default_irq;
533
534         if (!pci_msi_enable)
535                 return;
536         if (!dev)
537                 return;
538
539         if (!dev->msi_enabled)
540                 return;
541
542         msi_set_enable(dev, 0);
543         pci_intx(dev, 1);               /* enable intx */
544         dev->msi_enabled = 0;
545
546         entry = get_irq_msi(dev->first_msi_irq);
547         if (!entry || !entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) {
548                 return;
549         }
550         if (irq_has_action(dev->first_msi_irq)) {
551                 printk(KERN_WARNING "PCI: %s: pci_disable_msi() called without "
552                        "free_irq() on MSI irq %d\n",
553                        pci_name(dev), dev->first_msi_irq);
554                 BUG_ON(irq_has_action(dev->first_msi_irq));
555         } else {
556                 default_irq = entry->msi_attrib.default_irq;
557                 msi_free_irq(dev, dev->first_msi_irq);
558
559                 /* Restore dev->irq to its default pin-assertion irq */
560                 dev->irq = default_irq;
561         }
562         dev->first_msi_irq = 0;
563 }
564
565 static int msi_free_irq(struct pci_dev* dev, int irq)
566 {
567         struct msi_desc *entry;
568         int head, entry_nr, type;
569         void __iomem *base;
570
571         entry = get_irq_msi(irq);
572         if (!entry || entry->dev != dev) {
573                 return -EINVAL;
574         }
575         type = entry->msi_attrib.type;
576         entry_nr = entry->msi_attrib.entry_nr;
577         head = entry->link.head;
578         base = entry->mask_base;
579         get_irq_msi(entry->link.head)->link.tail = entry->link.tail;
580         get_irq_msi(entry->link.tail)->link.head = entry->link.head;
581
582         arch_teardown_msi_irq(irq);
583         kmem_cache_free(msi_cachep, entry);
584
585         if (type == PCI_CAP_ID_MSIX) {
586                 writel(1, base + entry_nr * PCI_MSIX_ENTRY_SIZE +
587                         PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
588
589                 if (head == irq)
590                         iounmap(base);
591         }
592
593         return 0;
594 }
595
596 /**
597  * pci_enable_msix - configure device's MSI-X capability structure
598  * @dev: pointer to the pci_dev data structure of MSI-X device function
599  * @entries: pointer to an array of MSI-X entries
600  * @nvec: number of MSI-X irqs requested for allocation by device driver
601  *
602  * Setup the MSI-X capability structure of device function with the number
603  * of requested irqs upon its software driver call to request for
604  * MSI-X mode enabled on its hardware device function. A return of zero
605  * indicates the successful configuration of MSI-X capability structure
606  * with new allocated MSI-X irqs. A return of < 0 indicates a failure.
607  * Or a return of > 0 indicates that driver request is exceeding the number
608  * of irqs available. Driver should use the returned value to re-send
609  * its request.
610  **/
611 int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
612 {
613         int status, pos, nr_entries;
614         int i, j;
615         u16 control;
616
617         if (!entries || pci_msi_supported(dev) < 0)
618                 return -EINVAL;
619
620         status = msi_init();
621         if (status < 0)
622                 return status;
623
624         pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
625         if (!pos)
626                 return -EINVAL;
627
628         pci_read_config_word(dev, msi_control_reg(pos), &control);
629         nr_entries = multi_msix_capable(control);
630         if (nvec > nr_entries)
631                 return -EINVAL;
632
633         /* Check for any invalid entries */
634         for (i = 0; i < nvec; i++) {
635                 if (entries[i].entry >= nr_entries)
636                         return -EINVAL;         /* invalid entry */
637                 for (j = i + 1; j < nvec; j++) {
638                         if (entries[i].entry == entries[j].entry)
639                                 return -EINVAL; /* duplicate entry */
640                 }
641         }
642         WARN_ON(!!dev->msix_enabled);
643
644         /* Check whether driver already requested for MSI irq */
645         if (dev->msi_enabled) {
646                 printk(KERN_INFO "PCI: %s: Can't enable MSI-X.  "
647                        "Device already has an MSI irq assigned\n",
648                        pci_name(dev));
649                 return -EINVAL;
650         }
651         status = msix_capability_init(dev, entries, nvec);
652         return status;
653 }
654
655 void pci_disable_msix(struct pci_dev* dev)
656 {
657         int irq, head, tail = 0, warning = 0;
658
659         if (!pci_msi_enable)
660                 return;
661         if (!dev)
662                 return;
663
664         if (!dev->msix_enabled)
665                 return;
666
667         msix_set_enable(dev, 0);
668         pci_intx(dev, 1);               /* enable intx */
669         dev->msix_enabled = 0;
670
671         irq = head = dev->first_msi_irq;
672         while (head != tail) {
673                 tail = get_irq_msi(irq)->link.tail;
674                 if (irq_has_action(irq))
675                         warning = 1;
676                 else if (irq != head)   /* Release MSI-X irq */
677                         msi_free_irq(dev, irq);
678                 irq = tail;
679         }
680         msi_free_irq(dev, irq);
681         if (warning) {
682                 printk(KERN_WARNING "PCI: %s: pci_disable_msix() called without "
683                         "free_irq() on all MSI-X irqs\n",
684                         pci_name(dev));
685                 BUG_ON(warning > 0);
686         }
687         dev->first_msi_irq = 0;
688 }
689
690 /**
691  * msi_remove_pci_irq_vectors - reclaim MSI(X) irqs to unused state
692  * @dev: pointer to the pci_dev data structure of MSI(X) device function
693  *
694  * Being called during hotplug remove, from which the device function
695  * is hot-removed. All previous assigned MSI/MSI-X irqs, if
696  * allocated for this device function, are reclaimed to unused state,
697  * which may be used later on.
698  **/
699 void msi_remove_pci_irq_vectors(struct pci_dev* dev)
700 {
701         if (!pci_msi_enable || !dev)
702                 return;
703
704         if (dev->msi_enabled) {
705                 if (irq_has_action(dev->first_msi_irq)) {
706                         printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() "
707                                "called without free_irq() on MSI irq %d\n",
708                                pci_name(dev), dev->first_msi_irq);
709                         BUG_ON(irq_has_action(dev->first_msi_irq));
710                 } else /* Release MSI irq assigned to this device */
711                         msi_free_irq(dev, dev->first_msi_irq);
712         }
713         if (dev->msix_enabled) {
714                 int irq, head, tail = 0, warning = 0;
715                 void __iomem *base = NULL;
716
717                 irq = head = dev->first_msi_irq;
718                 while (head != tail) {
719                         tail = get_irq_msi(irq)->link.tail;
720                         base = get_irq_msi(irq)->mask_base;
721                         if (irq_has_action(irq))
722                                 warning = 1;
723                         else if (irq != head) /* Release MSI-X irq */
724                                 msi_free_irq(dev, irq);
725                         irq = tail;
726                 }
727                 msi_free_irq(dev, irq);
728                 if (warning) {
729                         iounmap(base);
730                         printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() "
731                                "called without free_irq() on all MSI-X irqs\n",
732                                pci_name(dev));
733                         BUG_ON(warning > 0);
734                 }
735         }
736 }
737
738 void pci_no_msi(void)
739 {
740         pci_msi_enable = 0;
741 }
742
743 EXPORT_SYMBOL(pci_enable_msi);
744 EXPORT_SYMBOL(pci_disable_msi);
745 EXPORT_SYMBOL(pci_enable_msix);
746 EXPORT_SYMBOL(pci_disable_msix);