summaryrefslogtreecommitdiffstats
path: root/sys/kern/subr_bus.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2009-12-30 19:44:31 +0000
committerjhb <jhb@FreeBSD.org>2009-12-30 19:44:31 +0000
commit8d2a9e1d3c36dbd1d69e79aeb5fa5ba9f0356de0 (patch)
tree9a9e36c4d1be756ef9395a508b60cb3099649490 /sys/kern/subr_bus.c
parent2bebf345f5dfc83efe15fc75fd989883f2f88db5 (diff)
downloadFreeBSD-src-8d2a9e1d3c36dbd1d69e79aeb5fa5ba9f0356de0.zip
FreeBSD-src-8d2a9e1d3c36dbd1d69e79aeb5fa5ba9f0356de0.tar.gz
- Assert that a reserved resource returned via resource_list_alloc() is not
active. - Fix bus_generic_rl_(alloc|release)_resource() to not attempt to fetch a resource list for grandchild devices, but just pass those requests up to the parent directly. This worked by accident previously, but it is better to not let bus drivers try to operate on devices they do not manage.
Diffstat (limited to 'sys/kern/subr_bus.c')
-rw-r--r--sys/kern/subr_bus.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
index 8c2db32..1689505 100644
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -2898,8 +2898,11 @@ resource_list_busy(struct resource_list *rl, int type, int rid)
rle = resource_list_find(rl, type, rid);
if (rle == NULL || rle->res == NULL)
return (0);
- if ((rle->flags & (RLE_RESERVED | RLE_ALLOCATED)) == RLE_RESERVED)
+ if ((rle->flags & (RLE_RESERVED | RLE_ALLOCATED)) == RLE_RESERVED) {
+ KASSERT(!(rman_get_flags(rle->res) & RF_ACTIVE),
+ ("reserved resource is active"));
return (0);
+ }
return (1);
}
@@ -3801,6 +3804,10 @@ bus_generic_rl_release_resource(device_t dev, device_t child, int type,
{
struct resource_list * rl = NULL;
+ if (device_get_parent(child) != dev)
+ return (BUS_RELEASE_RESOURCE(device_get_parent(dev), child,
+ type, rid, r));
+
rl = BUS_GET_RESOURCE_LIST(dev, child);
if (!rl)
return (EINVAL);
@@ -3821,6 +3828,10 @@ bus_generic_rl_alloc_resource(device_t dev, device_t child, int type,
{
struct resource_list * rl = NULL;
+ if (device_get_parent(child) != dev)
+ return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
+ type, rid, start, end, count, flags));
+
rl = BUS_GET_RESOURCE_LIST(dev, child);
if (!rl)
return (NULL);
OpenPOWER on IntegriCloud