summaryrefslogtreecommitdiff
path: root/sys/dev/pci/agp.c
diff options
context:
space:
mode:
authorDimitry Andric <dim@cvs.openbsd.org>2007-01-30 21:12:15 +0000
committerDimitry Andric <dim@cvs.openbsd.org>2007-01-30 21:12:15 +0000
commit9f8ce4966cab88497f6ca4464e026d2af1c1b5ca (patch)
tree40fa8ecc346372cb6c07528d5d4a80c673667560 /sys/dev/pci/agp.c
parent8b33adb82f2e93453ba3a880a3e7031cadfd3f7b (diff)
Simplify agp_generic_bind_memory by not trying to allocate big chunks
of contiguous memory in a loop. This should save contiguous memory for other drivers, and AGP doesn't need it. Tested by many, ok miod
Diffstat (limited to 'sys/dev/pci/agp.c')
-rw-r--r--sys/dev/pci/agp.c78
1 files changed, 35 insertions, 43 deletions
diff --git a/sys/dev/pci/agp.c b/sys/dev/pci/agp.c
index f6d151ea857..98dd20ccba1 100644
--- a/sys/dev/pci/agp.c
+++ b/sys/dev/pci/agp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: agp.c,v 1.4 2007/01/03 14:05:00 deraadt Exp $ */
+/* $OpenBSD: agp.c,v 1.5 2007/01/30 21:12:14 dim Exp $ */
/*-
* Copyright (c) 2000 Doug Rabson
* All rights reserved.
@@ -514,7 +514,7 @@ agp_generic_bind_memory(struct vga_pci_softc *sc, struct agp_memory *mem,
bus_size_t done, j;
bus_addr_t pa;
off_t i, k;
- int contigpages, nseg, error;
+ int nseg, error;
lockmgr(&sc->sc_lock, LK_EXCLUSIVE, NULL);
@@ -534,56 +534,47 @@ agp_generic_bind_memory(struct vga_pci_softc *sc, struct agp_memory *mem,
}
/*
- * XXXfvdl
* The memory here needs to be directly accessable from the
* AGP video card, so it should be allocated using bus_dma.
* However, it need not be contiguous, since individual pages
* are translated using the GATT.
- *
- * Using a large chunk of contiguous memory may get in the way
- * of other subsystems that may need one, so we try to be friendly
- * and ask for allocation in chunks of a minimum of 8 pages
- * of contiguous memory on average, falling back to 4, 2 and 1
- * if really needed. Larger chunks are preferred, since allocating
- * a bus_dma_segment per page would be overkill.
*/
- for (contigpages = 32; contigpages > 0; contigpages >>= 1) {
- nseg = (mem->am_size / (contigpages * PAGE_SIZE)) + 1;
- segs = malloc(nseg * sizeof *segs, M_DEVBUF, M_WAITOK);
- if (segs == NULL)
- return ENOMEM;
- if ((error = bus_dmamem_alloc(sc->sc_dmat, mem->am_size, PAGE_SIZE, 0,
- segs, nseg, &mem->am_nseg, BUS_DMA_WAITOK)) != 0) {
- free(segs, M_DEVBUF);
- AGP_DPF("bus_dmamem_alloc failed %d\n", error);
- continue;
- }
- if ((error = bus_dmamem_map(sc->sc_dmat, segs, mem->am_nseg,
- mem->am_size, &mem->am_virtual, BUS_DMA_WAITOK)) != 0) {
- bus_dmamem_free(sc->sc_dmat, segs, mem->am_nseg);
- free(segs, M_DEVBUF);
- AGP_DPF("bus_dmamem_map failed %d\n", error);
- continue;
- }
- if ((error = bus_dmamap_load(sc->sc_dmat, mem->am_dmamap,
- mem->am_virtual, mem->am_size, NULL,
- BUS_DMA_WAITOK)) != 0) {
- bus_dmamem_unmap(sc->sc_dmat, mem->am_virtual,
- mem->am_size);
- bus_dmamem_free(sc->sc_dmat, segs, mem->am_nseg);
- free(segs, M_DEVBUF);
- AGP_DPF("bus_dmamap_load failed %d\n", error);
- continue;
- }
- mem->am_dmaseg = segs;
- break;
- }
-
- if (contigpages == 0) {
+ nseg = (mem->am_size + PAGE_SIZE - 1) / PAGE_SIZE;
+ segs = malloc(nseg * sizeof *segs, M_DEVBUF, M_WAITOK);
+ if (segs == NULL) {
lockmgr(&sc->sc_lock, LK_RELEASE, NULL);
+ AGP_DPF("malloc segs (%u) failed\n",
+ nseg * sizeof *segs);
return ENOMEM;
}
+ if ((error = bus_dmamem_alloc(sc->sc_dmat, mem->am_size, PAGE_SIZE, 0,
+ segs, nseg, &mem->am_nseg, BUS_DMA_WAITOK)) != 0) {
+ free(segs, M_DEVBUF);
+ lockmgr(&sc->sc_lock, LK_RELEASE, NULL);
+ AGP_DPF("bus_dmamem_alloc failed %d\n", error);
+ return error;
+ }
+ if ((error = bus_dmamem_map(sc->sc_dmat, segs, mem->am_nseg,
+ mem->am_size, &mem->am_virtual, BUS_DMA_WAITOK)) != 0) {
+ bus_dmamem_free(sc->sc_dmat, segs, mem->am_nseg);
+ free(segs, M_DEVBUF);
+ lockmgr(&sc->sc_lock, LK_RELEASE, NULL);
+ AGP_DPF("bus_dmamem_map failed %d\n", error);
+ return error;
+ }
+ if ((error = bus_dmamap_load(sc->sc_dmat, mem->am_dmamap,
+ mem->am_virtual, mem->am_size, NULL,
+ BUS_DMA_WAITOK)) != 0) {
+ bus_dmamem_unmap(sc->sc_dmat, mem->am_virtual,
+ mem->am_size);
+ bus_dmamem_free(sc->sc_dmat, segs, mem->am_nseg);
+ free(segs, M_DEVBUF);
+ lockmgr(&sc->sc_lock, LK_RELEASE, NULL);
+ AGP_DPF("bus_dmamap_load failed %d\n", error);
+ return error;
+ }
+ mem->am_dmaseg = segs;
/*
* Bind the individual pages and flush the chipset's
@@ -620,6 +611,7 @@ agp_generic_bind_memory(struct vga_pci_softc *sc, struct agp_memory *mem,
mem->am_nseg);
free(mem->am_dmaseg, M_DEVBUF);
lockmgr(&sc->sc_lock, LK_RELEASE, NULL);
+ AGP_DPF("AGP_BIND_PAGE failed %d\n", error);
return error;
}
}