- 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:
parent
0f93d8245d
commit
42be1191a0
@ -153,12 +153,10 @@ isa_init(device_t dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ofw_isa_pnp_map {
|
static struct {
|
||||||
const char *name;
|
const char *name;
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
};
|
} ofw_isa_pnp_map[] = {
|
||||||
|
|
||||||
static struct ofw_isa_pnp_map pnp_map[] = {
|
|
||||||
{ "SUNW,lomh", 0x0000ae4e }, /* SUN0000 */
|
{ "SUNW,lomh", 0x0000ae4e }, /* SUN0000 */
|
||||||
{ "dma", 0x0002d041 }, /* PNP0200 */
|
{ "dma", 0x0002d041 }, /* PNP0200 */
|
||||||
{ "floppy", 0x0007d041 }, /* PNP0700 */
|
{ "floppy", 0x0007d041 }, /* PNP0700 */
|
||||||
@ -176,12 +174,13 @@ static void
|
|||||||
isa_setup_children(device_t dev, phandle_t parent)
|
isa_setup_children(device_t dev, phandle_t parent)
|
||||||
{
|
{
|
||||||
struct isa_regs *regs;
|
struct isa_regs *regs;
|
||||||
|
struct resource_list *rl;
|
||||||
device_t cdev;
|
device_t cdev;
|
||||||
u_int64_t end, start;
|
u_int64_t end, start;
|
||||||
ofw_isa_intr_t *intrs, rintr;
|
ofw_isa_intr_t *intrs, rintr;
|
||||||
phandle_t node;
|
phandle_t node;
|
||||||
uint32_t *drqs, *regidx;
|
uint32_t *drqs, *regidx;
|
||||||
int i, ndrq, nintr, nreg, nregidx, rtype;
|
int i, ndrq, nintr, nreg, nregidx, rid, rtype;
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -208,10 +207,10 @@ isa_setup_children(device_t dev, phandle_t parent)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; pnp_map[i].name != NULL; i++)
|
for (i = 0; ofw_isa_pnp_map[i].name != NULL; i++)
|
||||||
if (strcmp(pnp_map[i].name, name) == 0)
|
if (strcmp(ofw_isa_pnp_map[i].name, name) == 0)
|
||||||
break;
|
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 "
|
printf("isa_setup_children: no PnP map entry for node "
|
||||||
"0x%lx: %s\n", (unsigned long)node, name);
|
"0x%lx: %s\n", (unsigned long)node, name);
|
||||||
continue;
|
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)) ==
|
if ((cdev = BUS_ADD_CHILD(dev, ISA_ORDER_PNPBIOS, NULL, -1)) ==
|
||||||
NULL)
|
NULL)
|
||||||
panic("isa_setup_children: BUS_ADD_CHILD failed");
|
panic("isa_setup_children: BUS_ADD_CHILD failed");
|
||||||
isa_set_logicalid(cdev, pnp_map[i].id);
|
isa_set_logicalid(cdev, ofw_isa_pnp_map[i].id);
|
||||||
isa_set_vendorid(cdev, 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),
|
nreg = OF_getprop_alloc(node, "reg", sizeof(*regs),
|
||||||
(void **)®s);
|
(void **)®s);
|
||||||
for (i = 0; i < nreg; i++) {
|
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;
|
end = start + regs[i].size - 1;
|
||||||
rtype = ofw_isa_range_map(isab_ranges, isab_nrange,
|
rtype = ofw_isa_range_map(isab_ranges, isab_nrange,
|
||||||
&start, &end, NULL);
|
&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);
|
end - start + 1);
|
||||||
}
|
}
|
||||||
if (nreg == -1 && parent != isab_node) {
|
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;
|
end = start + regs[regidx[i]].size - 1;
|
||||||
rtype = ofw_isa_range_map(isab_ranges,
|
rtype = ofw_isa_range_map(isab_ranges,
|
||||||
isab_nrange, &start, &end, NULL);
|
isab_nrange, &start, &end, NULL);
|
||||||
bus_set_resource(cdev, rtype, i, start,
|
rid = 0;
|
||||||
end - start + 1);
|
while (resource_list_find(rl, rtype,
|
||||||
|
rid) != NULL)
|
||||||
|
rid++;
|
||||||
|
bus_set_resource(cdev, rtype, rid,
|
||||||
|
start, end - start + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (regidx != NULL)
|
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 passthrough = (device_get_parent(child) != bus);
|
||||||
int isdefault = (start == 0UL && end == ~0UL);
|
int isdefault = (start == 0UL && end == ~0UL);
|
||||||
struct isa_device* idev = DEVTOISA(child);
|
struct resource_list *rl;
|
||||||
struct resource_list *rl = &idev->id_resources;
|
|
||||||
struct resource_list_entry *rle;
|
struct resource_list_entry *rle;
|
||||||
u_long base, limit;
|
u_long base, limit;
|
||||||
|
|
||||||
|
rl = BUS_GET_RESOURCE_LIST(bus, child);
|
||||||
if (!passthrough && !isdefault) {
|
if (!passthrough && !isdefault) {
|
||||||
rle = resource_list_find(rl, type, *rid);
|
rle = resource_list_find(rl, type, *rid);
|
||||||
if (!rle) {
|
if (!rle) {
|
||||||
if (*rid < 0)
|
if (*rid < 0)
|
||||||
return 0;
|
return (NULL);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SYS_RES_IRQ:
|
case SYS_RES_IRQ:
|
||||||
if (*rid >= ISA_NIRQ)
|
if (*rid >= ISA_NIRQ)
|
||||||
return 0;
|
return (NULL);
|
||||||
break;
|
break;
|
||||||
case SYS_RES_DRQ:
|
case SYS_RES_DRQ:
|
||||||
if (*rid >= ISA_NDRQ)
|
if (*rid >= ISA_NDRQ)
|
||||||
return 0;
|
return (NULL);
|
||||||
break;
|
break;
|
||||||
case SYS_RES_MEMORY:
|
case SYS_RES_MEMORY:
|
||||||
if (*rid >= ISA_NMEM)
|
if (*rid >= ISA_NMEM)
|
||||||
return 0;
|
return (NULL);
|
||||||
break;
|
break;
|
||||||
case SYS_RES_IOPORT:
|
case SYS_RES_IOPORT:
|
||||||
if (*rid >= ISA_NPORT)
|
if (*rid >= ISA_NPORT)
|
||||||
return 0;
|
return (NULL);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return (NULL);
|
||||||
}
|
}
|
||||||
resource_list_add(rl, type, *rid, start, end, count);
|
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,
|
isa_release_resource(device_t bus, device_t child, int type, int rid,
|
||||||
struct resource *res)
|
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
|
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
|
* Just pass through. This is going to be handled by either
|
||||||
* the parent PCI buses or the nexus device.
|
* one of the parent PCI buses or the nexus device.
|
||||||
* The interrupt was routed at allocation time.
|
* 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,
|
return (BUS_SETUP_INTR(device_get_parent(dev), child, irq, flags, intr,
|
||||||
arg, cookiep));
|
arg, cookiep));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user