Lines Matching +full:msi +full:- +full:x
1 // SPDX-License-Identifier: GPL-2.0
3 * PCI Backend Operations - respond to PCI requests from Frontend
37 if (dev->hdr_type != PCI_HEADER_TYPE_NORMAL) in xen_pcibk_control_isr()
41 dev_data->enable_intx = 0; in xen_pcibk_control_isr()
42 dev_data->ack_intr = 0; in xen_pcibk_control_isr()
44 enable = dev_data->enable_intx; in xen_pcibk_control_isr()
47 if (!enable && !dev_data->isr_on) in xen_pcibk_control_isr()
51 * b/c when device transitions to MSI, the dev->irq is in xen_pcibk_control_isr()
52 * overwritten with the MSI vector. in xen_pcibk_control_isr()
55 dev_data->irq = dev->irq; in xen_pcibk_control_isr()
58 * SR-IOV devices in all use MSI-X and have no legacy in xen_pcibk_control_isr()
61 if (dev_data->irq == 0) in xen_pcibk_control_isr()
64 dev_dbg(&dev->dev, "%s: #%d %s %s%s %s-> %s\n", in xen_pcibk_control_isr()
65 dev_data->irq_name, in xen_pcibk_control_isr()
66 dev_data->irq, in xen_pcibk_control_isr()
68 dev->msi_enabled ? "MSI" : "", in xen_pcibk_control_isr()
69 dev->msix_enabled ? "MSI/X" : "", in xen_pcibk_control_isr()
70 dev_data->isr_on ? "enable" : "disable", in xen_pcibk_control_isr()
75 * The MSI or MSI-X should not have an IRQ handler. Otherwise in xen_pcibk_control_isr()
78 if (dev->msi_enabled || dev->msix_enabled) in xen_pcibk_control_isr()
81 rc = request_irq(dev_data->irq, in xen_pcibk_control_isr()
83 dev_data->irq_name, dev); in xen_pcibk_control_isr()
85 dev_err(&dev->dev, "%s: failed to install fake IRQ " \ in xen_pcibk_control_isr()
87 dev_data->irq_name, dev_data->irq, rc); in xen_pcibk_control_isr()
91 free_irq(dev_data->irq, dev); in xen_pcibk_control_isr()
92 dev_data->irq = 0; in xen_pcibk_control_isr()
94 dev_data->isr_on = enable; in xen_pcibk_control_isr()
95 dev_data->ack_intr = enable; in xen_pcibk_control_isr()
97 dev_dbg(&dev->dev, "%s: #%d %s %s%s %s\n", in xen_pcibk_control_isr()
98 dev_data->irq_name, in xen_pcibk_control_isr()
99 dev_data->irq, in xen_pcibk_control_isr()
101 dev->msi_enabled ? "MSI" : "", in xen_pcibk_control_isr()
102 dev->msix_enabled ? "MSI/X" : "", in xen_pcibk_control_isr()
103 enable ? (dev_data->isr_on ? "enabled" : "failed to enable") : in xen_pcibk_control_isr()
104 (dev_data->isr_on ? "failed to disable" : "disabled")); in xen_pcibk_control_isr()
109 * ready to be re-exported)
118 if (dev->hdr_type == PCI_HEADER_TYPE_NORMAL) { in xen_pcibk_reset_device()
121 * disabling MSI/MSI-X interrupts.*/ in xen_pcibk_reset_device()
122 if (dev->msix_enabled) in xen_pcibk_reset_device()
124 if (dev->msi_enabled) in xen_pcibk_reset_device()
130 dev->is_busmaster = 0; in xen_pcibk_reset_device()
137 dev->is_busmaster = 0; in xen_pcibk_reset_device()
151 printk(KERN_DEBUG DRV_NAME ": %s: enable MSI\n", pci_name(dev)); in xen_pcibk_enable_msi()
153 if (dev->msi_enabled) in xen_pcibk_enable_msi()
154 status = -EALREADY; in xen_pcibk_enable_msi()
155 else if (dev->msix_enabled) in xen_pcibk_enable_msi()
156 status = -ENXIO; in xen_pcibk_enable_msi()
161 pr_warn_ratelimited("%s: error enabling MSI for guest %u: err %d\n", in xen_pcibk_enable_msi()
162 pci_name(dev), pdev->xdev->otherend_id, in xen_pcibk_enable_msi()
164 op->value = 0; in xen_pcibk_enable_msi()
171 op->value = dev->irq ? xen_pirq_from_irq(dev->irq) : 0; in xen_pcibk_enable_msi()
173 printk(KERN_DEBUG DRV_NAME ": %s: MSI: %d\n", pci_name(dev), in xen_pcibk_enable_msi()
174 op->value); in xen_pcibk_enable_msi()
178 dev_data->ack_intr = 0; in xen_pcibk_enable_msi()
188 printk(KERN_DEBUG DRV_NAME ": %s: disable MSI\n", in xen_pcibk_disable_msi()
191 if (dev->msi_enabled) { in xen_pcibk_disable_msi()
198 dev_data->ack_intr = 1; in xen_pcibk_disable_msi()
200 op->value = dev->irq ? xen_pirq_from_irq(dev->irq) : 0; in xen_pcibk_disable_msi()
202 printk(KERN_DEBUG DRV_NAME ": %s: MSI: %d\n", pci_name(dev), in xen_pcibk_disable_msi()
203 op->value); in xen_pcibk_disable_msi()
217 printk(KERN_DEBUG DRV_NAME ": %s: enable MSI-X\n", in xen_pcibk_enable_msix()
220 if (op->value > SH_INFO_MAX_VEC) in xen_pcibk_enable_msix()
221 return -EINVAL; in xen_pcibk_enable_msix()
223 if (dev->msix_enabled) in xen_pcibk_enable_msix()
224 return -EALREADY; in xen_pcibk_enable_msix()
228 * to access the BARs where the MSI-X entries reside. in xen_pcibk_enable_msix()
232 if (dev->msi_enabled || !(cmd & PCI_COMMAND_MEMORY)) in xen_pcibk_enable_msix()
233 return -ENXIO; in xen_pcibk_enable_msix()
235 entries = kmalloc_array(op->value, sizeof(*entries), GFP_KERNEL); in xen_pcibk_enable_msix()
237 return -ENOMEM; in xen_pcibk_enable_msix()
239 for (i = 0; i < op->value; i++) { in xen_pcibk_enable_msix()
240 entries[i].entry = op->msix_entries[i].entry; in xen_pcibk_enable_msix()
241 entries[i].vector = op->msix_entries[i].vector; in xen_pcibk_enable_msix()
244 result = pci_enable_msix_exact(dev, entries, op->value); in xen_pcibk_enable_msix()
246 for (i = 0; i < op->value; i++) { in xen_pcibk_enable_msix()
247 op->msix_entries[i].entry = entries[i].entry; in xen_pcibk_enable_msix()
249 op->msix_entries[i].vector = in xen_pcibk_enable_msix()
253 "MSI-X[%d]: %d\n", in xen_pcibk_enable_msix()
255 op->msix_entries[i].vector); in xen_pcibk_enable_msix()
259 pr_warn_ratelimited("%s: error enabling MSI-X for guest %u: err %d!\n", in xen_pcibk_enable_msix()
260 pci_name(dev), pdev->xdev->otherend_id, in xen_pcibk_enable_msix()
264 op->value = result; in xen_pcibk_enable_msix()
267 dev_data->ack_intr = 0; in xen_pcibk_enable_msix()
277 printk(KERN_DEBUG DRV_NAME ": %s: disable MSI-X\n", in xen_pcibk_disable_msix()
280 if (dev->msix_enabled) { in xen_pcibk_disable_msix()
287 dev_data->ack_intr = 1; in xen_pcibk_disable_msix()
290 * SR-IOV devices (which don't have any legacy IRQ) have in xen_pcibk_disable_msix()
293 op->value = dev->irq ? xen_pirq_from_irq(dev->irq) : 0; in xen_pcibk_disable_msix()
295 printk(KERN_DEBUG DRV_NAME ": %s: MSI-X: %d\n", in xen_pcibk_disable_msix()
296 pci_name(dev), op->value); in xen_pcibk_disable_msix()
304 (unsigned long *)&pdev->sh_info->flags) && in xen_pcibk_test_op_pending()
305 !test_and_set_bit(_PDEVF_op_active, &pdev->flags); in xen_pcibk_test_op_pending()
321 schedule_work(&pdev->op_work); in xen_pcibk_test_and_schedule_op()
326 if (!test_bit(_XEN_PCIB_active, (unsigned long *)&pdev->sh_info->flags) in xen_pcibk_test_and_schedule_op()
327 && test_bit(_PCIB_op_pending, &pdev->flags)) { in xen_pcibk_test_and_schedule_op()
346 struct xen_pci_op *op = &pdev->op; in xen_pcibk_do_one_op()
352 *op = pdev->sh_info->op; in xen_pcibk_do_one_op()
354 dev = xen_pcibk_get_pci_dev(pdev, op->domain, op->bus, op->devfn); in xen_pcibk_do_one_op()
357 op->err = XEN_PCI_ERR_dev_not_found; in xen_pcibk_do_one_op()
361 test_intx = dev_data->enable_intx; in xen_pcibk_do_one_op()
362 switch (op->cmd) { in xen_pcibk_do_one_op()
364 op->err = xen_pcibk_config_read(dev, in xen_pcibk_do_one_op()
365 op->offset, op->size, &op->value); in xen_pcibk_do_one_op()
368 op->err = xen_pcibk_config_write(dev, in xen_pcibk_do_one_op()
369 op->offset, op->size, op->value); in xen_pcibk_do_one_op()
373 op->err = xen_pcibk_enable_msi(pdev, dev, op); in xen_pcibk_do_one_op()
376 op->err = xen_pcibk_disable_msi(pdev, dev, op); in xen_pcibk_do_one_op()
379 nr = op->value; in xen_pcibk_do_one_op()
380 op->err = xen_pcibk_enable_msix(pdev, dev, op); in xen_pcibk_do_one_op()
383 op->err = xen_pcibk_disable_msix(pdev, dev, op); in xen_pcibk_do_one_op()
387 op->err = XEN_PCI_ERR_not_implemented; in xen_pcibk_do_one_op()
391 if (!op->err && dev && dev_data) { in xen_pcibk_do_one_op()
393 if ((dev_data->enable_intx != test_intx)) in xen_pcibk_do_one_op()
396 pdev->sh_info->op.err = op->err; in xen_pcibk_do_one_op()
397 pdev->sh_info->op.value = op->value; in xen_pcibk_do_one_op()
399 if (op->cmd == XEN_PCI_OP_enable_msix && op->err == 0) { in xen_pcibk_do_one_op()
403 pdev->sh_info->op.msix_entries[i].vector = in xen_pcibk_do_one_op()
404 op->msix_entries[i].vector; in xen_pcibk_do_one_op()
409 clear_bit(_XEN_PCIF_active, (unsigned long *)&pdev->sh_info->flags); in xen_pcibk_do_one_op()
410 notify_remote_via_irq(pdev->evtchn_irq); in xen_pcibk_do_one_op()
414 clear_bit(_PDEVF_op_active, &pdev->flags); in xen_pcibk_do_one_op()
435 /* IRQs might come in before pdev->evtchn_irq is written. */ in xen_pcibk_handle_event()
436 if (unlikely(pdev->evtchn_irq != irq)) in xen_pcibk_handle_event()
437 pdev->evtchn_irq = irq; in xen_pcibk_handle_event()
439 eoi = test_and_set_bit(_EOI_pending, &pdev->flags); in xen_pcibk_handle_event()
451 if (dev_data->isr_on && dev_data->ack_intr) { in xen_pcibk_guest_interrupt()
452 dev_data->handled++; in xen_pcibk_guest_interrupt()
453 if ((dev_data->handled % 1000) == 0) { in xen_pcibk_guest_interrupt()
457 dev_data->irq_name); in xen_pcibk_guest_interrupt()
458 dev_data->ack_intr = 0; in xen_pcibk_guest_interrupt()