- 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.
This commit is contained in:
Marius Strobl 2005-05-19 15:47:37 +00:00
parent 0f93d8245d
commit 42be1191a0

View File

@ -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));