diff options
Diffstat (limited to 'sys/dev/pci/agp.c')
-rw-r--r-- | sys/dev/pci/agp.c | 81 |
1 files changed, 31 insertions, 50 deletions
diff --git a/sys/dev/pci/agp.c b/sys/dev/pci/agp.c index cd369f282a6..d392c386be0 100644 --- a/sys/dev/pci/agp.c +++ b/sys/dev/pci/agp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: agp.c,v 1.28 2009/04/15 03:09:47 oga Exp $ */ +/* $OpenBSD: agp.c,v 1.29 2009/04/20 01:28:45 oga Exp $ */ /*- * Copyright (c) 2000 Doug Rabson * All rights reserved. @@ -343,22 +343,26 @@ agp_map_aperture(struct pci_attach_args *pa, struct agp_softc *sc, u_int32_t bar struct agp_gatt * agp_alloc_gatt(bus_dma_tag_t dmat, u_int32_t apsize) { - struct agp_gatt *gatt; - u_int32_t entries = apsize >> AGP_PAGE_SHIFT; - int nseg; + struct agp_gatt *gatt; + u_int32_t entries = apsize >> AGP_PAGE_SHIFT; gatt = malloc(sizeof(*gatt), M_AGP, M_NOWAIT | M_ZERO); if (!gatt) return (NULL); gatt->ag_entries = entries; + gatt->ag_size = entries * sizeof(u_int32_t); - if (agp_alloc_dmamem(dmat, entries * sizeof(u_int32_t), - 0, &gatt->ag_dmamap, (caddr_t *)&gatt->ag_virtual, - &gatt->ag_physical, &gatt->ag_dmaseg, 1, &nseg) != 0) + if (agp_alloc_dmamem(dmat, gatt->ag_size, &gatt->ag_dmamap, + &gatt->ag_physical, &gatt->ag_dmaseg) != 0) return (NULL); - gatt->ag_size = entries * sizeof(u_int32_t); - memset(gatt->ag_virtual, 0, gatt->ag_size); + if (bus_dmamem_map(dmat, &gatt->ag_dmaseg, 1, gatt->ag_size, + (caddr_t *)&gatt->ag_virtual, BUS_DMA_NOWAIT) != 0) { + agp_free_dmamem(dmat, gatt->ag_size, gatt->ag_dmamap, + &gatt->ag_dmaseg); + return (NULL); + } + agp_flush_cache(); return (gatt); @@ -367,8 +371,8 @@ agp_alloc_gatt(bus_dma_tag_t dmat, u_int32_t apsize) void agp_free_gatt(bus_dma_tag_t dmat, struct agp_gatt *gatt) { - agp_free_dmamem(dmat, gatt->ag_size, gatt->ag_dmamap, - (caddr_t)gatt->ag_virtual, &gatt->ag_dmaseg, 1); + bus_dmamem_unmap(dmat, (caddr_t)gatt->ag_virtual, gatt->ag_size); + agp_free_dmamem(dmat, gatt->ag_size, gatt->ag_dmamap, &gatt->ag_dmaseg); free(gatt, M_AGP); } @@ -509,25 +513,14 @@ agp_generic_bind_memory(struct agp_softc *sc, struct agp_memory *mem, nseg = (mem->am_size + PAGE_SIZE - 1) / PAGE_SIZE; segs = malloc(nseg * sizeof *segs, M_AGP, M_WAITOK); if ((error = bus_dmamem_alloc(sc->sc_dmat, mem->am_size, PAGE_SIZE, 0, - segs, nseg, &mem->am_nseg, BUS_DMA_WAITOK)) != 0) { + segs, nseg, &mem->am_nseg, BUS_DMA_ZERO | BUS_DMA_WAITOK)) != 0) { free(segs, M_AGP); rw_exit_write(&sc->sc_lock); 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_AGP); - rw_exit_write(&sc->sc_lock); - 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); + if ((error = bus_dmamap_load_raw(sc->sc_dmat, mem->am_dmamap, segs, + mem->am_nseg, mem->am_size, BUS_DMA_WAITOK)) != 0) { bus_dmamem_free(sc->sc_dmat, segs, mem->am_nseg); free(segs, M_AGP); rw_exit_write(&sc->sc_lock); @@ -567,8 +560,6 @@ agp_generic_bind_memory(struct agp_softc *sc, struct agp_memory *mem, sc->sc_chipc, offset + k); bus_dmamap_unload(sc->sc_dmat, mem->am_dmamap); - bus_dmamem_unmap(sc->sc_dmat, mem->am_virtual, - mem->am_size); bus_dmamem_free(sc->sc_dmat, mem->am_dmaseg, mem->am_nseg); free(mem->am_dmaseg, M_AGP); @@ -624,7 +615,6 @@ agp_generic_unbind_memory(struct agp_softc *sc, struct agp_memory *mem) sc->sc_methods->flush_tlb(sc->sc_chipc); bus_dmamap_unload(sc->sc_dmat, mem->am_dmamap); - bus_dmamem_unmap(sc->sc_dmat, mem->am_virtual, mem->am_size); bus_dmamem_free(sc->sc_dmat, mem->am_dmaseg, mem->am_nseg); free(mem->am_dmaseg, M_AGP); @@ -637,30 +627,26 @@ agp_generic_unbind_memory(struct agp_softc *sc, struct agp_memory *mem) return (0); } +/* + * Allocates a single-segment block of zeroed, wired dma memory. + */ int -agp_alloc_dmamem(bus_dma_tag_t tag, size_t size, int flags, - bus_dmamap_t *mapp, caddr_t *vaddr, bus_addr_t *baddr, - bus_dma_segment_t *seg, int nseg, int *rseg) - +agp_alloc_dmamem(bus_dma_tag_t tag, size_t size, bus_dmamap_t *mapp, + bus_addr_t *baddr, bus_dma_segment_t *seg) { - int error, level = 0; + int error, level = 0, nseg; if ((error = bus_dmamem_alloc(tag, size, PAGE_SIZE, 0, - seg, nseg, rseg, BUS_DMA_NOWAIT)) != 0) - goto out; - level++; - - if ((error = bus_dmamem_map(tag, seg, *rseg, size, vaddr, - BUS_DMA_NOWAIT | flags)) != 0) + seg, 1, &nseg, BUS_DMA_NOWAIT | BUS_DMA_ZERO)) != 0) goto out; level++; - if ((error = bus_dmamap_create(tag, size, *rseg, size, 0, + if ((error = bus_dmamap_create(tag, size, nseg, size, 0, BUS_DMA_NOWAIT, mapp)) != 0) goto out; level++; - if ((error = bus_dmamap_load(tag, *mapp, *vaddr, size, NULL, + if ((error = bus_dmamap_load_raw(tag, *mapp, seg, nseg, size, BUS_DMA_NOWAIT)) != 0) goto out; @@ -669,14 +655,11 @@ agp_alloc_dmamem(bus_dma_tag_t tag, size_t size, int flags, return (0); out: switch (level) { - case 3: - bus_dmamap_destroy(tag, *mapp); - /* FALLTHROUGH */ case 2: - bus_dmamem_unmap(tag, *vaddr, size); + bus_dmamap_destroy(tag, *mapp); /* FALLTHROUGH */ case 1: - bus_dmamem_free(tag, seg, *rseg); + bus_dmamem_free(tag, seg, nseg); break; default: break; @@ -687,13 +670,11 @@ out: void agp_free_dmamem(bus_dma_tag_t tag, size_t size, bus_dmamap_t map, - caddr_t vaddr, bus_dma_segment_t *seg, int nseg) + bus_dma_segment_t *seg) { - bus_dmamap_unload(tag, map); bus_dmamap_destroy(tag, map); - bus_dmamem_unmap(tag, vaddr, size); - bus_dmamem_free(tag, seg, nseg); + bus_dmamem_free(tag, seg, 1); } /* Helper functions used in both user and kernel APIs */ |