diff options
-rw-r--r-- | sys/dev/pci/agp.c | 81 | ||||
-rw-r--r-- | sys/dev/pci/agp_amd.c | 22 | ||||
-rw-r--r-- | sys/dev/pci/agp_i810.c | 39 | ||||
-rw-r--r-- | sys/dev/pci/agpvar.h | 9 |
4 files changed, 71 insertions, 80 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 */ diff --git a/sys/dev/pci/agp_amd.c b/sys/dev/pci/agp_amd.c index 714213f7b00..e33573e789e 100644 --- a/sys/dev/pci/agp_amd.c +++ b/sys/dev/pci/agp_amd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: agp_amd.c,v 1.9 2008/11/09 15:11:19 oga Exp $ */ +/* $OpenBSD: agp_amd.c,v 1.10 2009/04/20 01:28:45 oga Exp $ */ /* $NetBSD: agp_amd.c,v 1.6 2001/10/06 02:48:50 thorpej Exp $ */ /*- @@ -111,25 +111,30 @@ agp_amd_alloc_gatt(bus_dma_tag_t dmat, bus_size_t apsize) gatt = malloc(sizeof(struct agp_amd_gatt), M_AGP, M_NOWAIT); if (!gatt) return (0); + gatt->ag_size = AGP_PAGE_SIZE + entries * sizeof(u_int32_t); - if (agp_alloc_dmamem(dmat, - AGP_PAGE_SIZE + entries * sizeof(u_int32_t), 0, - &gatt->ag_dmamap, &vdir, &gatt->ag_pdir, - &gatt->ag_dmaseg, 1, &gatt->ag_nseg) != 0) { + if (agp_alloc_dmamem(dmat, gatt->ag_size, &gatt->ag_dmamap, + &gatt->ag_pdir, &gatt->ag_dmaseg) != 0) { printf("failed to allocate GATT\n"); free(gatt, M_AGP); return (NULL); } + if (bus_dmamem_map(dmat, &gatt->ag_dmaseg, 1, gatt->ag_size, + &vdir, BUS_DMA_NOWAIT) != 0) { + printf("failed to map GATT\n"); + agp_free_dmamem(dmat, gatt->ag_size, gatt->ag_dmamap, + &gatt->ag_dmaseg); + free(gatt, M_AGP); + return (NULL); + } + gatt->ag_vdir = (u_int32_t *)vdir; gatt->ag_entries = entries; gatt->ag_virtual = (u_int32_t *)(vdir + AGP_PAGE_SIZE); gatt->ag_physical = gatt->ag_pdir + AGP_PAGE_SIZE; gatt->ag_size = AGP_PAGE_SIZE + entries * sizeof(u_int32_t); - memset(gatt->ag_vdir, 0, AGP_PAGE_SIZE); - memset(gatt->ag_virtual, 0, entries * sizeof(u_int32_t)); - /* * Map the pages of the GATT into the page directory. */ @@ -151,6 +156,7 @@ agp_amd_alloc_gatt(bus_dma_tag_t dmat, bus_size_t apsize) void agp_amd_free_gatt(bus_dma_tag_t dmat, struct agp_amd_gatt *gatt) { + bus_dmamem_unmap(dmat, gatt->ag_virtual, gatt->ag_size); agp_free_dmamem(dmat, gatt->ag_size, gatt->ag_dmamap, (caddr_t)gatt->ag_virtual, &gatt->ag_dmaseg, gatt->ag_nseg); diff --git a/sys/dev/pci/agp_i810.c b/sys/dev/pci/agp_i810.c index 021acdff2c7..638c20eaca7 100644 --- a/sys/dev/pci/agp_i810.c +++ b/sys/dev/pci/agp_i810.c @@ -1,4 +1,4 @@ -/* $OpenBSD: agp_i810.c,v 1.47 2009/04/15 03:09:20 oga Exp $ */ +/* $OpenBSD: agp_i810.c,v 1.48 2009/04/20 01:28:45 oga Exp $ */ /*- * Copyright (c) 2000 Doug Rabson @@ -251,7 +251,7 @@ agp_i810_attach(struct device *parent, struct device *self, void *aux) } } - gatt = malloc(sizeof(*gatt), M_AGP, M_NOWAIT); + gatt = malloc(sizeof(*gatt), M_AGP, M_NOWAIT | M_ZERO); if (gatt == NULL) { printf("can't alloc gatt\n"); goto out; @@ -271,7 +271,6 @@ agp_i810_attach(struct device *parent, struct device *self, void *aux) } if (isc->chiptype == CHIP_I810) { - int dummyseg; /* Some i810s have on-chip memory called dcache */ if (READ1(AGP_I810_DRT) & AGP_I810_DRT_POPULATED) isc->dcache_size = 4 * 1024 * 1024; @@ -279,14 +278,15 @@ agp_i810_attach(struct device *parent, struct device *self, void *aux) isc->dcache_size = 0; /* According to the specs the gatt on the i810 must be 64k */ - if (agp_alloc_dmamem(pa->pa_dmat, 64 * 1024, - 0, &gatt->ag_dmamap, (caddr_t *)&gatt->ag_virtual, - &gatt->ag_physical, &gatt->ag_dmaseg, 1, &dummyseg) != 0) { + if (agp_alloc_dmamem(pa->pa_dmat, 64 * 1024, &gatt->ag_dmamap, + &gatt->ag_physical, &gatt->ag_dmaseg) != 0) { goto out; } - gatt->ag_size = gatt->ag_entries * sizeof(u_int32_t); - memset(gatt->ag_virtual, 0, gatt->ag_size); + + if (bus_dmamem_map(pa->pa_dmat, &gatt->ag_dmaseg, 1, 64 * 1024, + (caddr_t *)&gatt->ag_virtual, BUS_DMA_NOWAIT) != 0) + goto out; agp_flush_cache(); /* Install the GATT. */ @@ -461,7 +461,11 @@ agp_i810_attach(struct device *parent, struct device *self, void *aux) gmaddr, memtype, &isc->dev); return; out: + if (isc->gatt) + if (isc->gatt->ag_size != 0) + agp_free_dmamem(pa->pa_dmat, gatt->ag_size, + gatt->ag_dmamap, &gatt->ag_dmaseg); free(isc->gatt, M_AGP); if (isc->gtt_map != NULL) vga_pci_bar_unmap(isc->gtt_map); @@ -491,8 +495,10 @@ agp_i810_detach(struct agp_softc *sc) } if (sc->chiptype == CHIP_I810) { + bus_dmamem_unmap(pa->pa_dmat, isc->gatt->ag_virtual, + gatt->ag_size); agp_free_dmamem(sc->sc_dmat, gatt->ag_size, gatt->ag_dmamap, - (void *)gatt->ag_virtual, &gatt->ag_dmaseg, 1); + &gatt->ag_dmaseg); } free(sc->gatt, M_AGP); @@ -613,17 +619,16 @@ agp_i810_alloc_memory(void *softc, int type, vsize_t size) * Allocate and wire down the pages now so that we can * get their physical address. */ - mem->am_dmaseg = malloc(sizeof *mem->am_dmaseg, M_AGP, - M_WAITOK); - if ((error = agp_alloc_dmamem(sc->sc_dmat, size, 0, - &mem->am_dmamap, &mem->am_virtual, &mem->am_physical, - mem->am_dmaseg, 1, &mem->am_nseg)) != 0) { - free(mem->am_dmaseg, M_AGP); + if ((mem->am_dmaseg = malloc(sizeof (*mem->am_dmaseg), M_AGP, + M_WAITOK | M_CANFAIL)) == NULL) + return (NULL); + + if ((error = agp_alloc_dmamem(sc->sc_dmat, size, + &mem->am_dmamap, &mem->am_physical, mem->am_dmaseg)) != 0) { free(mem, M_AGP); printf("agp: agp_alloc_dmamem(%d)\n", error); return (NULL); } - memset(mem->am_virtual, 0, size); } else if (type != 1) { if ((error = bus_dmamap_create(sc->sc_dmat, size, size / PAGE_SIZE + 1, size, 0, BUS_DMA_NOWAIT, @@ -651,7 +656,7 @@ agp_i810_free_memory(void *softc, struct agp_memory *mem) if (mem->am_type == 2) { agp_free_dmamem(sc->sc_dmat, mem->am_size, mem->am_dmamap, - mem->am_virtual, mem->am_dmaseg, mem->am_nseg); + mem->am_dmaseg); free(mem->am_dmaseg, M_AGP); } else if (mem->am_type != 1) { bus_dmamap_destroy(sc->sc_dmat, mem->am_dmamap); diff --git a/sys/dev/pci/agpvar.h b/sys/dev/pci/agpvar.h index bd14c5ee33d..4e810649b23 100644 --- a/sys/dev/pci/agpvar.h +++ b/sys/dev/pci/agpvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: agpvar.h,v 1.15 2008/11/09 15:11:19 oga Exp $ */ +/* $OpenBSD: agpvar.h,v 1.16 2009/04/20 01:28:45 oga Exp $ */ /* $NetBSD: agpvar.h,v 1.4 2001/10/01 21:54:48 fvdl Exp $ */ /*- @@ -74,7 +74,6 @@ struct agp_memory { off_t am_offset; /* page offset if bound */ int am_is_bound; /* non-zero if bound */ bus_addr_t am_physical; - caddr_t am_virtual; bus_dmamap_t am_dmamap; int am_nseg; bus_dma_segment_t *am_dmaseg; @@ -162,10 +161,10 @@ void agp_flush_cache(void); int agp_generic_bind_memory(struct agp_softc *, struct agp_memory *, off_t); int agp_generic_unbind_memory(struct agp_softc *, struct agp_memory *); -int agp_alloc_dmamem(bus_dma_tag_t, size_t, int, bus_dmamap_t *, - caddr_t *, bus_addr_t *, bus_dma_segment_t *, int, int *); +int agp_alloc_dmamem(bus_dma_tag_t, size_t, bus_dmamap_t *, + bus_addr_t *, bus_dma_segment_t *); void agp_free_dmamem(bus_dma_tag_t, size_t, bus_dmamap_t, - caddr_t, bus_dma_segment_t *, int nseg) ; + bus_dma_segment_t *); int agpdev_print(void *, const char *); int agpbus_probe(struct agp_attach_args *aa); |