summaryrefslogtreecommitdiffstats
path: root/sys/dev/cardbus
diff options
context:
space:
mode:
authorglebius <glebius@FreeBSD.org>2005-12-28 10:15:01 +0000
committerglebius <glebius@FreeBSD.org>2005-12-28 10:15:01 +0000
commitcf781bf1e2e31ed168cb348dbb6519e8c5046f21 (patch)
tree55037e52ffa4817715ce2d2fbd4b22484fed186f /sys/dev/cardbus
parentfc7124b63109f5a496e22f37c58fdcb3d5d0e758 (diff)
downloadFreeBSD-src-cf781bf1e2e31ed168cb348dbb6519e8c5046f21.zip
FreeBSD-src-cf781bf1e2e31ed168cb348dbb6519e8c5046f21.tar.gz
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
Diffstat (limited to 'sys/dev/cardbus')
-rw-r--r--sys/dev/cardbus/cardbus.c55
1 files changed, 40 insertions, 15 deletions
diff --git a/sys/dev/cardbus/cardbus.c b/sys/dev/cardbus/cardbus.c
index 81c9bf7..49bc7fd 100644
--- a/sys/dev/cardbus/cardbus.c
+++ b/sys/dev/cardbus/cardbus.c
@@ -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);
OpenPOWER on IntegriCloud