--- a/sys/bus/isa/x86_64/isa.c +++ b/sys/bus/isa/x86_64/isa.c @@ -84,10 +84,17 @@ */ int passthrough = (device_get_parent(child) != bus); int isdefault = (start == 0UL && end == ~0UL); - struct isa_device* idev = DEVTOISA(child); - struct resource_list *rl = &idev->id_resources; + /* + * The child's ivars are only a struct isa_device for direct + * children of this bus; a passthrough (grandchild) request must + * never cast them. The resource_list helpers do not touch rl + * on passthrough, so leave it NULL for that case. + */ + struct resource_list *rl = NULL; struct resource_list_entry *rle; + if (!passthrough) + rl = &DEVTOISA(child)->id_resources; if (!passthrough && !isdefault) { rle = resource_list_find(rl, type, *rid); if (!rle) { @@ -127,8 +134,13 @@ isa_release_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { - struct isa_device* idev = DEVTOISA(child); - struct resource_list *rl = &idev->id_resources; + /* ivars are a struct isa_device only for direct children */ + struct resource_list *rl; + + if (device_get_parent(child) == bus) + rl = &DEVTOISA(child)->id_resources; + else + rl = NULL; return resource_list_release(rl, bus, child, type, rid, r); }