diff options
author | imp <imp@FreeBSD.org> | 2005-12-29 23:38:45 +0000 |
---|---|---|
committer | imp <imp@FreeBSD.org> | 2005-12-29 23:38:45 +0000 |
commit | 95bb7dd5c456f4064c8d82261961b3a348d5a32f (patch) | |
tree | 4a7d1d996b155022f281e2a194ef82545df89a91 | |
parent | 2cf01da41229a069a9e67de3d163a840b308d5da (diff) | |
download | FreeBSD-src-95bb7dd5c456f4064c8d82261961b3a348d5a32f.zip FreeBSD-src-95bb7dd5c456f4064c8d82261961b3a348d5a32f.tar.gz |
Simplify the opening of the resources for cardbus cards. Before we'd
try very hard to be perfect. However, these attempts broke down when
there were large numbers of resources. We'd not be able to map them all.
Instead, accept that we might pass more range to thse subbus than
might be optimal be able to compute. However, there's little harm in
this and it allows us to pass greater resources through.
# it has been suggested that we allocate a fixed amount of resources
# on attach and give it out upon request. This might not be a bad idea...
-rw-r--r-- | sys/dev/pccbb/pccbb.c | 155 |
1 files changed, 53 insertions, 102 deletions
diff --git a/sys/dev/pccbb/pccbb.c b/sys/dev/pccbb/pccbb.c index 012e862..1ec2d66 100644 --- a/sys/dev/pccbb/pccbb.c +++ b/sys/dev/pccbb/pccbb.c @@ -485,7 +485,7 @@ cbb_event_thread(void *arg) */ mtx_lock(&Giant); status = cbb_get(sc, CBB_SOCKET_STATE); - DPRINTF(("Status is 0x%x\n", status)); + DPRINTF(("Status is 0x%x %x\n", status, sc->bsh)); if (!CBB_CARD_PRESENT(status)) { not_a_card = 0; /* We know card type */ cbb_removal(sc); @@ -1034,21 +1034,20 @@ cbb_cardbus_mem_open(device_t brdev, int win, uint32_t start, uint32_t end) return (0); } -/* - * XXX The following function belongs in the pci bus layer. - */ +#define START_NONE 0xffffffff +#define END_NONE 0 + static void cbb_cardbus_auto_open(struct cbb_softc *sc, int type) { uint32_t starts[2]; uint32_t ends[2]; struct cbb_reslist *rle; - int align; - int prefetchable[2]; + int align, i; uint32_t reg; - starts[0] = starts[1] = 0xffffffff; - ends[0] = ends[1] = 0; + starts[0] = starts[1] = START_NONE; + ends[0] = ends[1] = END_NONE; if (type == SYS_RES_MEMORY) align = CBB_MEMALIGN; @@ -1057,115 +1056,68 @@ cbb_cardbus_auto_open(struct cbb_softc *sc, int type) else align = 1; - /* - * This looks somewhat bogus, and doesn't seem to really respect - * alignment. The alignment stuff is happening too late (it - * should happen at allocation time, not activation time) and - * this code looks generally to be too complex for the purpose - * it surves. - */ SLIST_FOREACH(rle, &sc->rl, link) { if (rle->type != type) - ; - else if (rle->res == NULL) { - device_printf(sc->dev, "WARNING: Resource not reserved? " - "(type=%d, addr=%lx)\n", - rle->type, rman_get_start(rle->res)); - } else if (!(rman_get_flags(rle->res) & RF_ACTIVE)) { - /* XXX */ - } else if (starts[0] == 0xffffffff) { - starts[0] = rman_get_start(rle->res); - ends[0] = rman_get_end(rle->res); - prefetchable[0] = - rman_get_flags(rle->res) & RF_PREFETCHABLE; - } else if (rman_get_end(rle->res) > ends[0] && - rman_get_start(rle->res) - ends[0] < - CBB_AUTO_OPEN_SMALLHOLE && prefetchable[0] == - (rman_get_flags(rle->res) & RF_PREFETCHABLE)) { - ends[0] = rman_get_end(rle->res); - } else if (rman_get_start(rle->res) < starts[0] && - starts[0] - rman_get_end(rle->res) < - CBB_AUTO_OPEN_SMALLHOLE && prefetchable[0] == - (rman_get_flags(rle->res) & RF_PREFETCHABLE)) { - starts[0] = rman_get_start(rle->res); - } else if (starts[1] == 0xffffffff) { - starts[1] = rman_get_start(rle->res); - ends[1] = rman_get_end(rle->res); - prefetchable[1] = - rman_get_flags(rle->res) & RF_PREFETCHABLE; - } else if (rman_get_end(rle->res) > ends[1] && - rman_get_start(rle->res) - ends[1] < - CBB_AUTO_OPEN_SMALLHOLE && prefetchable[1] == - (rman_get_flags(rle->res) & RF_PREFETCHABLE)) { - ends[1] = rman_get_end(rle->res); - } else if (rman_get_start(rle->res) < starts[1] && - starts[1] - rman_get_end(rle->res) < - CBB_AUTO_OPEN_SMALLHOLE && prefetchable[1] == - (rman_get_flags(rle->res) & RF_PREFETCHABLE)) { - starts[1] = rman_get_start(rle->res); + continue; + if (rle->res == NULL) + continue; + if (!(rman_get_flags(rle->res) & RF_ACTIVE)) + continue; + if (rman_get_flags(rle->res) & RF_PREFETCHABLE) + i = 1; + else + i = 0; + if (rman_get_start(rle->res) < starts[i]) + starts[i] = rman_get_start(rle->res); + if (rman_get_end(rle->res) > ends[i]) + ends[i] = rman_get_end(rle->res); + } + for (i = 0; i < 2; i++) { + if (starts[i] == START_NONE) + continue; + starts[i] &= ~(align - 1); + ends[i] = ((ends[i] + align - 1) & ~(align - 1)) - 1; + } + if (starts[0] != START_NONE && starts[1] != START_NONE) { + if (starts[0] < starts[1]) { + if (ends[0] > starts[1]) { + device_printf(sc->dev, "Overlapping ranges" + " for prefetch and non-prefetch memory\n"); + return; + } } else { - uint32_t diffs[2]; - int win; - - diffs[0] = diffs[1] = 0xffffffff; - if (rman_get_start(rle->res) > ends[0]) - diffs[0] = rman_get_start(rle->res) - ends[0]; - else if (rman_get_end(rle->res) < starts[0]) - diffs[0] = starts[0] - rman_get_end(rle->res); - if (rman_get_start(rle->res) > ends[1]) - diffs[1] = rman_get_start(rle->res) - ends[1]; - else if (rman_get_end(rle->res) < starts[1]) - diffs[1] = starts[1] - rman_get_end(rle->res); - - win = (diffs[0] <= diffs[1])?0:1; - if (rman_get_start(rle->res) > ends[win]) - ends[win] = rman_get_end(rle->res); - else if (rman_get_end(rle->res) < starts[win]) - starts[win] = rman_get_start(rle->res); - if (!(rman_get_flags(rle->res) & RF_PREFETCHABLE)) - prefetchable[win] = 0; + if (ends[1] > starts[0]) { + device_printf(sc->dev, "Overlapping ranges" + " for prefetch and non-prefetch memory\n"); + return; + } } - - if (starts[0] != 0xffffffff) - starts[0] -= starts[0] % align; - if (starts[1] != 0xffffffff) - starts[1] -= starts[1] % align; - if (ends[0] % align != 0) - ends[0] += align - ends[0] % align - 1; - if (ends[1] % align != 0) - ends[1] += align - ends[1] % align - 1; } if (type == SYS_RES_MEMORY) { cbb_cardbus_mem_open(sc->dev, 0, starts[0], ends[0]); cbb_cardbus_mem_open(sc->dev, 1, starts[1], ends[1]); reg = pci_read_config(sc->dev, CBBR_BRIDGECTRL, 2); - reg &= ~(CBBM_BRIDGECTRL_PREFETCH_0| + reg &= ~(CBBM_BRIDGECTRL_PREFETCH_0 | CBBM_BRIDGECTRL_PREFETCH_1); - reg |= (prefetchable[0]?CBBM_BRIDGECTRL_PREFETCH_0:0)| - (prefetchable[1]?CBBM_BRIDGECTRL_PREFETCH_1:0); + if (starts[1] != START_NONE) + reg |= CBBM_BRIDGECTRL_PREFETCH_1; pci_write_config(sc->dev, CBBR_BRIDGECTRL, reg, 2); - if (cbb_debug) { - if (starts[0] != 0xffffffff) - device_printf(sc->dev, "Memory window 0:" - " %#x-%#x%s\n", starts[0], ends[0], - prefetchable[0] ? " prefetch" : ""); - if (starts[1] != 0xffffffff) - device_printf(sc->dev, "Memory window 1:" - " %#x-%#x%s\n", starts[1], ends[1], - prefetchable[1] ? " prefetch" : ""); + if (bootverbose) { + device_printf(sc->dev, "Opening memory:\n"); + if (starts[0] != START_NONE) + device_printf(sc->dev, "Normal: %#x-%#x\n", + starts[0], ends[0]); + if (starts[1] != START_NONE) + device_printf(sc->dev, "Prefetch: %#x-%#x\n", + starts[1], ends[1]); } } else if (type == SYS_RES_IOPORT) { cbb_cardbus_io_open(sc->dev, 0, starts[0], ends[0]); cbb_cardbus_io_open(sc->dev, 1, starts[1], ends[1]); - if (cbb_debug) { - if (starts[0] != 0xffffffff) - device_printf(sc->dev, "I/O window 0:" - " %#x-%#x\n", starts[0], ends[0]); - if (starts[1] != 0xffffffff) - device_printf(sc->dev, "I/O window 1:" - " %#x-%#x\n", starts[1], ends[1]); - } + if (bootverbose && starts[0] != START_NONE) + device_printf(sc->dev, "Opening I/O: %#x-%#x\n", + starts[0], ends[0]); } } @@ -1241,7 +1193,6 @@ cbb_cardbus_alloc_resource(device_t brdev, device_t child, int type, rman_make_alignment_flags(align); break; } - res = BUS_ALLOC_RESOURCE(device_get_parent(brdev), child, type, rid, start, end, count, flags & ~RF_ACTIVE); if (res == NULL) { |