Lines Matching +full:msi +full:- +full:x
1 // SPDX-License-Identifier: GPL-2.0
3 * PCI Message Signaled Interrupt (MSI)
5 * Copyright (C) 2003-2004 Intel
14 #include "msi.h"
21 raw_spinlock_t *lock = &to_pci_dev(desc->dev)->msi_lock; in pci_msi_update_mask()
24 if (!desc->pci.msi_attrib.can_mask) in pci_msi_update_mask()
28 desc->pci.msi_mask &= ~clear; in pci_msi_update_mask()
29 desc->pci.msi_mask |= set; in pci_msi_update_mask()
30 pci_write_config_dword(msi_desc_to_pci_dev(desc), desc->pci.mask_pos, in pci_msi_update_mask()
31 desc->pci.msi_mask); in pci_msi_update_mask()
47 return desc->pci.mask_base + desc->msi_index * PCI_MSIX_ENTRY_SIZE; in pci_msix_desc_addr()
60 if (desc->pci.msi_attrib.can_mask) in pci_msix_write_vector_ctrl()
66 desc->pci.msix_ctrl |= PCI_MSIX_ENTRY_CTRL_MASKBIT; in pci_msix_mask()
67 pci_msix_write_vector_ctrl(desc, desc->pci.msix_ctrl); in pci_msix_mask()
69 readl(desc->pci.mask_base); in pci_msix_mask()
74 desc->pci.msix_ctrl &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT; in pci_msix_unmask()
75 pci_msix_write_vector_ctrl(desc, desc->pci.msix_ctrl); in pci_msix_unmask()
80 if (desc->pci.msi_attrib.is_msix) in __pci_msi_mask_desc()
88 if (desc->pci.msi_attrib.is_msix) in __pci_msi_unmask_desc()
95 * pci_msi_mask_irq - Generic IRQ chip callback to mask PCI/MSI interrupts
102 __pci_msi_mask_desc(desc, BIT(data->irq - desc->irq)); in pci_msi_mask_irq()
107 * pci_msi_unmask_irq - Generic IRQ chip callback to unmask PCI/MSI interrupts
114 __pci_msi_unmask_desc(desc, BIT(data->irq - desc->irq)); in pci_msi_unmask_irq()
122 BUG_ON(dev->current_state != PCI_D0); in __pci_read_msi_msg()
124 if (entry->pci.msi_attrib.is_msix) { in __pci_read_msi_msg()
127 if (WARN_ON_ONCE(entry->pci.msi_attrib.is_virtual)) in __pci_read_msi_msg()
130 msg->address_lo = readl(base + PCI_MSIX_ENTRY_LOWER_ADDR); in __pci_read_msi_msg()
131 msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR); in __pci_read_msi_msg()
132 msg->data = readl(base + PCI_MSIX_ENTRY_DATA); in __pci_read_msi_msg()
134 int pos = dev->msi_cap; in __pci_read_msi_msg()
138 &msg->address_lo); in __pci_read_msi_msg()
139 if (entry->pci.msi_attrib.is_64) { in __pci_read_msi_msg()
141 &msg->address_hi); in __pci_read_msi_msg()
144 msg->address_hi = 0; in __pci_read_msi_msg()
147 msg->data = data; in __pci_read_msi_msg()
155 if (dev->current_state != PCI_D0 || pci_dev_is_disconnected(dev)) { in __pci_write_msi_msg()
157 } else if (entry->pci.msi_attrib.is_msix) { in __pci_write_msi_msg()
159 u32 ctrl = entry->pci.msix_ctrl; in __pci_write_msi_msg()
162 if (entry->pci.msi_attrib.is_virtual) in __pci_write_msi_msg()
176 writel(msg->address_lo, base + PCI_MSIX_ENTRY_LOWER_ADDR); in __pci_write_msi_msg()
177 writel(msg->address_hi, base + PCI_MSIX_ENTRY_UPPER_ADDR); in __pci_write_msi_msg()
178 writel(msg->data, base + PCI_MSIX_ENTRY_DATA); in __pci_write_msi_msg()
186 int pos = dev->msi_cap; in __pci_write_msi_msg()
191 msgctl |= entry->pci.msi_attrib.multiple << 4; in __pci_write_msi_msg()
195 msg->address_lo); in __pci_write_msi_msg()
196 if (entry->pci.msi_attrib.is_64) { in __pci_write_msi_msg()
198 msg->address_hi); in __pci_write_msi_msg()
200 msg->data); in __pci_write_msi_msg()
203 msg->data); in __pci_write_msi_msg()
210 entry->msg = *msg; in __pci_write_msi_msg()
212 if (entry->write_msi_msg) in __pci_write_msi_msg()
213 entry->write_msi_msg(entry, entry->write_msi_msg_data); in __pci_write_msi_msg()
229 if (dev->msix_base) { in free_msi_irqs()
230 iounmap(dev->msix_base); in free_msi_irqs()
231 dev->msix_base = NULL; in free_msi_irqs()
237 if (!(dev->dev_flags & PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG)) in pci_intx_for_msi()
245 pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control); in pci_msi_set_enable()
249 pci_write_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, control); in pci_msi_set_enable()
253 * Architecture override returns true when the PCI MSI message should be
266 if (!dev->msi_enabled) in __pci_restore_msi_state()
269 entry = irq_get_msi_desc(dev->irq); in __pci_restore_msi_state()
274 __pci_write_msi_msg(entry, &entry->msg); in __pci_restore_msi_state()
276 pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control); in __pci_restore_msi_state()
279 control |= (entry->pci.msi_attrib.multiple << 4) | PCI_MSI_FLAGS_ENABLE; in __pci_restore_msi_state()
280 pci_write_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, control); in __pci_restore_msi_state()
287 pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &ctrl); in pci_msix_clear_and_set_ctrl()
290 pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, ctrl); in pci_msix_clear_and_set_ctrl()
298 if (!dev->msix_enabled) in __pci_restore_msix_state()
308 msi_lock_descs(&dev->dev); in __pci_restore_msix_state()
309 msi_for_each_desc(entry, &dev->dev, MSI_DESC_ALL) { in __pci_restore_msix_state()
311 __pci_write_msi_msg(entry, &entry->msg); in __pci_restore_msix_state()
312 pci_msix_write_vector_ctrl(entry, entry->pci.msix_ctrl); in __pci_restore_msix_state()
314 msi_unlock_descs(&dev->dev); in __pci_restore_msix_state()
330 dev->is_msi_managed = false; in pcim_msi_release()
336 * vs. msi_device_data_release() in the MSI core code.
342 if (!pci_is_managed(dev) || dev->is_msi_managed) in pcim_setup_msi_release()
345 ret = devm_add_action(&dev->dev, pcim_msi_release, dev); in pcim_setup_msi_release()
347 dev->is_msi_managed = true; in pcim_setup_msi_release()
352 * Ordering vs. devres: msi device data has to be installed first so that
357 int ret = msi_setup_device_data(&dev->dev); in pci_setup_msi_context()
370 /* MSI Entry Initialization */ in msi_setup_msi_desc()
373 pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control); in msi_setup_msi_desc()
375 if (dev->dev_flags & PCI_DEV_FLAGS_HAS_MSI_MASKING) in msi_setup_msi_desc()
384 desc.pci.msi_attrib.default_irq = dev->irq; in msi_setup_msi_desc()
390 desc.pci.mask_pos = dev->msi_cap + PCI_MSI_MASK_64; in msi_setup_msi_desc()
392 desc.pci.mask_pos = dev->msi_cap + PCI_MSI_MASK_32; in msi_setup_msi_desc()
398 return msi_add_msi_desc(&dev->dev, &desc); in msi_setup_msi_desc()
405 if (!dev->no_64bit_msi) in msi_verify_entries()
408 msi_for_each_desc(entry, &dev->dev, MSI_DESC_ALL) { in msi_verify_entries()
409 if (entry->msg.address_hi) { in msi_verify_entries()
410 pci_err(dev, "arch assigned 64-bit MSI address %#x%08x but device only supports 32 bits\n", in msi_verify_entries()
411 entry->msg.address_hi, entry->msg.address_lo); in msi_verify_entries()
415 return !entry ? 0 : -EIO; in msi_verify_entries()
419 * msi_capability_init - configure device's MSI capability structure
420 * @dev: pointer to the pci_dev data structure of MSI device function
424 * Setup the MSI capability structure of the device with the requested
426 * setup of an entry with the new MSI IRQ. A negative return value indicates
438 * Disable MSI during setup in the hardware, but mark it enabled in msi_capability_init()
442 dev->msi_enabled = 1; in msi_capability_init()
447 msi_lock_descs(&dev->dev); in msi_capability_init()
453 entry = msi_first_desc(&dev->dev, MSI_DESC_ALL); in msi_capability_init()
456 /* Configure MSI capability structure */ in msi_capability_init()
465 /* Set MSI enabled bits */ in msi_capability_init()
470 dev->irq = entry->irq; in msi_capability_init()
477 dev->msi_enabled = 0; in msi_capability_init()
479 msi_unlock_descs(&dev->dev); in msi_capability_init()
492 pci_read_config_dword(dev, dev->msix_cap + PCI_MSIX_TABLE, in msix_map_region()
519 desc.pci.msi_attrib.default_irq = dev->irq; in msix_setup_msi_descs()
534 ret = msi_add_msi_desc(&dev->dev, &desc); in msix_setup_msi_descs()
546 msi_for_each_desc(desc, &dev->dev, MSI_DESC_ALL) { in msix_update_entries()
547 entries->vector = desc->irq; in msix_update_entries()
575 msi_lock_descs(&dev->dev); in msix_setup_interrupts()
584 /* Check if all MSI entries honor device restrictions */ in msix_setup_interrupts()
595 msi_unlock_descs(&dev->dev); in msix_setup_interrupts()
601 * msix_capability_init - configure device's MSI-X capability
602 * @dev: pointer to the pci_dev data structure of MSI-X device function
607 * Setup the MSI-X capability structure of device function with a
608 * single MSI-X IRQ. A return of zero indicates the successful setup of
609 * requested MSI-X entries with allocated IRQs or non-zero for otherwise.
619 * Some devices require MSI-X to be enabled before the MSI-X in msix_capability_init()
627 dev->msix_enabled = 1; in msix_capability_init()
629 pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control); in msix_capability_init()
630 /* Request & Map MSI-X table region */ in msix_capability_init()
634 ret = -ENOMEM; in msix_capability_init()
638 dev->msix_base = base; in msix_capability_init()
652 * which takes the MSI-X mask bits into account even in msix_capability_init()
653 * when MSI-X is disabled, which prevents MSI delivery. in msix_capability_init()
662 dev->msix_enabled = 0; in msix_capability_init()
669 * pci_msi_supported - check whether MSI may be enabled on a device
670 * @dev: pointer to the pci_dev data structure of MSI device function
674 * to determine if MSI/-X are supported for the device. If MSI/-X is
681 /* MSI must be globally enabled and supported by the device */ in pci_msi_supported()
685 if (!dev || dev->no_msi) in pci_msi_supported()
697 * Any bridge which does NOT route MSI transactions from its in pci_msi_supported()
702 * - arch-specific PCI host bus controller drivers (deprecated) in pci_msi_supported()
703 * - quirks for specific PCI bridges in pci_msi_supported()
705 * or indirectly by platform-specific PCI host bridge drivers by in pci_msi_supported()
707 * the NO_MSI flag when no MSI domain is found for this bridge in pci_msi_supported()
710 for (bus = dev->bus; bus; bus = bus->parent) in pci_msi_supported()
711 if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI) in pci_msi_supported()
718 * pci_msi_vec_count - Return the number of MSI vectors a device can send
721 * This function returns the number of MSI vectors a device requested via
723 * device is not capable sending MSI interrupts. Otherwise, the call succeeds
725 * MSI specification.
732 if (!dev->msi_cap) in pci_msi_vec_count()
733 return -EINVAL; in pci_msi_vec_count()
735 pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &msgctl); in pci_msi_vec_count()
746 if (!pci_msi_enable || !dev || !dev->msi_enabled) in pci_msi_shutdown()
751 dev->msi_enabled = 0; in pci_msi_shutdown()
753 /* Return the device with MSI unmasked as initial states */ in pci_msi_shutdown()
754 desc = msi_first_desc(&dev->dev, MSI_DESC_ALL); in pci_msi_shutdown()
758 /* Restore dev->irq to its default pin-assertion IRQ */ in pci_msi_shutdown()
759 dev->irq = desc->pci.msi_attrib.default_irq; in pci_msi_shutdown()
765 if (!pci_msi_enable || !dev || !dev->msi_enabled) in pci_disable_msi()
768 msi_lock_descs(&dev->dev); in pci_disable_msi()
771 msi_unlock_descs(&dev->dev); in pci_disable_msi()
776 * pci_msix_vec_count - return the number of device's MSI-X table entries
777 * @dev: pointer to the pci_dev data structure of MSI-X device function
778 * This function returns the number of device's MSI-X table entries and
779 * therefore the number of MSI-X vectors device is capable of sending.
780 * It returns a negative errno if the device is not capable of sending MSI-X
787 if (!dev->msix_cap) in pci_msix_vec_count()
788 return -EINVAL; in pci_msix_vec_count()
790 pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control); in pci_msix_vec_count()
801 if (!pci_msi_supported(dev, nvec) || dev->current_state != PCI_D0) in __pci_enable_msix()
802 return -EINVAL; in __pci_enable_msix()
814 return -EINVAL; /* invalid entry */ in __pci_enable_msix()
817 return -EINVAL; /* duplicate entry */ in __pci_enable_msix()
822 /* Check whether driver already requested for MSI IRQ */ in __pci_enable_msix()
823 if (dev->msi_enabled) { in __pci_enable_msix()
824 pci_info(dev, "can't enable MSI-X (MSI IRQ already assigned)\n"); in __pci_enable_msix()
825 return -EINVAL; in __pci_enable_msix()
834 if (!pci_msi_enable || !dev || !dev->msix_enabled) in pci_msix_shutdown()
838 dev->msix_enabled = 0; in pci_msix_shutdown()
842 /* Return the device with MSI-X masked as initial states */ in pci_msix_shutdown()
843 msi_for_each_desc(desc, &dev->dev, MSI_DESC_ALL) in pci_msix_shutdown()
848 dev->msix_enabled = 0; in pci_msix_shutdown()
854 if (!pci_msi_enable || !dev || !dev->msix_enabled) in pci_disable_msix()
857 msi_lock_descs(&dev->dev); in pci_disable_msix()
860 msi_unlock_descs(&dev->dev); in pci_disable_msix()
870 if (!pci_msi_supported(dev, minvec) || dev->current_state != PCI_D0) in __pci_enable_msi_range()
871 return -EINVAL; in __pci_enable_msi_range()
873 /* Check whether driver already requested MSI-X IRQs */ in __pci_enable_msi_range()
874 if (dev->msix_enabled) { in __pci_enable_msi_range()
875 pci_info(dev, "can't enable MSI (MSI-X already enabled)\n"); in __pci_enable_msi_range()
876 return -EINVAL; in __pci_enable_msi_range()
880 return -ERANGE; in __pci_enable_msi_range()
882 if (WARN_ON_ONCE(dev->msi_enabled)) in __pci_enable_msi_range()
883 return -EINVAL; in __pci_enable_msi_range()
889 return -ENOSPC; in __pci_enable_msi_range()
902 return -ENOSPC; in __pci_enable_msi_range()
912 return -ENOSPC; in __pci_enable_msi_range()
936 return -ERANGE; in __pci_enable_msix_range()
938 if (WARN_ON_ONCE(dev->msix_enabled)) in __pci_enable_msix_range()
939 return -EINVAL; in __pci_enable_msix_range()
949 return -ENOSPC; in __pci_enable_msix_range()
959 return -ENOSPC; in __pci_enable_msix_range()
966 * pci_enable_msix_range - configure device's MSI-X capability structure
967 * @dev: pointer to the pci_dev data structure of MSI-X device function
968 * @entries: pointer to an array of MSI-X entries
969 * @minvec: minimum number of MSI-X IRQs requested
970 * @maxvec: maximum number of MSI-X IRQs requested
972 * Setup the MSI-X capability structure of device function with a maximum
974 * upon its software driver call to request for MSI-X mode enabled on its
977 * indicates the successful configuration of MSI-X capability structure
978 * with new allocated MSI-X interrupts.
988 * pci_alloc_irq_vectors_affinity - allocate multiple IRQs for a device
995 * Allocate up to @max_vecs interrupt vectors for @dev, using MSI-X or MSI
1000 * available for @dev the function will fail with -ENOSPC.
1010 int nvecs = -ENOSPC; in pci_alloc_irq_vectors_affinity()
1035 if (min_vecs == 1 && dev->irq) { in pci_alloc_irq_vectors_affinity()
1053 * pci_free_irq_vectors - free previously allocated IRQs for a device
1066 * pci_irq_vector - return Linux IRQ number of a device vector
1068 * @nr: Interrupt vector index (0-based)
1071 * MSI-X: The index in the MSI-X vector table
1072 * MSI: The index of the enabled MSI vectors
1075 * Return: The Linux interrupt number or -EINVAl if @nr is out of range.
1081 if (!dev->msi_enabled && !dev->msix_enabled) in pci_irq_vector()
1082 return !nr ? dev->irq : -EINVAL; in pci_irq_vector()
1084 irq = msi_get_virq(&dev->dev, nr); in pci_irq_vector()
1085 return irq ? irq : -EINVAL; in pci_irq_vector()
1090 * pci_irq_get_affinity - return the affinity of a particular MSI vector
1092 * @nr: device-relative interrupt vector index (0-based).
1095 * MSI-X: The index in the MSI-X vector table
1096 * MSI: The index of the enabled MSI vectors
1110 /* Non-MSI does not have the information handy */ in pci_irq_get_affinity()
1114 /* MSI[X] interrupts can be allocated without affinity descriptor */ in pci_irq_get_affinity()
1115 if (!desc->affinity) in pci_irq_get_affinity()
1119 * MSI has a mask array in the descriptor. in pci_irq_get_affinity()
1120 * MSI-X has a single mask. in pci_irq_get_affinity()
1122 idx = dev->msi_enabled ? nr : 0; in pci_irq_get_affinity()
1123 return &desc->affinity[idx].mask; in pci_irq_get_affinity()
1129 return to_pci_dev(desc->dev); in msi_desc_to_pci_dev()
1139 * pci_msi_enabled - is MSI enabled?
1141 * Returns true if MSI has not been disabled by the command-line option