diff options
author | Gleb Smirnoff <glebius@FreeBSD.org> | 2005-12-28 10:15:01 +0000 |
---|---|---|
committer | Gleb Smirnoff <glebius@FreeBSD.org> | 2005-12-28 10:15:01 +0000 |
commit | 086745614c65bb20df0618960d389b477ddf5df3 (patch) | |
tree | 55037e52ffa4817715ce2d2fbd4b22484fed186f /sys/dev/cardbus | |
parent | fc9fac4c78a9776538a3ab67b9ac245577a04981 (diff) | |
download | src-086745614c65bb20df0618960d389b477ddf5df3.tar.gz src-086745614c65bb20df0618960d389b477ddf5df3.zip |
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
Notes
Notes:
svn path=/head/; revision=153788
Diffstat (limited to 'sys/dev/cardbus')
-rw-r--r-- | sys/dev/cardbus/cardbus.c | 55 |
1 files changed, 40 insertions, 15 deletions
diff --git a/sys/dev/cardbus/cardbus.c b/sys/dev/cardbus/cardbus.c index 81c9bf73cd02..49bc7fd019bd 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); |