Handle various ways that interrupt config data can be malformed by

warning and assuming more or less reasonable values.
This commit is contained in:
Ian Lepore 2014-08-10 00:30:12 +00:00
parent 1fb6bc18cb
commit c654477e64
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=269770

View file

@ -435,6 +435,7 @@ ofwbus_setup_dinfo(device_t dev, phandle_t node)
{
struct ofwbus_softc *sc;
struct ofwbus_devinfo *ndi;
const char *nodename;
uint32_t *reg, *intr, icells;
uint64_t phys, size;
phandle_t iparent;
@ -449,8 +450,8 @@ ofwbus_setup_dinfo(device_t dev, phandle_t node)
free(ndi, M_DEVBUF);
return (NULL);
}
if (OFWBUS_EXCLUDED(ndi->ndi_obdinfo.obd_name,
ndi->ndi_obdinfo.obd_type)) {
nodename = ndi->ndi_obdinfo.obd_name;
if (OFWBUS_EXCLUDED(nodename, ndi->ndi_obdinfo.obd_type)) {
ofw_bus_gen_destroy_devinfo(&ndi->ndi_obdinfo);
free(ndi, M_DEVBUF);
return (NULL);
@ -463,7 +464,7 @@ ofwbus_setup_dinfo(device_t dev, phandle_t node)
if (nreg % (sc->acells + sc->scells) != 0) {
if (bootverbose)
device_printf(dev, "Malformed reg property on <%s>\n",
ndi->ndi_obdinfo.obd_name);
nodename);
nreg = 0;
}
@ -487,11 +488,24 @@ ofwbus_setup_dinfo(device_t dev, phandle_t node)
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 nexus on <%s>\n", nodename);
iparent = 0xffffffff;
}
if (OF_searchencprop(OF_xref_phandle(iparent),
"#interrupt-cells", &icells, sizeof(icells)) == -1) {
device_printf(dev, "Missing #interrupt-cells property, "
"assuming <1> on <%s>\n", nodename);
icells = 1;
}
if (icells < 1 || icells > nintr) {
device_printf(dev, "Invalid #interrupt-cells property "
"value <%d>, assuming <1> on <%s>\n", icells,
nodename);
icells = 1;
}
for (i = 0, rid = 0; i < nintr; i += icells, rid++) {
intr[i] = ofw_bus_map_intr(dev, iparent, icells,
&intr[i]);