summaryrefslogtreecommitdiff
path: root/sys/dev/pci/agp.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/pci/agp.c')
-rw-r--r--sys/dev/pci/agp.c81
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 */