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
This commit is contained in:
parent
728f2c6131
commit
1fb99e97e9
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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().
|
||||
*
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user