summaryrefslogtreecommitdiffstats
path: root/sys/dev/cardbus/cardbus_cis.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/cardbus/cardbus_cis.c')
-rw-r--r--sys/dev/cardbus/cardbus_cis.c129
1 files changed, 39 insertions, 90 deletions
diff --git a/sys/dev/cardbus/cardbus_cis.c b/sys/dev/cardbus/cardbus_cis.c
index 2b8e2b2..250ac65 100644
--- a/sys/dev/cardbus/cardbus_cis.c
+++ b/sys/dev/cardbus/cardbus_cis.c
@@ -456,7 +456,6 @@ decode_tuple_bar(device_t cbdev, device_t child, int id,
* device drivers will know which type of BARs can be used.
*/
pci_enable_io(child, type);
-
return (0);
}
@@ -770,6 +769,14 @@ cardbus_parse_cis(device_t cbdev, device_t child,
return (0);
}
+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
barsort(const void *a, const void *b)
{
@@ -821,10 +828,11 @@ cardbus_alloc_resources(device_t cbdev, device_t child)
/* Allocate prefetchable memory */
flags = 0;
for (tmp = 0; tmp < count; tmp++) {
- if (barlist[tmp]->res == NULL &&
- barlist[tmp]->type == SYS_RES_MEMORY &&
- dinfo->mprefetchable & BARBIT(barlist[tmp]->rid)) {
- flags = rman_make_alignment_flags(barlist[tmp]->count);
+ rle = barlist[tmp];
+ if (rle->res == NULL &&
+ rle->type == SYS_RES_MEMORY &&
+ dinfo->mprefetchable & BARBIT(rle->rid)) {
+ flags = rman_make_alignment_flags(rle->count);
break;
}
}
@@ -850,36 +858,11 @@ cardbus_alloc_resources(device_t cbdev, device_t child)
*/
bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
for (tmp = 0; tmp < count; tmp++) {
- if (barlist[tmp]->res == NULL &&
- barlist[tmp]->type == SYS_RES_MEMORY &&
- dinfo->mprefetchable & BARBIT(barlist[tmp]->rid)) {
- barlist[tmp]->res = bus_alloc_resource(cbdev,
- barlist[tmp]->type,
- &barlist[tmp]->rid, start, end,
- barlist[tmp]->count,
- rman_make_alignment_flags(
- barlist[tmp]->count));
- if (barlist[tmp]->res == NULL) {
- mem_nsize += barlist[tmp]->count;
- dinfo->mprefetchable &=
- ~BARBIT(barlist[tmp]->rid);
- DEVPRINTF((cbdev, "Cannot pre-allocate "
- "prefetchable memory, will try as "
- "non-prefetchable.\n"));
- } else {
- barlist[tmp]->start =
- rman_get_start(barlist[tmp]->res);
- barlist[tmp]->end =
- rman_get_end(barlist[tmp]->res);
- pci_write_config(child,
- barlist[tmp]->rid,
- barlist[tmp]->start, 4);
- DEVPRINTF((cbdev, "Prefetchable memory "
- "rid=%x at %lx-%lx\n",
- barlist[tmp]->rid,
- barlist[tmp]->start,
- barlist[tmp]->end));
- }
+ rle = barlist[tmp];
+ if (rle->type == SYS_RES_MEMORY &&
+ dinfo->mprefetchable & BARBIT(rle->rid)) {
+ cardbus_do_res(rle, child, start);
+ start += rle->count;
}
}
}
@@ -887,9 +870,10 @@ cardbus_alloc_resources(device_t cbdev, device_t child)
/* Allocate non-prefetchable memory */
flags = 0;
for (tmp = 0; tmp < count; tmp++) {
- if (barlist[tmp]->res == NULL &&
- barlist[tmp]->type == SYS_RES_MEMORY) {
- flags = rman_make_alignment_flags(barlist[tmp]->count);
+ rle = barlist[tmp];
+ if (rle->type == SYS_RES_MEMORY &&
+ (dinfo->mprefetchable & BARBIT(rle->rid)) == 0) {
+ flags = rman_make_alignment_flags(rle->count);
break;
}
}
@@ -916,29 +900,11 @@ cardbus_alloc_resources(device_t cbdev, device_t child)
*/
bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
for (tmp = 0; tmp < count; tmp++) {
- if (barlist[tmp]->res == NULL &&
- barlist[tmp]->type == SYS_RES_MEMORY) {
- barlist[tmp]->res = bus_alloc_resource(cbdev,
- barlist[tmp]->type, &barlist[tmp]->rid,
- start, end, barlist[tmp]->count,
- rman_make_alignment_flags(
- barlist[tmp]->count));
- if (barlist[tmp]->res == NULL) {
- DEVPRINTF((cbdev, "Cannot pre-allocate "
- "memory for cardbus device\n"));
- free(barlist, M_DEVBUF);
- return (ENOMEM);
- }
- barlist[tmp]->start =
- rman_get_start(barlist[tmp]->res);
- barlist[tmp]->end = rman_get_end(
- barlist[tmp]->res);
- pci_write_config(child, barlist[tmp]->rid,
- barlist[tmp]->start, 4);
- DEVPRINTF((cbdev, "Non-prefetchable memory "
- "rid=%x at %lx-%lx (%lx)\n",
- barlist[tmp]->rid, barlist[tmp]->start,
- barlist[tmp]->end, barlist[tmp]->count));
+ rle = barlist[tmp];
+ if (rle->type == SYS_RES_MEMORY &&
+ (dinfo->mprefetchable & BARBIT(rle->rid)) == 0) {
+ cardbus_do_res(rle, child, start);
+ start += rle->count;
}
}
}
@@ -946,9 +912,9 @@ cardbus_alloc_resources(device_t cbdev, device_t child)
/* Allocate IO ports */
flags = 0;
for (tmp = 0; tmp < count; tmp++) {
- if (barlist[tmp]->res == NULL &&
- barlist[tmp]->type == SYS_RES_IOPORT) {
- flags = rman_make_alignment_flags(barlist[tmp]->count);
+ rle = barlist[tmp];
+ if (rle->type == SYS_RES_IOPORT) {
+ flags = rman_make_alignment_flags(rle->count);
break;
}
}
@@ -973,28 +939,10 @@ cardbus_alloc_resources(device_t cbdev, device_t child)
*/
bus_release_resource(cbdev, SYS_RES_IOPORT, rid, res);
for (tmp = 0; tmp < count; tmp++) {
- if (barlist[tmp]->res == NULL &&
- barlist[tmp]->type == SYS_RES_IOPORT) {
- barlist[tmp]->res = bus_alloc_resource(cbdev,
- barlist[tmp]->type, &barlist[tmp]->rid,
- start, end, barlist[tmp]->count,
- rman_make_alignment_flags(
- barlist[tmp]->count));
- if (barlist[tmp]->res == NULL) {
- DEVPRINTF((cbdev, "Cannot pre-allocate "
- "IO port for cardbus device\n"));
- free(barlist, M_DEVBUF);
- return (ENOMEM);
- }
- barlist[tmp]->start =
- rman_get_start(barlist[tmp]->res);
- barlist[tmp]->end =
- rman_get_end(barlist[tmp]->res);
- pci_write_config(child, barlist[tmp]->rid,
- barlist[tmp]->start, 4);
- DEVPRINTF((cbdev, "IO port rid=%x at %lx-%lx\n",
- barlist[tmp]->rid, barlist[tmp]->start,
- barlist[tmp]->end));
+ rle = barlist[tmp];
+ if (rle->type == SYS_RES_IOPORT) {
+ cardbus_do_res(rle, child, start);
+ start += rle->count;
}
}
}
@@ -1003,10 +951,11 @@ cardbus_alloc_resources(device_t cbdev, device_t child)
rid = 0;
res = bus_alloc_resource(cbdev, SYS_RES_IRQ, &rid, 0, ~0UL, 1,
RF_SHAREABLE);
- resource_list_add(&dinfo->pci.resources, SYS_RES_IRQ, rid,
- rman_get_start(res), rman_get_end(res), 1);
- rle = resource_list_find(&dinfo->pci.resources, SYS_RES_IRQ, rid);
- rle->res = res;
+ 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);
dinfo->pci.cfg.intline = rman_get_start(res);
pci_write_config(child, PCIR_INTLINE, rman_get_start(res), 1);
OpenPOWER on IntegriCloud