• Home
  • Raw
  • Download

Lines Matching +full:pci +full:- +full:domain

1 // SPDX-License-Identifier: GPL-2.0
3 * Xen PCI Frontend
15 #include <linux/pci.h>
18 #include <asm/xen/pci.h>
27 #include <asm/xen/swiotlb-xen.h>
29 #define INVALID_EVTCHN (-1)
64 return sd->pdev; in pcifront_get_pdev()
68 unsigned int domain, unsigned int bus, in pcifront_init_sd() argument
72 sd->sd.node = first_online_node; in pcifront_init_sd()
73 sd->sd.domain = domain; in pcifront_init_sd()
74 sd->pdev = pdev; in pcifront_init_sd()
107 if (test_bit(_XEN_PCIB_active, (unsigned long *)&pdev->sh_info->flags) in schedule_pcifront_aer_op()
108 && !test_and_set_bit(_PDEVB_op_active, &pdev->flags)) { in schedule_pcifront_aer_op()
109 dev_dbg(&pdev->xdev->dev, "schedule aer frontend job\n"); in schedule_pcifront_aer_op()
110 schedule_work(&pdev->op_work); in schedule_pcifront_aer_op()
117 struct xen_pci_op *active_op = &pdev->sh_info->op; in do_pci_op()
119 evtchn_port_t port = pdev->evtchn; in do_pci_op()
120 unsigned irq = pdev->irq; in do_pci_op()
123 spin_lock_irqsave(&pdev->sh_info_lock, irq_flags); in do_pci_op()
129 set_bit(_XEN_PCIF_active, (unsigned long *)&pdev->sh_info->flags); in do_pci_op()
135 * (in the latter case we end up continually re-executing poll() with a in do_pci_op()
143 (unsigned long *)&pdev->sh_info->flags)) { in do_pci_op()
148 dev_err(&pdev->xdev->dev, in do_pci_op()
151 (unsigned long *)&pdev->sh_info->flags); in do_pci_op()
159 * reuse same evtchn with pci_conf backend response. So re-schedule in do_pci_op()
163 (unsigned long *)&pdev->sh_info->flags)) { in do_pci_op()
164 dev_err(&pdev->xdev->dev, in do_pci_op()
171 err = op->err; in do_pci_op()
173 spin_unlock_irqrestore(&pdev->sh_info_lock, irq_flags); in do_pci_op()
177 /* Access to this function is spinlocked in drivers/pci/access.c */
184 .domain = pci_domain_nr(bus), in pcifront_bus_read()
185 .bus = bus->number, in pcifront_bus_read()
190 struct pcifront_sd *sd = bus->sysdata; in pcifront_bus_read()
194 dev_info(&pdev->xdev->dev, in pcifront_bus_read()
195 "read dev=%04x:%02x:%02x.%d - offset %x size %d\n", in pcifront_bus_read()
196 pci_domain_nr(bus), bus->number, PCI_SLOT(devfn), in pcifront_bus_read()
203 dev_info(&pdev->xdev->dev, "read got back value %x\n", in pcifront_bus_read()
207 } else if (err == -ENODEV) { in pcifront_bus_read()
216 /* Access to this function is spinlocked in drivers/pci/access.c */
222 .domain = pci_domain_nr(bus), in pcifront_bus_write()
223 .bus = bus->number, in pcifront_bus_write()
229 struct pcifront_sd *sd = bus->sysdata; in pcifront_bus_write()
233 dev_info(&pdev->xdev->dev, in pcifront_bus_write()
234 "write dev=%04x:%02x:%02x.%d - " in pcifront_bus_write()
236 pci_domain_nr(bus), bus->number, in pcifront_bus_write()
255 .domain = pci_domain_nr(dev->bus), in pci_frontend_enable_msix()
256 .bus = dev->bus->number, in pci_frontend_enable_msix()
257 .devfn = dev->devfn, in pci_frontend_enable_msix()
260 struct pcifront_sd *sd = dev->bus->sysdata; in pci_frontend_enable_msix()
265 pci_err(dev, "too many vectors (0x%x) for PCI frontend:" in pci_frontend_enable_msix()
267 return -EINVAL; in pci_frontend_enable_msix()
272 op.msix_entries[i].entry = entry->msi_attrib.entry_nr; in pci_frontend_enable_msix()
274 op.msix_entries[i].vector = -1; in pci_frontend_enable_msix()
285 pci_warn(dev, "MSI-X entry %d is invalid: %d!\n", in pci_frontend_enable_msix()
287 err = -EINVAL; in pci_frontend_enable_msix()
288 vector[i] = -1; in pci_frontend_enable_msix()
309 .domain = pci_domain_nr(dev->bus), in pci_frontend_disable_msix()
310 .bus = dev->bus->number, in pci_frontend_disable_msix()
311 .devfn = dev->devfn, in pci_frontend_disable_msix()
313 struct pcifront_sd *sd = dev->bus->sysdata; in pci_frontend_disable_msix()
328 .domain = pci_domain_nr(dev->bus), in pci_frontend_enable_msi()
329 .bus = dev->bus->number, in pci_frontend_enable_msi()
330 .devfn = dev->devfn, in pci_frontend_enable_msi()
332 struct pcifront_sd *sd = dev->bus->sysdata; in pci_frontend_enable_msi()
341 err = -EINVAL; in pci_frontend_enable_msi()
342 vector[0] = -1; in pci_frontend_enable_msi()
345 pci_err(dev, "pci frontend enable msi failed for dev " in pci_frontend_enable_msi()
347 err = -EINVAL; in pci_frontend_enable_msi()
357 .domain = pci_domain_nr(dev->bus), in pci_frontend_disable_msi()
358 .bus = dev->bus->number, in pci_frontend_disable_msi()
359 .devfn = dev->devfn, in pci_frontend_disable_msi()
361 struct pcifront_sd *sd = dev->bus->sysdata; in pci_frontend_disable_msi()
393 /* Claim resources for the PCI frontend as-is, backend won't allow changes */
401 r = &dev->resource[i]; in pcifront_claim_resource()
403 if (!r->parent && r->start && r->flags) { in pcifront_claim_resource()
404 dev_info(&pdev->xdev->dev, "claiming resource %s/%d\n", in pcifront_claim_resource()
407 dev_err(&pdev->xdev->dev, "Could not claim resource %s/%d! " in pcifront_claim_resource()
418 unsigned int domain, unsigned int bus, in pcifront_scan_bus() argument
425 * We omit handling of PCI bridge attachment because pciback prevents in pcifront_scan_bus()
438 dev_info(&pdev->xdev->dev, "New device on " in pcifront_scan_bus()
439 "%04x:%02x:%02x.%d found.\n", domain, bus, in pcifront_scan_bus()
447 unsigned int domain, unsigned int bus) in pcifront_scan_root() argument
461 if (domain != 0) { in pcifront_scan_root()
462 dev_err(&pdev->xdev->dev, in pcifront_scan_root()
463 "PCI Root in non-zero PCI Domain! domain=%d\n", domain); in pcifront_scan_root()
464 dev_err(&pdev->xdev->dev, in pcifront_scan_root()
466 err = -EINVAL; in pcifront_scan_root()
471 dev_info(&pdev->xdev->dev, "Creating PCI Frontend Bus %04x:%02x\n", in pcifront_scan_root()
472 domain, bus); in pcifront_scan_root()
477 err = -ENOMEM; in pcifront_scan_root()
483 pcifront_init_sd(sd, domain, bus, pdev); in pcifront_scan_root()
487 b = pci_scan_root_bus(&pdev->xdev->dev, bus, in pcifront_scan_root()
490 dev_err(&pdev->xdev->dev, in pcifront_scan_root()
491 "Error creating PCI Frontend Bus!\n"); in pcifront_scan_root()
492 err = -ENOMEM; in pcifront_scan_root()
498 bus_entry->bus = b; in pcifront_scan_root()
500 list_add(&bus_entry->list, &pdev->root_buses); in pcifront_scan_root()
504 err = pcifront_scan_bus(pdev, domain, bus, b); in pcifront_scan_root()
523 unsigned int domain, unsigned int bus) in pcifront_rescan_root() argument
529 if (domain != 0) { in pcifront_rescan_root()
530 dev_err(&pdev->xdev->dev, in pcifront_rescan_root()
531 "PCI Root in non-zero PCI Domain! domain=%d\n", domain); in pcifront_rescan_root()
532 dev_err(&pdev->xdev->dev, in pcifront_rescan_root()
534 return -EINVAL; in pcifront_rescan_root()
538 dev_info(&pdev->xdev->dev, "Rescanning PCI Frontend Bus %04x:%02x\n", in pcifront_rescan_root()
539 domain, bus); in pcifront_rescan_root()
541 b = pci_find_bus(domain, bus); in pcifront_rescan_root()
544 return pcifront_scan_root(pdev, domain, bus); in pcifront_rescan_root()
546 err = pcifront_scan_bus(pdev, domain, bus, b); in pcifront_rescan_root()
561 while (!list_empty(&bus->devices)) { in free_root_bus_devs()
562 dev = container_of(bus->devices.next, struct pci_dev, in free_root_bus_devs()
573 dev_dbg(&pdev->xdev->dev, "cleaning up root buses\n"); in pcifront_free_roots()
576 list_for_each_entry_safe(bus_entry, t, &pdev->root_buses, list) { in pcifront_free_roots()
577 list_del(&bus_entry->list); in pcifront_free_roots()
579 free_root_bus_devs(bus_entry->bus); in pcifront_free_roots()
581 kfree(bus_entry->bus->sysdata); in pcifront_free_roots()
583 device_unregister(bus_entry->bus->bridge); in pcifront_free_roots()
584 pci_remove_bus(bus_entry->bus); in pcifront_free_roots()
597 int bus = pdev->sh_info->aer_op.bus; in pcifront_common_process()
598 int devfn = pdev->sh_info->aer_op.devfn; in pcifront_common_process()
599 int domain = pdev->sh_info->aer_op.domain; in pcifront_common_process() local
603 dev_dbg(&pdev->xdev->dev, in pcifront_common_process()
608 pcidev = pci_get_domain_bus_and_slot(domain, bus, devfn); in pcifront_common_process()
609 if (!pcidev || !pcidev->driver) { in pcifront_common_process()
610 dev_err(&pdev->xdev->dev, "device or AER driver is NULL\n"); in pcifront_common_process()
614 pdrv = pcidev->driver; in pcifront_common_process()
617 if (pdrv->err_handler && pdrv->err_handler->error_detected) { in pcifront_common_process()
623 result = pdrv->err_handler-> in pcifront_common_process()
627 result = pdrv->err_handler-> in pcifront_common_process()
631 result = pdrv->err_handler-> in pcifront_common_process()
635 pdrv->err_handler->resume(pcidev); in pcifront_common_process()
638 dev_err(&pdev->xdev->dev, in pcifront_common_process()
657 int cmd = pdev->sh_info->aer_op.cmd; in pcifront_do_aer()
659 (pci_channel_state_t)pdev->sh_info->aer_op.err; in pcifront_do_aer()
663 dev_dbg(&pdev->xdev->dev, in pcifront_do_aer()
665 pdev->sh_info->aer_op.bus, pdev->sh_info->aer_op.devfn); in pcifront_do_aer()
667 pdev->sh_info->aer_op.err = pcifront_common_process(cmd, pdev, state); in pcifront_do_aer()
671 clear_bit(_XEN_PCIB_active, (unsigned long *)&pdev->sh_info->flags); in pcifront_do_aer()
672 notify_remote_via_evtchn(pdev->evtchn); in pcifront_do_aer()
676 clear_bit(_PDEVB_op_active, &pdev->flags); in pcifront_do_aer()
696 dev_info(&pdev->xdev->dev, "Installing PCI frontend\n"); in pcifront_connect_and_init_dma()
699 err = -EEXIST; in pcifront_connect_and_init_dma()
706 dev_err(&pdev->xdev->dev, "Could not setup SWIOTLB!\n"); in pcifront_connect_and_init_dma()
716 dev_info(&pdev->xdev->dev, in pcifront_disconnect()
717 "Disconnecting PCI Frontend Buses\n"); in pcifront_disconnect()
731 pdev->sh_info = in alloc_pdev()
733 if (pdev->sh_info == NULL) { in alloc_pdev()
738 pdev->sh_info->flags = 0; in alloc_pdev()
741 set_bit(_XEN_PCIB_AERHANDLER, (void *)&pdev->sh_info->flags); in alloc_pdev()
743 dev_set_drvdata(&xdev->dev, pdev); in alloc_pdev()
744 pdev->xdev = xdev; in alloc_pdev()
746 INIT_LIST_HEAD(&pdev->root_buses); in alloc_pdev()
748 spin_lock_init(&pdev->sh_info_lock); in alloc_pdev()
750 pdev->evtchn = INVALID_EVTCHN; in alloc_pdev()
751 pdev->gnt_ref = INVALID_GRANT_REF; in alloc_pdev()
752 pdev->irq = -1; in alloc_pdev()
754 INIT_WORK(&pdev->op_work, pcifront_do_aer); in alloc_pdev()
756 dev_dbg(&xdev->dev, "Allocated pdev @ 0x%p pdev->sh_info @ 0x%p\n", in alloc_pdev()
757 pdev, pdev->sh_info); in alloc_pdev()
764 dev_dbg(&pdev->xdev->dev, "freeing pdev @ 0x%p\n", pdev); in free_pdev()
768 cancel_work_sync(&pdev->op_work); in free_pdev()
770 if (pdev->irq >= 0) in free_pdev()
771 unbind_from_irqhandler(pdev->irq, pdev); in free_pdev()
773 if (pdev->evtchn != INVALID_EVTCHN) in free_pdev()
774 xenbus_free_evtchn(pdev->xdev, pdev->evtchn); in free_pdev()
776 if (pdev->gnt_ref != INVALID_GRANT_REF) in free_pdev()
777 gnttab_end_foreign_access(pdev->gnt_ref, 0 /* r/w page */, in free_pdev()
778 (unsigned long)pdev->sh_info); in free_pdev()
780 free_page((unsigned long)pdev->sh_info); in free_pdev()
782 dev_set_drvdata(&pdev->xdev->dev, NULL); in free_pdev()
793 err = xenbus_grant_ring(pdev->xdev, pdev->sh_info, 1, &gref); in pcifront_publish_info()
797 pdev->gnt_ref = gref; in pcifront_publish_info()
799 err = xenbus_alloc_evtchn(pdev->xdev, &pdev->evtchn); in pcifront_publish_info()
803 err = bind_evtchn_to_irqhandler(pdev->evtchn, pcifront_handler_aer, in pcifront_publish_info()
809 pdev->irq = err; in pcifront_publish_info()
814 xenbus_dev_fatal(pdev->xdev, err, in pcifront_publish_info()
820 err = xenbus_printf(trans, pdev->xdev->nodename, in pcifront_publish_info()
821 "pci-op-ref", "%u", pdev->gnt_ref); in pcifront_publish_info()
823 err = xenbus_printf(trans, pdev->xdev->nodename, in pcifront_publish_info()
824 "event-channel", "%u", pdev->evtchn); in pcifront_publish_info()
826 err = xenbus_printf(trans, pdev->xdev->nodename, in pcifront_publish_info()
831 xenbus_dev_fatal(pdev->xdev, err, in pcifront_publish_info()
836 if (err == -EAGAIN) in pcifront_publish_info()
839 xenbus_dev_fatal(pdev->xdev, err, in pcifront_publish_info()
846 xenbus_switch_state(pdev->xdev, XenbusStateInitialised); in pcifront_publish_info()
848 dev_dbg(&pdev->xdev->dev, "publishing successful!\n"); in pcifront_publish_info()
856 int err = -EFAULT; in pcifront_try_connect()
859 unsigned int domain, bus; in pcifront_try_connect() local
863 if (xenbus_read_driver_state(pdev->xdev->nodename) != in pcifront_try_connect()
868 if (err && err != -EEXIST) { in pcifront_try_connect()
869 xenbus_dev_fatal(pdev->xdev, err, in pcifront_try_connect()
870 "Error setting up PCI Frontend"); in pcifront_try_connect()
874 err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, in pcifront_try_connect()
876 if (err == -ENOENT) { in pcifront_try_connect()
877 xenbus_dev_error(pdev->xdev, err, in pcifront_try_connect()
878 "No PCI Roots found, trying 0000:00"); in pcifront_try_connect()
881 xenbus_dev_fatal(pdev->xdev, err, in pcifront_try_connect()
882 "Error scanning PCI root 0000:00"); in pcifront_try_connect()
888 err = -EINVAL; in pcifront_try_connect()
889 xenbus_dev_fatal(pdev->xdev, err, in pcifront_try_connect()
890 "Error reading number of PCI roots"); in pcifront_try_connect()
895 len = snprintf(str, sizeof(str), "root-%d", i); in pcifront_try_connect()
896 if (unlikely(len >= (sizeof(str) - 1))) { in pcifront_try_connect()
897 err = -ENOMEM; in pcifront_try_connect()
901 err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, str, in pcifront_try_connect()
902 "%x:%x", &domain, &bus); in pcifront_try_connect()
905 err = -EINVAL; in pcifront_try_connect()
906 xenbus_dev_fatal(pdev->xdev, err, in pcifront_try_connect()
907 "Error reading PCI root %d", i); in pcifront_try_connect()
911 err = pcifront_scan_root(pdev, domain, bus); in pcifront_try_connect()
913 xenbus_dev_fatal(pdev->xdev, err, in pcifront_try_connect()
914 "Error scanning PCI root %04x:%02x", in pcifront_try_connect()
915 domain, bus); in pcifront_try_connect()
920 err = xenbus_switch_state(pdev->xdev, XenbusStateConnected); in pcifront_try_connect()
932 prev_state = xenbus_read_driver_state(pdev->xdev->nodename); in pcifront_try_disconnect()
942 err = xenbus_switch_state(pdev->xdev, XenbusStateClosed); in pcifront_try_disconnect()
951 int err = -EFAULT; in pcifront_attach_devices()
953 unsigned int domain, bus; in pcifront_attach_devices() local
956 if (xenbus_read_driver_state(pdev->xdev->nodename) != in pcifront_attach_devices()
960 err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, in pcifront_attach_devices()
962 if (err == -ENOENT) { in pcifront_attach_devices()
963 xenbus_dev_error(pdev->xdev, err, in pcifront_attach_devices()
964 "No PCI Roots found, trying 0000:00"); in pcifront_attach_devices()
967 xenbus_dev_fatal(pdev->xdev, err, in pcifront_attach_devices()
968 "Error scanning PCI root 0000:00"); in pcifront_attach_devices()
974 err = -EINVAL; in pcifront_attach_devices()
975 xenbus_dev_fatal(pdev->xdev, err, in pcifront_attach_devices()
976 "Error reading number of PCI roots"); in pcifront_attach_devices()
981 len = snprintf(str, sizeof(str), "root-%d", i); in pcifront_attach_devices()
982 if (unlikely(len >= (sizeof(str) - 1))) { in pcifront_attach_devices()
983 err = -ENOMEM; in pcifront_attach_devices()
987 err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, str, in pcifront_attach_devices()
988 "%x:%x", &domain, &bus); in pcifront_attach_devices()
991 err = -EINVAL; in pcifront_attach_devices()
992 xenbus_dev_fatal(pdev->xdev, err, in pcifront_attach_devices()
993 "Error reading PCI root %d", i); in pcifront_attach_devices()
997 err = pcifront_rescan_root(pdev, domain, bus); in pcifront_attach_devices()
999 xenbus_dev_fatal(pdev->xdev, err, in pcifront_attach_devices()
1000 "Error scanning PCI root %04x:%02x", in pcifront_attach_devices()
1001 domain, bus); in pcifront_attach_devices()
1006 xenbus_switch_state(pdev->xdev, XenbusStateConnected); in pcifront_attach_devices()
1016 unsigned int domain, bus, slot, func; in pcifront_detach_devices() local
1020 if (xenbus_read_driver_state(pdev->xdev->nodename) != in pcifront_detach_devices()
1024 err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, "num_devs", "%d", in pcifront_detach_devices()
1028 err = -EINVAL; in pcifront_detach_devices()
1029 xenbus_dev_fatal(pdev->xdev, err, in pcifront_detach_devices()
1030 "Error reading number of PCI devices"); in pcifront_detach_devices()
1037 l = snprintf(str, sizeof(str), "state-%d", i); in pcifront_detach_devices()
1038 if (unlikely(l >= (sizeof(str) - 1))) { in pcifront_detach_devices()
1039 err = -ENOMEM; in pcifront_detach_devices()
1042 state = xenbus_read_unsigned(pdev->xdev->otherend, str, in pcifront_detach_devices()
1049 l = snprintf(str, sizeof(str), "vdev-%d", i); in pcifront_detach_devices()
1050 if (unlikely(l >= (sizeof(str) - 1))) { in pcifront_detach_devices()
1051 err = -ENOMEM; in pcifront_detach_devices()
1054 err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, str, in pcifront_detach_devices()
1055 "%x:%x:%x.%x", &domain, &bus, &slot, &func); in pcifront_detach_devices()
1058 err = -EINVAL; in pcifront_detach_devices()
1059 xenbus_dev_fatal(pdev->xdev, err, in pcifront_detach_devices()
1060 "Error reading PCI device %d", i); in pcifront_detach_devices()
1064 pci_dev = pci_get_domain_bus_and_slot(domain, bus, in pcifront_detach_devices()
1067 dev_dbg(&pdev->xdev->dev, in pcifront_detach_devices()
1068 "Cannot get PCI device %04x:%02x:%02x.%d\n", in pcifront_detach_devices()
1069 domain, bus, slot, func); in pcifront_detach_devices()
1077 dev_dbg(&pdev->xdev->dev, in pcifront_detach_devices()
1078 "PCI device %04x:%02x:%02x.%d removed.\n", in pcifront_detach_devices()
1079 domain, bus, slot, func); in pcifront_detach_devices()
1082 err = xenbus_switch_state(pdev->xdev, XenbusStateReconfiguring); in pcifront_detach_devices()
1091 struct pcifront_device *pdev = dev_get_drvdata(&xdev->dev); in pcifront_backend_changed()
1105 if (xdev->state == XenbusStateClosed) in pcifront_backend_changed()
1107 /* Missed the backend's CLOSING state -- fallthrough */ in pcifront_backend_changed()
1109 dev_warn(&xdev->dev, "backend going away!\n"); in pcifront_backend_changed()
1130 err = -ENOMEM; in pcifront_xenbus_probe()
1146 struct pcifront_device *pdev = dev_get_drvdata(&xdev->dev); in pcifront_xenbus_remove()
1154 {"pci"},
1169 return -ENODEV; in pcifront_init()
1172 return -ENODEV; in pcifront_init()
1187 MODULE_DESCRIPTION("Xen PCI passthrough frontend.");
1189 MODULE_ALIAS("xen:pci");