When in rev. 1.47 cardbus_alloc_resources() function was moved from
cardbus_cis.c to this file, some code was not merged and thus resource list entries were invalid. They didn't have a resources attached to them. However, the problem was masked for some time later, because newer resources list entries were added to the head of the list, and resource_list_find() always returned the first matching resource list entry. Usually the underlying driver allocated a valid resource and added it to the head of the list, and invalid one wasn't used. In rev. 1.174 of subr_bus.c the sorting of resource list entries was reversed demasking the problem in cardbus_alloc_resources(). This commit fixes the problem returning back some code from cardbus_cis.c, pre-1.49 revisions. PR: kern/87114 PR: kern/90441 Hardware provided by: Vasily Olekhov <olekhov yandex.ru> Reviewed by: imp
This commit is contained in:
parent
fc9fac4c78
commit
086745614c
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=153788
@ -149,14 +149,6 @@ cardbus_pickup_maps(device_t cbdev, device_t child)
|
||||
cardbus_add_map(cbdev, child, PCIR_BAR(reg));
|
||||
}
|
||||
|
||||
static void
|
||||
cardbus_do_res(struct resource_list_entry *rle, device_t child, uint32_t start)
|
||||
{
|
||||
rle->start = start;
|
||||
rle->end = start + rle->count - 1;
|
||||
pci_write_config(child, rle->rid, rle->start, 4);
|
||||
}
|
||||
|
||||
static int
|
||||
cardbus_barsort(const void *a, const void *b)
|
||||
{
|
||||
@ -249,8 +241,16 @@ cardbus_alloc_resources(device_t cbdev, device_t child)
|
||||
rle = barlist[tmp];
|
||||
if (rle->type == SYS_RES_MEMORY &&
|
||||
dinfo->mprefetchable & BARBIT(rle->rid)) {
|
||||
cardbus_do_res(rle, child, start);
|
||||
start += rle->count;
|
||||
rle->res = bus_alloc_resource(cbdev,
|
||||
rle->type, &rle->rid, start, end,
|
||||
rle->count,
|
||||
rman_make_alignment_flags(rle->count));
|
||||
if (rle->res != NULL) {
|
||||
rle->start = rman_get_start(rle->res);
|
||||
rle->end = rman_get_end(rle->res);
|
||||
pci_write_config(child,
|
||||
rle->rid, rle->start, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -297,8 +297,20 @@ cardbus_alloc_resources(device_t cbdev, device_t child)
|
||||
rle = barlist[tmp];
|
||||
if (rle->type == SYS_RES_MEMORY &&
|
||||
(dinfo->mprefetchable & BARBIT(rle->rid)) == 0) {
|
||||
cardbus_do_res(rle, child, start);
|
||||
start += rle->count;
|
||||
rle->res = bus_alloc_resource(cbdev,
|
||||
rle->type, &rle->rid, start, end,
|
||||
rle->count,
|
||||
rman_make_alignment_flags(rle->count));
|
||||
if (rle->res == NULL) {
|
||||
DEVPRINTF((cbdev, "Cannot pre-allocate "
|
||||
"memory for cardbus device\n"));
|
||||
free(barlist, M_DEVBUF);
|
||||
return (ENOMEM);
|
||||
}
|
||||
rle->start = rman_get_start(rle->res);
|
||||
rle->end = rman_get_end(rle->res);
|
||||
pci_write_config(child,
|
||||
rle->rid, rle->start, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -341,8 +353,20 @@ cardbus_alloc_resources(device_t cbdev, device_t child)
|
||||
for (tmp = 0; tmp < count; tmp++) {
|
||||
rle = barlist[tmp];
|
||||
if (rle->type == SYS_RES_IOPORT) {
|
||||
cardbus_do_res(rle, child, start);
|
||||
start += rle->count;
|
||||
rle->res = bus_alloc_resource(cbdev,
|
||||
rle->type, &rle->rid, start, end,
|
||||
rle->count,
|
||||
rman_make_alignment_flags(rle->count));
|
||||
if (rle->res == NULL) {
|
||||
DEVPRINTF((cbdev, "Cannot pre-allocate "
|
||||
"IO port for cardbus device\n"));
|
||||
free(barlist, M_DEVBUF);
|
||||
return (ENOMEM);
|
||||
}
|
||||
rle->start = rman_get_start(rle->res);
|
||||
rle->end = rman_get_end(rle->res);
|
||||
pci_write_config(child,
|
||||
rle->rid, rle->start, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -357,9 +381,10 @@ cardbus_alloc_resources(device_t cbdev, device_t child)
|
||||
}
|
||||
start = rman_get_start(res);
|
||||
end = rman_get_end(res);
|
||||
bus_release_resource(cbdev, SYS_RES_IRQ, rid, res);
|
||||
resource_list_add(&dinfo->pci.resources, SYS_RES_IRQ, rid, start, end,
|
||||
1);
|
||||
rle = resource_list_find(&dinfo->pci.resources, SYS_RES_IRQ, rid);
|
||||
rle->res = res;
|
||||
dinfo->pci.cfg.intline = start;
|
||||
pci_write_config(child, PCIR_INTLINE, start, 1);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user