Lines Matching +full:pci +full:- +full:ep

1 // SPDX-License-Identifier: GPL-2.0
6 * para-virtual IOMMUs and the endpoints they manage. The OS uses it to
16 * hasn't yet been initialized, VIOT returns -EPROBE_DEFER to postpone probing
25 #include <linux/pci.h>
37 /* PCI range */
62 max_t(size_t, sizeof(*viot), viot->node_offset)); in viot_check_bounds()
63 end = ACPI_ADD_PTR(struct acpi_viot_header, viot, viot->header.length); in viot_check_bounds()
68 return -EOVERFLOW; in viot_check_bounds()
70 if (hdr->length < sizeof(*hdr)) { in viot_check_bounds()
72 return -EINVAL; in viot_check_bounds()
86 pr_err("Could not find PCI IOMMU\n"); in viot_get_pci_iommu_fwnode()
87 return -ENODEV; in viot_get_pci_iommu_fwnode()
90 fwnode = dev_fwnode(&pdev->dev); in viot_get_pci_iommu_fwnode()
93 * PCI devices aren't necessarily described by ACPI. Create a in viot_get_pci_iommu_fwnode()
99 return -ENOMEM; in viot_get_pci_iommu_fwnode()
101 set_primary_fwnode(&pdev->dev, fwnode); in viot_get_pci_iommu_fwnode()
103 viommu->fwnode = dev_fwnode(&pdev->dev); in viot_get_pci_iommu_fwnode()
121 return -EINVAL; in viot_get_mmio_iommu_fwnode()
123 viommu->fwnode = &adev->fwnode; in viot_get_mmio_iommu_fwnode()
134 struct acpi_viot_virtio_iommu_pci pci; in viot_get_iommu() member
139 if (viommu->offset == offset) in viot_get_iommu()
149 viommu->offset = offset; in viot_get_iommu()
150 switch (hdr->type) { in viot_get_iommu()
152 if (hdr->length < sizeof(node->pci)) in viot_get_iommu()
155 ret = viot_get_pci_iommu_fwnode(viommu, node->pci.segment, in viot_get_iommu()
156 node->pci.bdf); in viot_get_iommu()
159 if (hdr->length < sizeof(node->mmio)) in viot_get_iommu()
163 node->mmio.base_address); in viot_get_iommu()
166 ret = -EINVAL; in viot_get_iommu()
171 list_add(&viommu->list, &viot_iommus); in viot_get_iommu()
181 int ret = -EINVAL; in viot_parse_node()
183 struct viot_endpoint *ep; in viot_parse_node() local
186 struct acpi_viot_pci_range pci; in viot_parse_node() member
190 return -EINVAL; in viot_parse_node()
192 if (hdr->type == ACPI_VIOT_NODE_VIRTIO_IOMMU_PCI || in viot_parse_node()
193 hdr->type == ACPI_VIOT_NODE_VIRTIO_IOMMU_MMIO) in viot_parse_node()
196 ep = kzalloc(sizeof(*ep), GFP_KERNEL); in viot_parse_node()
197 if (!ep) in viot_parse_node()
198 return -ENOMEM; in viot_parse_node()
200 switch (hdr->type) { in viot_parse_node()
202 if (hdr->length < sizeof(node->pci)) { in viot_parse_node()
203 pr_err(FW_BUG "Invalid PCI node size\n"); in viot_parse_node()
207 ep->segment_start = node->pci.segment_start; in viot_parse_node()
208 ep->segment_end = node->pci.segment_end; in viot_parse_node()
209 ep->bdf_start = node->pci.bdf_start; in viot_parse_node()
210 ep->bdf_end = node->pci.bdf_end; in viot_parse_node()
211 ep->endpoint_id = node->pci.endpoint_start; in viot_parse_node()
212 ep->viommu = viot_get_iommu(node->pci.output_node); in viot_parse_node()
216 if (hdr->length < sizeof(node->mmio)) { in viot_parse_node()
221 ep->address = node->mmio.base_address; in viot_parse_node()
222 ep->endpoint_id = node->mmio.endpoint; in viot_parse_node()
223 ep->viommu = viot_get_iommu(node->mmio.output_node); in viot_parse_node()
227 pr_warn("Unsupported node %x\n", hdr->type); in viot_parse_node()
232 if (!ep->viommu) { in viot_parse_node()
242 list_add(&ep->list, list); in viot_parse_node()
246 kfree(ep); in viot_parse_node()
251 * acpi_viot_early_init - Test the presence of VIOT and enable ACS
271 * acpi_viot_init - Parse the VIOT table
295 node = ACPI_ADD_PTR(struct acpi_viot_header, viot, viot->node_offset); in acpi_viot_init()
296 for (i = 0; i < viot->node_count; i++) { in acpi_viot_init()
301 node->length); in acpi_viot_init()
311 return -ENODEV; in viot_dev_iommu_init()
314 if (device_match_fwnode(dev, viommu->fwnode)) in viot_dev_iommu_init()
315 return -EINVAL; in viot_dev_iommu_init()
317 return acpi_iommu_fwspec_init(dev, epid, viommu->fwnode); in viot_dev_iommu_init()
323 struct viot_endpoint *ep; in viot_pci_dev_iommu_init() local
325 u32 domain_nr = pci_domain_nr(pdev->bus); in viot_pci_dev_iommu_init()
327 list_for_each_entry(ep, &viot_pci_ranges, list) { in viot_pci_dev_iommu_init()
328 if (domain_nr >= ep->segment_start && in viot_pci_dev_iommu_init()
329 domain_nr <= ep->segment_end && in viot_pci_dev_iommu_init()
330 dev_id >= ep->bdf_start && in viot_pci_dev_iommu_init()
331 dev_id <= ep->bdf_end) { in viot_pci_dev_iommu_init()
332 epid = ((domain_nr - ep->segment_start) << 16) + in viot_pci_dev_iommu_init()
333 dev_id - ep->bdf_start + ep->endpoint_id; in viot_pci_dev_iommu_init()
335 return viot_dev_iommu_init(aliased_dev, ep->viommu, in viot_pci_dev_iommu_init()
339 return -ENODEV; in viot_pci_dev_iommu_init()
345 struct viot_endpoint *ep; in viot_mmio_dev_iommu_init() local
349 return -ENODEV; in viot_mmio_dev_iommu_init()
351 list_for_each_entry(ep, &viot_mmio_endpoints, list) { in viot_mmio_dev_iommu_init()
352 if (ep->address == mem->start) in viot_mmio_dev_iommu_init()
353 return viot_dev_iommu_init(&pdev->dev, ep->viommu, in viot_mmio_dev_iommu_init()
354 ep->endpoint_id); in viot_mmio_dev_iommu_init()
356 return -ENODEV; in viot_mmio_dev_iommu_init()
360 * viot_iommu_configure - Setup IOMMU ops for an endpoint described by VIOT
372 return -ENODEV; in viot_iommu_configure()