summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/pci/agp.c81
-rw-r--r--sys/dev/pci/agp_amd.c22
-rw-r--r--sys/dev/pci/agp_i810.c39
-rw-r--r--sys/dev/pci/agpvar.h9
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);