diff options
author | ian <ian@FreeBSD.org> | 2014-01-24 00:42:18 +0000 |
---|---|---|
committer | ian <ian@FreeBSD.org> | 2014-01-24 00:42:18 +0000 |
commit | 11813eb2829e7f51e3faa7b308edd62f95237d7b (patch) | |
tree | b34686c2165d624a9d80cca7d8ab455654af3469 | |
parent | 5979ccd151f2146f8c87768ed1811960db6288e1 (diff) | |
download | FreeBSD-src-11813eb2829e7f51e3faa7b308edd62f95237d7b.zip FreeBSD-src-11813eb2829e7f51e3faa7b308edd62f95237d7b.tar.gz |
Be more robust with malformed interrupt config data. Instead of crashing
or going into a near-infinite loop, warn and make potentially-reasonable
assumptions.
Reviewed by: brooks, nwhitehorn
-rw-r--r-- | sys/dev/fdt/fdt_common.c | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/sys/dev/fdt/fdt_common.c b/sys/dev/fdt/fdt_common.c index 9d6840c..b4aabbd 100644 --- a/sys/dev/fdt/fdt_common.c +++ b/sys/dev/fdt/fdt_common.c @@ -483,11 +483,23 @@ fdt_intr_to_rl(device_t dev, phandle_t node, struct resource_list *rl, nintr = OF_getencprop_alloc(node, "interrupts", sizeof(*intr), (void **)&intr); if (nintr > 0) { - iparent = 0; - OF_searchencprop(node, "interrupt-parent", &iparent, - sizeof(iparent)); - OF_searchencprop(OF_xref_phandle(iparent), "#interrupt-cells", - &icells, sizeof(icells)); + if (OF_searchencprop(node, "interrupt-parent", &iparent, + sizeof(iparent)) == -1) { + device_printf(dev, "No interrupt-parent found, " + "assuming direct parent\n"); + iparent = OF_parent(node); + } + if (OF_searchencprop(OF_xref_phandle(iparent), + "#interrupt-cells", &icells, sizeof(icells)) == -1) { + device_printf(dev, "Missing #interrupt-cells property, " + "assuming <1>\n"); + icells = 1; + } + if (icells < 1 || icells > nintr) { + device_printf(dev, "Invalid #interrupt-cells property " + "value <%d>, assuming <1>\n", icells); + icells = 1; + } for (i = 0, k = 0; i < nintr; i += icells, k++) { intr[i] = ofw_bus_map_intr(dev, iparent, intr[i]); resource_list_add(rl, SYS_RES_IRQ, k, intr[i], intr[i], |