summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authormarius <marius@FreeBSD.org>2005-05-19 15:47:37 +0000
committermarius <marius@FreeBSD.org>2005-05-19 15:47:37 +0000
commit0ef27299c3538d580cf75375e746f66dce6fd6e1 (patch)
tree6b9c99aab65ffeccd5977b373f814103ea36eeca /sys
parent906cfe30a450d9ef16216f5fba3f4b63fbf21899 (diff)
downloadFreeBSD-src-0ef27299c3538d580cf75375e746f66dce6fd6e1.zip
FreeBSD-src-0ef27299c3538d580cf75375e746f66dce6fd6e1.tar.gz
- When iterating over the register resources of the children don't use
the iteration variable as the RID when adding the respective resource to the child via bus_set_resource(). In case a device has both I/O and memory resources this generates gaps in the newbus resources of the child, e.g. its first memory resource might end up as RID 1. To solve this mimic resource_list_add_next() via resource_list_find() and bus_set_resource(); we can't just use resource_list_add_next() here as this would circumvent the limit checks in isa_set_resource() of the common ISA code. This however is more or less a theoretical problem so far as all known ISA devices on sparc64 soley use I/O space. - Just use bus_generic_rl_release_resource() for isa_release_resource() instead of re-implementing the former. - Improve some comments to better reflect reality, minor clean-up and simplifications, return NULL instead of 0 were appropriate.
Diffstat (limited to 'sys')
-rw-r--r--sys/sparc64/isa/isa.c60
1 files changed, 33 insertions, 27 deletions
diff --git a/sys/sparc64/isa/isa.c b/sys/sparc64/isa/isa.c
index b849dfc..4147e37 100644
--- a/sys/sparc64/isa/isa.c
+++ b/sys/sparc64/isa/isa.c
@@ -153,12 +153,10 @@ isa_init(device_t dev)
}
}
-struct ofw_isa_pnp_map {
+static struct {
const char *name;
uint32_t id;
-};
-
-static struct ofw_isa_pnp_map pnp_map[] = {
+} ofw_isa_pnp_map[] = {
{ "SUNW,lomh", 0x0000ae4e }, /* SUN0000 */
{ "dma", 0x0002d041 }, /* PNP0200 */
{ "floppy", 0x0007d041 }, /* PNP0700 */
@@ -176,12 +174,13 @@ static void
isa_setup_children(device_t dev, phandle_t parent)
{
struct isa_regs *regs;
+ struct resource_list *rl;
device_t cdev;
u_int64_t end, start;
ofw_isa_intr_t *intrs, rintr;
phandle_t node;
uint32_t *drqs, *regidx;
- int i, ndrq, nintr, nreg, nregidx, rtype;
+ int i, ndrq, nintr, nreg, nregidx, rid, rtype;
char *name;
/*
@@ -208,10 +207,10 @@ isa_setup_children(device_t dev, phandle_t parent)
continue;
}
- for (i = 0; pnp_map[i].name != NULL; i++)
- if (strcmp(pnp_map[i].name, name) == 0)
+ for (i = 0; ofw_isa_pnp_map[i].name != NULL; i++)
+ if (strcmp(ofw_isa_pnp_map[i].name, name) == 0)
break;
- if (i == (sizeof(pnp_map) / sizeof(*pnp_map)) - 1) {
+ if (ofw_isa_pnp_map[i].name == NULL) {
printf("isa_setup_children: no PnP map entry for node "
"0x%lx: %s\n", (unsigned long)node, name);
continue;
@@ -220,9 +219,10 @@ isa_setup_children(device_t dev, phandle_t parent)
if ((cdev = BUS_ADD_CHILD(dev, ISA_ORDER_PNPBIOS, NULL, -1)) ==
NULL)
panic("isa_setup_children: BUS_ADD_CHILD failed");
- isa_set_logicalid(cdev, pnp_map[i].id);
- isa_set_vendorid(cdev, pnp_map[i].id);
+ isa_set_logicalid(cdev, ofw_isa_pnp_map[i].id);
+ isa_set_vendorid(cdev, ofw_isa_pnp_map[i].id);
+ rl = BUS_GET_RESOURCE_LIST(dev, cdev);
nreg = OF_getprop_alloc(node, "reg", sizeof(*regs),
(void **)&regs);
for (i = 0; i < nreg; i++) {
@@ -230,7 +230,10 @@ isa_setup_children(device_t dev, phandle_t parent)
end = start + regs[i].size - 1;
rtype = ofw_isa_range_map(isab_ranges, isab_nrange,
&start, &end, NULL);
- bus_set_resource(cdev, rtype, i, start,
+ rid = 0;
+ while (resource_list_find(rl, rtype, rid) != NULL)
+ rid++;
+ bus_set_resource(cdev, rtype, rid, start,
end - start + 1);
}
if (nreg == -1 && parent != isab_node) {
@@ -251,8 +254,12 @@ isa_setup_children(device_t dev, phandle_t parent)
end = start + regs[regidx[i]].size - 1;
rtype = ofw_isa_range_map(isab_ranges,
isab_nrange, &start, &end, NULL);
- bus_set_resource(cdev, rtype, i, start,
- end - start + 1);
+ rid = 0;
+ while (resource_list_find(rl, rtype,
+ rid) != NULL)
+ rid++;
+ bus_set_resource(cdev, rtype, rid,
+ start, end - start + 1);
}
}
if (regidx != NULL)
@@ -304,35 +311,35 @@ isa_alloc_resource(device_t bus, device_t child, int type, int *rid,
*/
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;
+ struct resource_list *rl;
struct resource_list_entry *rle;
u_long base, limit;
+ rl = BUS_GET_RESOURCE_LIST(bus, child);
if (!passthrough && !isdefault) {
rle = resource_list_find(rl, type, *rid);
if (!rle) {
if (*rid < 0)
- return 0;
+ return (NULL);
switch (type) {
case SYS_RES_IRQ:
if (*rid >= ISA_NIRQ)
- return 0;
+ return (NULL);
break;
case SYS_RES_DRQ:
if (*rid >= ISA_NDRQ)
- return 0;
+ return (NULL);
break;
case SYS_RES_MEMORY:
if (*rid >= ISA_NMEM)
- return 0;
+ return (NULL);
break;
case SYS_RES_IOPORT:
if (*rid >= ISA_NPORT)
- return 0;
+ return (NULL);
break;
default:
- return 0;
+ return (NULL);
}
resource_list_add(rl, type, *rid, start, end, count);
}
@@ -384,10 +391,8 @@ int
isa_release_resource(device_t bus, device_t child, int type, int rid,
struct resource *res)
{
- struct isa_device* idev = DEVTOISA(child);
- struct resource_list *rl = &idev->id_resources;
- return (resource_list_release(rl, bus, child, type, rid, res));
+ return (bus_generic_rl_release_resource(bus, child, type, rid, res));
}
int
@@ -397,9 +402,10 @@ isa_setup_intr(device_t dev, device_t child,
{
/*
- * Just pass through. This is going to be handled by either one of
- * the parent PCI buses or the nexus device.
- * The interrupt was routed at allocation time.
+ * Just pass through. This is going to be handled by either
+ * one of the parent PCI buses or the nexus device.
+ * The interrupt had been routed before it was added to the
+ * resource list of the child.
*/
return (BUS_SETUP_INTR(device_get_parent(dev), child, irq, flags, intr,
arg, cookiep));
OpenPOWER on IntegriCloud