Date: Mon, 15 Nov 2021 18:02:56 GMT From: Mark Johnston <markj@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 1fb99e97e959 - main - bus: Make BUS_TRANSLATE_RESOURCE behave more like other bus methods Message-ID: <202111151802.1AFI2uU2027253@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=1fb99e97e959a51306fd216a41977079d4689665 commit 1fb99e97e959a51306fd216a41977079d4689665 Author: Mark Johnston <markj@FreeBSD.org> AuthorDate: 2021-11-15 16:29:49 +0000 Commit: Mark Johnston <markj@FreeBSD.org> CommitDate: 2021-11-15 18:01:30 +0000 bus: Make BUS_TRANSLATE_RESOURCE behave more like other bus methods - Return an errno value upon failure, instead of 1. - Provide a bus_translate_resource() wrapper. - Implement the generic version, which traverses the hierarchy until a bus driver with a non-trivial implementation is found, in subr_bus.c like other similar default implementations. - Make ofw_pcib_translate_resource() return an error if a matching PCI address range is not found. - Make generic_pcie_translate_resource_common() return an int instead of a bool. Fix up callers. No functional change intended. Reviewed by: imp, jhb MFC after: 2 weeks Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D32855 --- sys/compat/linuxkpi/common/src/linux_pci.c | 9 +++++--- sys/dev/ofw/ofw_pcib.c | 6 +++--- sys/dev/pci/pci_host_generic.c | 19 +++++++++-------- sys/dev/pci/pci_user.c | 2 +- sys/kern/bus_if.m | 18 ++++------------ sys/kern/subr_bus.c | 33 ++++++++++++++++++++++++++++++ sys/sys/bus.h | 2 ++ 7 files changed, 60 insertions(+), 29 deletions(-) diff --git a/sys/compat/linuxkpi/common/src/linux_pci.c b/sys/compat/linuxkpi/common/src/linux_pci.c index db94bc08239e..8ec6a5af2140 100644 --- a/sys/compat/linuxkpi/common/src/linux_pci.c +++ b/sys/compat/linuxkpi/common/src/linux_pci.c @@ -690,14 +690,17 @@ pci_resource_start(struct pci_dev *pdev, int bar) struct resource_list_entry *rle; rman_res_t newstart; device_t dev; + int error; if ((rle = linux_pci_get_bar(pdev, bar, true)) == NULL) return (0); dev = pdev->pdrv != NULL && pdev->pdrv->isdrm ? device_get_parent(pdev->dev.bsddev) : pdev->dev.bsddev; - if (BUS_TRANSLATE_RESOURCE(dev, rle->type, rle->start, &newstart)) { - device_printf(pdev->dev.bsddev, "translate of %#jx failed\n", - (uintmax_t)rle->start); + error = bus_translate_resource(dev, rle->type, rle->start, &newstart); + if (error != 0) { + device_printf(pdev->dev.bsddev, + "translate of %#jx failed: %d\n", + (uintmax_t)rle->start, error); return (0); } return (newstart); diff --git a/sys/dev/ofw/ofw_pcib.c b/sys/dev/ofw/ofw_pcib.c index 1de5a884ebc9..b10feffedf6c 100644 --- a/sys/dev/ofw/ofw_pcib.c +++ b/sys/dev/ofw/ofw_pcib.c @@ -511,11 +511,11 @@ ofw_pcib_translate_resource(device_t bus, int type, rman_res_t start, if (type == space) { start += (rp->host - rp->pci); - break; + *newstart = start; + return (0); } } - *newstart = start; - return (0); + return (ENOENT); } static int diff --git a/sys/dev/pci/pci_host_generic.c b/sys/dev/pci/pci_host_generic.c index 4d7d9f314dce..e1a0a48bad3a 100644 --- a/sys/dev/pci/pci_host_generic.c +++ b/sys/dev/pci/pci_host_generic.c @@ -331,7 +331,7 @@ pci_host_generic_core_release_resource(device_t dev, device_t child, int type, return (bus_generic_release_resource(dev, child, type, rid, res)); } -static bool +static int generic_pcie_translate_resource_common(device_t dev, int type, rman_res_t start, rman_res_t end, rman_res_t *new_start, rman_res_t *new_end) { @@ -385,7 +385,7 @@ generic_pcie_translate_resource_common(device_t dev, int type, rman_res_t start, break; } - return (found); + return (found ? 0 : ENOENT); } static int @@ -394,7 +394,7 @@ generic_pcie_translate_resource(device_t bus, int type, { rman_res_t newend; /* unused */ - return (!generic_pcie_translate_resource_common( + return (generic_pcie_translate_resource_common( bus, type, start, 0, newstart, &newend)); } @@ -422,8 +422,8 @@ pci_host_generic_core_alloc_resource(device_t dev, device_t child, int type, type, rid, start, end, count, flags)); /* Translate the address from a PCI address to a physical address */ - if (!generic_pcie_translate_resource_common(dev, type, start, end, &phys_start, - &phys_end)) { + if (generic_pcie_translate_resource_common(dev, type, start, end, + &phys_start, &phys_end) != 0) { device_printf(dev, "Failed to translate resource %jx-%jx type %x for %s\n", (uintmax_t)start, (uintmax_t)end, type, @@ -474,9 +474,12 @@ generic_pcie_activate_resource(device_t dev, device_t child, int type, start = rman_get_start(r); end = rman_get_end(r); - if (!generic_pcie_translate_resource_common(dev, type, start, end, &start, - &end)) - return (EINVAL); + res = generic_pcie_translate_resource_common(dev, type, start, end, + &start, &end); + if (res != 0) { + rman_deactivate_resource(r); + return (res); + } rman_set_start(r, start); rman_set_end(r, end); diff --git a/sys/dev/pci/pci_user.c b/sys/dev/pci/pci_user.c index 7ebd9b66138c..ce63122128c5 100644 --- a/sys/dev/pci/pci_user.c +++ b/sys/dev/pci/pci_user.c @@ -877,7 +877,7 @@ pci_bar_mmap(device_t pcidev, struct pci_bar_mmap *pbm) return (EBUSY); /* XXXKIB enable if _ACTIVATE */ if (!PCI_BAR_MEM(pm->pm_value)) return (EIO); - error = BUS_TRANSLATE_RESOURCE(pcidev, SYS_RES_MEMORY, + error = bus_translate_resource(pcidev, SYS_RES_MEMORY, pm->pm_value & PCIM_BAR_MEM_BASE, &membase); if (error != 0) return (error); diff --git a/sys/kern/bus_if.m b/sys/kern/bus_if.m index 0bd7056019ab..0f673c983d08 100644 --- a/sys/kern/bus_if.m +++ b/sys/kern/bus_if.m @@ -77,18 +77,6 @@ CODE { return (0); } - static int - null_translate_resource(device_t bus, int type, rman_res_t start, - rman_res_t *newstart) - { - if (device_get_parent(bus) != NULL) - return (BUS_TRANSLATE_RESOURCE(device_get_parent(bus), - type, start, newstart)); - - *newstart = start; - return (0); - } - static ssize_t null_get_property(device_t dev, device_t child, const char *propname, void *propvalue, size_t size) @@ -425,10 +413,12 @@ METHOD int adjust_resource { rman_res_t _end; }; - /** * @brief translate a resource value * + * Give a bus driver the opportunity to translate resource ranges. If + * successful, the host's view of the resource starting at @p _start is + * returned in @p _newstart, otherwise an error is returned. * * @param _dev the device associated with the resource * @param _type the type of resource @@ -440,7 +430,7 @@ METHOD int translate_resource { int _type; rman_res_t _start; rman_res_t *_newstart; -} DEFAULT null_translate_resource; +} DEFAULT bus_generic_translate_resource; /** * @brief Release a resource diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c index cdbaee9c203e..09072e1a23de 100644 --- a/sys/kern/subr_bus.c +++ b/sys/kern/subr_bus.c @@ -4242,6 +4242,24 @@ bus_generic_adjust_resource(device_t dev, device_t child, int type, return (EINVAL); } +/* + * @brief Helper function for implementing BUS_TRANSLATE_RESOURCE(). + * + * This simple implementation of BUS_TRANSLATE_RESOURCE() simply calls the + * BUS_TRANSLATE_RESOURCE() method of the parent of @p dev. If there is no + * parent, no translation happens. + */ +int +bus_generic_translate_resource(device_t dev, int type, rman_res_t start, + rman_res_t *newstart) +{ + if (dev->parent) + return (BUS_TRANSLATE_RESOURCE(dev->parent, type, start, + newstart)); + *newstart = start; + return (0); +} + /** * @brief Helper function for implementing BUS_ALLOC_RESOURCE(). * @@ -4672,6 +4690,21 @@ bus_adjust_resource(device_t dev, int type, struct resource *r, rman_res_t start return (BUS_ADJUST_RESOURCE(dev->parent, dev, type, r, start, end)); } +/** + * @brief Wrapper function for BUS_TRANSLATE_RESOURCE(). + * + * This function simply calls the BUS_TRANSLATE_RESOURCE() method of the + * parent of @p dev. + */ +int +bus_translate_resource(device_t dev, int type, rman_res_t start, + rman_res_t *newstart) +{ + if (dev->parent == NULL) + return (EINVAL); + return (BUS_TRANSLATE_RESOURCE(dev->parent, type, start, newstart)); +} + /** * @brief Wrapper function for BUS_ACTIVATE_RESOURCE(). * diff --git a/sys/sys/bus.h b/sys/sys/bus.h index 8544aa32cff8..0942b7246ae4 100644 --- a/sys/sys/bus.h +++ b/sys/sys/bus.h @@ -515,6 +515,8 @@ void bus_release_resources(device_t dev, const struct resource_spec *rs, int bus_adjust_resource(device_t child, int type, struct resource *r, rman_res_t start, rman_res_t end); +int bus_translate_resource(device_t child, int type, rman_res_t start, + rman_res_t *newstart); struct resource *bus_alloc_resource(device_t dev, int type, int *rid, rman_res_t start, rman_res_t end, rman_res_t count, u_int flags);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202111151802.1AFI2uU2027253>