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