Module Name: src
Committed By: riastradh
Date: Wed Jun 11 17:15:18 UTC 2014
Modified Files:
src/sys/dev/pci: agp_i810.c
Log Message:
Fix various mistakes in yesterday's commit.
- Set mem->am_nseg, particularly before trying to use it.
- Avoid error-prone local copies in agp_i810_bind_memory_main.
- Omit missing DMA unload/free in agp_i810_unbind_memory.
To generate a diff of this commit:
cvs rdiff -u -r1.93 -r1.94 src/sys/dev/pci/agp_i810.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/pci/agp_i810.c
diff -u src/sys/dev/pci/agp_i810.c:1.93 src/sys/dev/pci/agp_i810.c:1.94
--- src/sys/dev/pci/agp_i810.c:1.93 Wed Jun 11 17:02:09 2014
+++ src/sys/dev/pci/agp_i810.c Wed Jun 11 17:15:18 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: agp_i810.c,v 1.93 2014/06/11 17:02:09 riastradh Exp $ */
+/* $NetBSD: agp_i810.c,v 1.94 2014/06/11 17:15:18 riastradh Exp $ */
/*-
* Copyright (c) 2000 Doug Rabson
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: agp_i810.c,v 1.93 2014/06/11 17:02:09 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: agp_i810.c,v 1.94 2014/06/11 17:15:18 riastradh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -1266,8 +1266,7 @@ agp_i810_bind_memory_main(struct agp_sof
off_t offset)
{
struct agp_i810_softc *const isc = sc->as_chipc;
- bus_dma_segment_t *segs;
- int nseg_alloc, nseg;
+ int nseg;
uint32_t i, j;
unsigned seg;
bus_addr_t addr;
@@ -1286,29 +1285,30 @@ agp_i810_bind_memory_main(struct agp_sof
return EINVAL;
/* Allocate an array of DMA segments. */
- nseg_alloc = (mem->am_size >> AGP_PAGE_SHIFT);
- if (nseg_alloc > (SIZE_MAX / sizeof(*segs))) {
+ nseg = (mem->am_size >> AGP_PAGE_SHIFT);
+ if (nseg > (SIZE_MAX / sizeof(*mem->am_dmaseg))) {
error = ENOMEM;
goto fail0;
}
- segs = malloc(nseg_alloc * sizeof(*segs), M_AGP, M_WAITOK);
+ mem->am_dmaseg = malloc(nseg*sizeof(*mem->am_dmaseg), M_AGP, M_WAITOK);
/* Allocate DMA-safe physical segments. */
error = bus_dmamem_alloc(sc->as_dmat, mem->am_size, PAGE_SIZE,
- 0, segs, nseg_alloc, &nseg, BUS_DMA_WAITOK);
+ 0, mem->am_dmaseg, nseg, &mem->am_nseg, BUS_DMA_WAITOK);
if (error)
goto fail1;
- KASSERT(nseg <= nseg_alloc);
+ KASSERT(mem->am_nseg <= nseg);
/* Shrink the array of DMA segments if we can. */
- if (nseg < nseg_alloc) {
- segs = realloc(segs, nseg, M_AGP, M_WAITOK);
- nseg_alloc = nseg;
+ if (mem->am_nseg < nseg) {
+ mem->am_dmaseg = realloc(mem->am_dmaseg, mem->am_nseg, M_AGP,
+ M_WAITOK);
+ nseg = mem->am_nseg;
}
/* Load the DMA map. */
error = bus_dmamap_load_raw(sc->as_dmat, mem->am_dmamap,
- segs, mem->am_nseg, mem->am_size, BUS_DMA_WAITOK);
+ mem->am_dmaseg, mem->am_nseg, mem->am_size, BUS_DMA_WAITOK);
if (error)
goto fail2;
@@ -1334,15 +1334,16 @@ agp_i810_bind_memory_main(struct agp_sof
}
/* Success! */
- mem->am_dmaseg = segs;
mem->am_offset = offset;
return 0;
fail3: for (j = 0; j < i; j += AGP_PAGE_SIZE)
(void)agp_i810_unbind_page(sc, offset + j);
bus_dmamap_unload(sc->as_dmat, mem->am_dmamap);
-fail2: bus_dmamem_free(sc->as_dmat, segs, nseg_alloc);
-fail1: free(segs, M_AGP);
+fail2: bus_dmamem_free(sc->as_dmat, mem->am_dmaseg, mem->am_nseg);
+fail1: free(mem->am_dmaseg, M_AGP);
+ mem->am_dmaseg = NULL;
+ mem->am_nseg = 0;
fail0: KASSERT(error);
return error;
}
@@ -1412,15 +1413,23 @@ agp_i810_unbind_memory(struct agp_softc
switch (mem->am_type) {
case AGP_I810_MEMTYPE_MAIN:
- case AGP_I810_MEMTYPE_HWCURSOR:
for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE)
(void)agp_i810_unbind_page(sc, mem->am_offset + i);
+ bus_dmamap_unload(sc->as_dmat, mem->am_dmamap);
+ bus_dmamem_free(sc->as_dmat, mem->am_dmaseg, mem->am_nseg);
+ free(mem->am_dmaseg, M_AGP);
+ mem->am_offset = 0;
break;
case AGP_I810_MEMTYPE_DCACHE:
KASSERT(isc->chiptype == CHIP_I810);
for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE)
(void)agp_i810_write_gtt_entry(isc, i, 0);
break;
+ case AGP_I810_MEMTYPE_HWCURSOR:
+ for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE)
+ (void)agp_i810_unbind_page(sc, mem->am_offset + i);
+ mem->am_offset = 0;
+ break;
default:
panic("invalid agp i810 memory type: %d", mem->am_type);
}