Prettify to make the code easier to follow.
While here remove the XXX comments I added for lastaddr initialization, now that I can see what's going on.
This commit is contained in:
parent
7a18a3a01f
commit
83c6d7c82f
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: bus_dma.c,v 1.3 2008/05/03 22:07:07 uwe Exp $ */
|
/* $NetBSD: bus_dma.c,v 1.4 2008/05/03 23:45:40 uwe Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005 NONAKA Kimihiro
|
* Copyright (c) 2005 NONAKA Kimihiro
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v 1.3 2008/05/03 22:07:07 uwe Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v 1.4 2008/05/03 23:45:40 uwe Exp $");
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
|
@ -79,47 +79,42 @@ _bus_dmamap_create(bus_dma_tag_t t, bus_size_t size, int nsegments,
|
||||||
bus_dmamap_t map;
|
bus_dmamap_t map;
|
||||||
void *mapstore;
|
void *mapstore;
|
||||||
size_t mapsize;
|
size_t mapsize;
|
||||||
int error;
|
|
||||||
|
|
||||||
DPRINTF(("%s: t = %p, size = %ld, nsegments = %d, maxsegsz = %ld,"
|
DPRINTF(("%s: t = %p, size = %ld, nsegments = %d, maxsegsz = %ld,"
|
||||||
" boundary = %ld, flags = %x\n",
|
" boundary = %ld, flags = %x\n",
|
||||||
__func__, t, size, nsegments, maxsegsz, boundary, flags));
|
__func__, t, size, nsegments, maxsegsz, boundary, flags));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate and initialize the DMA map. The end of the map
|
* Allocate and initialize the DMA map. The end of the map is
|
||||||
* is a variable-sized array of segments, so we allocate enough
|
* a variable-sized array of segments, so we allocate enough
|
||||||
* room for them in one shot.
|
* room for them in one shot. bus_dmamap_t includes one
|
||||||
|
* bus_dma_segment_t already, hence the (nsegments - 1).
|
||||||
*
|
*
|
||||||
* Note we don't preserve the WAITOK or NOWAIT flags. Preservation
|
* Note that we don't preserve WAITOK and NOWAIT flags.
|
||||||
* of ALLOCNOW notifies others that we've reserved these resources,
|
* Preservation of ALLOCNOW notifies others that we've
|
||||||
* and they are not to be freed.
|
* reserved these resources, and they are not to be freed.
|
||||||
*
|
|
||||||
* The bus_dmamap_t includes one bus_dma_segment_t, hence
|
|
||||||
* the (nsegments - 1).
|
|
||||||
*/
|
*/
|
||||||
error = 0;
|
mapsize = sizeof(struct _bus_dmamap)
|
||||||
mapsize = sizeof(struct _bus_dmamap) +
|
+ (sizeof(bus_dma_segment_t) * (nsegments - 1));
|
||||||
(sizeof(bus_dma_segment_t) * (nsegments - 1));
|
mapstore = malloc(mapsize, M_DMAMAP, M_ZERO
|
||||||
if ((mapstore = malloc(mapsize, M_DMAMAP,
|
| (flags & BUS_DMA_NOWAIT) ? M_NOWAIT : M_WAITOK);
|
||||||
(flags & BUS_DMA_NOWAIT) ? M_NOWAIT : M_WAITOK)) == NULL)
|
if (mapstore == NULL)
|
||||||
return (ENOMEM);
|
return ENOMEM;
|
||||||
|
|
||||||
DPRINTF(("%s: dmamp = %p\n", __func__, mapstore));
|
DPRINTF(("%s: dmamp = %p\n", __func__, mapstore));
|
||||||
|
|
||||||
memset(mapstore, 0, mapsize);
|
|
||||||
map = (bus_dmamap_t)mapstore;
|
map = (bus_dmamap_t)mapstore;
|
||||||
map->_dm_size = size;
|
map->_dm_size = size;
|
||||||
map->_dm_segcnt = nsegments;
|
map->_dm_segcnt = nsegments;
|
||||||
map->_dm_maxsegsz = maxsegsz;
|
map->_dm_maxsegsz = maxsegsz;
|
||||||
map->_dm_boundary = boundary;
|
map->_dm_boundary = boundary;
|
||||||
map->_dm_flags = flags & ~(BUS_DMA_WAITOK|BUS_DMA_NOWAIT);
|
map->_dm_flags = flags & ~(BUS_DMA_WAITOK | BUS_DMA_NOWAIT);
|
||||||
|
|
||||||
map->dm_mapsize = 0; /* no valid mappings */
|
map->dm_mapsize = 0; /* no valid mappings */
|
||||||
map->dm_nsegs = 0;
|
map->dm_nsegs = 0;
|
||||||
|
|
||||||
*dmamp = map;
|
*dmamp = map;
|
||||||
|
return 0;
|
||||||
return (0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -171,40 +166,41 @@ _bus_dmamap_load_paddr(bus_dma_tag_t t, bus_dmamap_t map,
|
||||||
DPRINTF(("%s: sgsize = %d\n", __func__, sgsize));
|
DPRINTF(("%s: sgsize = %d\n", __func__, sgsize));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Insert chunk into a segment, coalescing with
|
* Insert chunk coalescing with previous segment if possible.
|
||||||
* previous segment if possible.
|
|
||||||
*/
|
*/
|
||||||
if (first) {
|
if (first) {
|
||||||
/* first segment */
|
|
||||||
DPRINTF(("%s: first\n", __func__));
|
DPRINTF(("%s: first\n", __func__));
|
||||||
|
first = 0;
|
||||||
|
|
||||||
segs[nseg].ds_addr = SH3_PHYS_TO_P2SEG(paddr);
|
segs[nseg].ds_addr = SH3_PHYS_TO_P2SEG(paddr);
|
||||||
segs[nseg].ds_len = sgsize;
|
segs[nseg].ds_len = sgsize;
|
||||||
segs[nseg]._ds_vaddr = vaddr;
|
segs[nseg]._ds_vaddr = vaddr;
|
||||||
first = 0;
|
}
|
||||||
} else {
|
else if ((paddr == lastaddr)
|
||||||
if ((paddr == lastaddr)
|
|
||||||
&& (segs[nseg].ds_len + sgsize <= map->_dm_maxsegsz)
|
&& (segs[nseg].ds_len + sgsize <= map->_dm_maxsegsz)
|
||||||
&& (map->_dm_boundary == 0 ||
|
&& (map->_dm_boundary == 0 ||
|
||||||
(segs[nseg].ds_addr & bmask) == (paddr & bmask))) {
|
(segs[nseg].ds_addr & bmask) == (paddr & bmask)))
|
||||||
/* coalesce */
|
{
|
||||||
DPRINTF(("%s: coalesce\n", __func__));
|
DPRINTF(("%s: coalesce\n", __func__));
|
||||||
segs[nseg].ds_len += sgsize;
|
|
||||||
} else {
|
segs[nseg].ds_len += sgsize;
|
||||||
if (++nseg >= map->_dm_segcnt) {
|
}
|
||||||
break;
|
else {
|
||||||
}
|
DPRINTF(("%s: new\n", __func__));
|
||||||
/* new segment */
|
|
||||||
DPRINTF(("%s: new\n", __func__));
|
++nseg;
|
||||||
segs[nseg].ds_addr = SH3_PHYS_TO_P2SEG(paddr);
|
if (nseg >= map->_dm_segcnt)
|
||||||
segs[nseg].ds_len = sgsize;
|
break;
|
||||||
segs[nseg]._ds_vaddr = vaddr;
|
|
||||||
}
|
segs[nseg].ds_addr = SH3_PHYS_TO_P2SEG(paddr);
|
||||||
|
segs[nseg].ds_len = sgsize;
|
||||||
|
segs[nseg]._ds_vaddr = vaddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastaddr = paddr + sgsize;
|
|
||||||
paddr += sgsize;
|
paddr += sgsize;
|
||||||
vaddr += sgsize;
|
vaddr += sgsize;
|
||||||
size -= sgsize;
|
size -= sgsize;
|
||||||
|
lastaddr = paddr;
|
||||||
|
|
||||||
DPRINTF(("%s: lastaddr = 0x%08lx, paddr = 0x%08lx,"
|
DPRINTF(("%s: lastaddr = 0x%08lx, paddr = 0x%08lx,"
|
||||||
" vaddr = 0x%08lx, size = %d\n",
|
" vaddr = 0x%08lx, size = %d\n",
|
||||||
|
@ -216,13 +212,10 @@ _bus_dmamap_load_paddr(bus_dma_tag_t t, bus_dmamap_t map,
|
||||||
*segp = nseg;
|
*segp = nseg;
|
||||||
*lastaddrp = lastaddr;
|
*lastaddrp = lastaddr;
|
||||||
|
|
||||||
/*
|
|
||||||
* Did we fit?
|
|
||||||
*/
|
|
||||||
if (size != 0) {
|
if (size != 0) {
|
||||||
/*
|
/*
|
||||||
* If there is a chained window, we will automatically
|
* It didn't fit. If there is a chained window, we
|
||||||
* fall back to it.
|
* will automatically fall back to it.
|
||||||
*/
|
*/
|
||||||
return (EFBIG); /* XXX better return value here? */
|
return (EFBIG); /* XXX better return value here? */
|
||||||
}
|
}
|
||||||
|
@ -252,34 +245,32 @@ _bus_bus_dmamap_load_buffer(bus_dma_tag_t t, bus_dmamap_t map, void *buf,
|
||||||
else
|
else
|
||||||
pmap = pmap_kernel();
|
pmap = pmap_kernel();
|
||||||
|
|
||||||
*segp = 0;
|
|
||||||
first = 1;
|
first = 1;
|
||||||
len = buflen;
|
lastaddr = 0;
|
||||||
lastaddr = 0; /* XXX: uwe: gag gcc4, but this is WRONG!!! */
|
|
||||||
while (len > 0) {
|
|
||||||
/*
|
|
||||||
* Get the physical address for this segment.
|
|
||||||
*/
|
|
||||||
(void)pmap_extract(pmap, vaddr, &curaddr);
|
|
||||||
|
|
||||||
/*
|
len = buflen;
|
||||||
* Compute the segment size, and adjust counts.
|
while (len > 0) {
|
||||||
*/
|
bool mapped;
|
||||||
sgsize = PAGE_SIZE - ((u_long)vaddr & PGOFSET);
|
|
||||||
|
mapped = pmap_extract(pmap, vaddr, &curaddr);
|
||||||
|
if (!mapped)
|
||||||
|
return EFAULT;
|
||||||
|
|
||||||
|
sgsize = PAGE_SIZE - (vaddr & PGOFSET);
|
||||||
if (len < sgsize)
|
if (len < sgsize)
|
||||||
sgsize = len;
|
sgsize = len;
|
||||||
|
|
||||||
error = _bus_dmamap_load_paddr(t, map, curaddr, vaddr, sgsize,
|
error = _bus_dmamap_load_paddr(t, map, curaddr, vaddr, sgsize,
|
||||||
segp, &lastaddr, first);
|
segp, &lastaddr, first);
|
||||||
if (error)
|
if (error)
|
||||||
return (error);
|
return error;
|
||||||
|
|
||||||
vaddr += sgsize;
|
vaddr += sgsize;
|
||||||
len -= sgsize;
|
len -= sgsize;
|
||||||
first = 0;
|
first = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -299,26 +290,25 @@ _bus_dmamap_load(bus_dma_tag_t t, bus_dmamap_t map, void *buf,
|
||||||
" p = %p, flags = %x\n",
|
" p = %p, flags = %x\n",
|
||||||
__func__, t, map, buf, buflen, p, flags));
|
__func__, t, map, buf, buflen, p, flags));
|
||||||
|
|
||||||
/*
|
/* make sure that on error condition we return "no valid mappings" */
|
||||||
* Make sure on error condition we return "no valid mappings."
|
|
||||||
*/
|
|
||||||
map->dm_mapsize = 0;
|
map->dm_mapsize = 0;
|
||||||
map->dm_nsegs = 0;
|
map->dm_nsegs = 0;
|
||||||
|
|
||||||
if (buflen > map->_dm_size)
|
if (buflen > map->_dm_size)
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
|
|
||||||
lastaddr = 0; /* XXX: uwe: gag gcc4, but this is WRONG!!! */
|
seg = 0;
|
||||||
|
|
||||||
if ((addr >= SH3_P1SEG_BASE) && (addr + buflen <= SH3_P2SEG_END)) {
|
if (SH3_P1SEG_BASE <= addr && addr + buflen <= SH3_P2SEG_END) {
|
||||||
bus_addr_t curaddr;
|
bus_addr_t curaddr;
|
||||||
bus_size_t sgsize;
|
bus_size_t sgsize;
|
||||||
bus_size_t len = buflen;
|
bus_size_t len = buflen;
|
||||||
|
|
||||||
DPRINTF(("%s: P[12]SEG (0x%08lx)\n", __func__, addr));
|
DPRINTF(("%s: P[12]SEG (0x%08lx)\n", __func__, addr));
|
||||||
|
|
||||||
seg = 0;
|
|
||||||
first = 1;
|
first = 1;
|
||||||
|
lastaddr = 0;
|
||||||
|
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
curaddr = SH3_P1SEG_TO_PHYS(addr);
|
curaddr = SH3_P1SEG_TO_PHYS(addr);
|
||||||
|
|
||||||
|
@ -326,30 +316,28 @@ _bus_dmamap_load(bus_dma_tag_t t, bus_dmamap_t map, void *buf,
|
||||||
if (len < sgsize)
|
if (len < sgsize)
|
||||||
sgsize = len;
|
sgsize = len;
|
||||||
|
|
||||||
error = _bus_dmamap_load_paddr(t, map, curaddr, addr,
|
error = _bus_dmamap_load_paddr(t, map,
|
||||||
sgsize, &seg, &lastaddr, first);
|
curaddr, addr, sgsize,
|
||||||
|
&seg, &lastaddr, first);
|
||||||
if (error)
|
if (error)
|
||||||
return (error);
|
break;
|
||||||
|
|
||||||
addr += sgsize;
|
addr += sgsize;
|
||||||
len -= sgsize;
|
len -= sgsize;
|
||||||
first = 0;
|
first = 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
map->dm_nsegs = seg + 1;
|
else {
|
||||||
map->dm_mapsize = buflen;
|
error = _bus_bus_dmamap_load_buffer(t, map, buf, buflen,
|
||||||
return (0);
|
p, flags, &seg);
|
||||||
}
|
}
|
||||||
|
|
||||||
error = _bus_bus_dmamap_load_buffer(t, map, buf, buflen, p, flags,
|
if (error)
|
||||||
&seg);
|
return (error);
|
||||||
if (error == 0) {
|
|
||||||
map->dm_nsegs = seg + 1;
|
|
||||||
map->dm_mapsize = buflen;
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (error);
|
map->dm_nsegs = seg + 1;
|
||||||
|
map->dm_mapsize = buflen;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -368,9 +356,7 @@ _bus_dmamap_load_mbuf(bus_dma_tag_t t, bus_dmamap_t map, struct mbuf *m0,
|
||||||
DPRINTF(("%s: t = %p, map = %p, m0 = %p, flags = %x\n",
|
DPRINTF(("%s: t = %p, map = %p, m0 = %p, flags = %x\n",
|
||||||
__func__, t, map, m0, flags));
|
__func__, t, map, m0, flags));
|
||||||
|
|
||||||
/*
|
/* make sure that on error condition we return "no valid mappings" */
|
||||||
* Make sure on error condition we return "no valid mappings."
|
|
||||||
*/
|
|
||||||
map->dm_nsegs = 0;
|
map->dm_nsegs = 0;
|
||||||
map->dm_mapsize = 0;
|
map->dm_mapsize = 0;
|
||||||
|
|
||||||
|
@ -384,9 +370,9 @@ _bus_dmamap_load_mbuf(bus_dma_tag_t t, bus_dmamap_t map, struct mbuf *m0,
|
||||||
|
|
||||||
seg = 0;
|
seg = 0;
|
||||||
first = 1;
|
first = 1;
|
||||||
error = 0;
|
lastaddr = 0;
|
||||||
lastaddr = 0; /* XXX: uwe: gag gcc4, but this is WRONG!!! */
|
|
||||||
for (m = m0; m != NULL && error == 0; m = m->m_next) {
|
for (m = m0; m != NULL; m = m->m_next) {
|
||||||
paddr_t paddr;
|
paddr_t paddr;
|
||||||
vaddr_t vaddr;
|
vaddr_t vaddr;
|
||||||
int size;
|
int size;
|
||||||
|
@ -398,17 +384,15 @@ _bus_dmamap_load_mbuf(bus_dma_tag_t t, bus_dmamap_t map, struct mbuf *m0,
|
||||||
paddr = (paddr_t)(PMAP_UNMAP_POOLPAGE(vaddr));
|
paddr = (paddr_t)(PMAP_UNMAP_POOLPAGE(vaddr));
|
||||||
size = m->m_len;
|
size = m->m_len;
|
||||||
error = _bus_dmamap_load_paddr(t, map, paddr, vaddr, size,
|
error = _bus_dmamap_load_paddr(t, map, paddr, vaddr, size,
|
||||||
&seg, &lastaddr, first);
|
&seg, &lastaddr, first);
|
||||||
|
if (error)
|
||||||
|
return error;
|
||||||
first = 0;
|
first = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error == 0) {
|
map->dm_nsegs = seg + 1;
|
||||||
map->dm_nsegs = seg + 1;
|
map->dm_mapsize = m0->m_pkthdr.len;
|
||||||
map->dm_mapsize = m0->m_pkthdr.len;
|
return 0;
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -624,8 +608,9 @@ _bus_dmamem_free(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs)
|
||||||
segs[curseg].ds_addr, segs[curseg].ds_len));
|
segs[curseg].ds_addr, segs[curseg].ds_len));
|
||||||
|
|
||||||
for (addr = segs[curseg].ds_addr;
|
for (addr = segs[curseg].ds_addr;
|
||||||
addr < (segs[curseg].ds_addr + segs[curseg].ds_len);
|
addr < (segs[curseg].ds_addr + segs[curseg].ds_len);
|
||||||
addr += PAGE_SIZE) {
|
addr += PAGE_SIZE)
|
||||||
|
{
|
||||||
m = PHYS_TO_VM_PAGE(addr);
|
m = PHYS_TO_VM_PAGE(addr);
|
||||||
DPRINTF(("%s: m = %p\n", __func__, m));
|
DPRINTF(("%s: m = %p\n", __func__, m));
|
||||||
TAILQ_INSERT_TAIL(&mlist, m, pageq);
|
TAILQ_INSERT_TAIL(&mlist, m, pageq);
|
||||||
|
@ -640,7 +625,6 @@ int
|
||||||
_bus_dmamem_map(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs,
|
_bus_dmamem_map(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs,
|
||||||
size_t size, void **kvap, int flags)
|
size_t size, void **kvap, int flags)
|
||||||
{
|
{
|
||||||
const uvm_flag_t kmflags = (flags & BUS_DMA_NOWAIT) ? UVM_KMF_NOWAIT:0;
|
|
||||||
vaddr_t va;
|
vaddr_t va;
|
||||||
bus_addr_t addr;
|
bus_addr_t addr;
|
||||||
int curseg;
|
int curseg;
|
||||||
|
@ -650,28 +634,29 @@ _bus_dmamem_map(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs,
|
||||||
__func__, t, segs, nsegs, size, kvap, flags));
|
__func__, t, segs, nsegs, size, kvap, flags));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we're only mapping 1 segment, use P2SEG, to avoid
|
* If we're mapping only a single segment, use direct-mapped
|
||||||
* TLB thrashing.
|
* va, to avoid thrashing the TLB.
|
||||||
*/
|
*/
|
||||||
if (nsegs == 1) {
|
if (nsegs == 1) {
|
||||||
if (flags & BUS_DMA_COHERENT) {
|
if (flags & BUS_DMA_COHERENT)
|
||||||
*kvap = (void *)SH3_PHYS_TO_P2SEG(segs[0].ds_addr);
|
*kvap = (void *)SH3_PHYS_TO_P2SEG(segs[0].ds_addr);
|
||||||
} else {
|
else
|
||||||
*kvap = (void *)SH3_PHYS_TO_P1SEG(segs[0].ds_addr);
|
*kvap = (void *)SH3_PHYS_TO_P1SEG(segs[0].ds_addr);
|
||||||
}
|
|
||||||
DPRINTF(("%s: addr = 0x%08lx, kva = %p\n",
|
DPRINTF(("%s: addr = 0x%08lx, kva = %p\n",
|
||||||
__func__, segs[0].ds_addr, *kvap));
|
__func__, segs[0].ds_addr, *kvap));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Always round the size. */
|
/* Always round the size. */
|
||||||
size = round_page(size);
|
size = round_page(size);
|
||||||
|
|
||||||
va = uvm_km_alloc(kernel_map, size, 0, UVM_KMF_VAONLY | kmflags);
|
va = uvm_km_alloc(kernel_map, size, 0, UVM_KMF_VAONLY
|
||||||
|
| (flags & BUS_DMA_NOWAIT) ? UVM_KMF_NOWAIT : 0);
|
||||||
if (va == 0)
|
if (va == 0)
|
||||||
return (ENOMEM);
|
return (ENOMEM);
|
||||||
|
|
||||||
*kvap = (void *)va;
|
|
||||||
for (curseg = 0; curseg < nsegs; curseg++) {
|
for (curseg = 0; curseg < nsegs; curseg++) {
|
||||||
DPRINTF(("%s: segs[%d]: ds_addr = 0x%08lx, ds_len = %ld\n",
|
DPRINTF(("%s: segs[%d]: ds_addr = 0x%08lx, ds_len = %ld\n",
|
||||||
__func__, curseg,
|
__func__, curseg,
|
||||||
|
@ -679,42 +664,42 @@ _bus_dmamem_map(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs,
|
||||||
|
|
||||||
for (addr = segs[curseg].ds_addr;
|
for (addr = segs[curseg].ds_addr;
|
||||||
addr < segs[curseg].ds_addr + segs[curseg].ds_len;
|
addr < segs[curseg].ds_addr + segs[curseg].ds_len;
|
||||||
addr += PAGE_SIZE, va += PAGE_SIZE, size -= PAGE_SIZE) {
|
addr += PAGE_SIZE, va += PAGE_SIZE, size -= PAGE_SIZE)
|
||||||
if (size == 0)
|
{
|
||||||
|
if (__predict_false(size == 0))
|
||||||
panic("_bus_dmamem_map: size botch");
|
panic("_bus_dmamem_map: size botch");
|
||||||
|
|
||||||
pmap_kenter_pa(va, addr,
|
pmap_kenter_pa(va, addr,
|
||||||
VM_PROT_READ | VM_PROT_WRITE);
|
VM_PROT_READ | VM_PROT_WRITE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pmap_update(pmap_kernel());
|
|
||||||
|
|
||||||
|
pmap_update(pmap_kernel());
|
||||||
|
*kvap = (void *)va;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_bus_dmamem_unmap(bus_dma_tag_t t, void *kva, size_t size)
|
_bus_dmamem_unmap(bus_dma_tag_t t, void *kva, size_t size)
|
||||||
{
|
{
|
||||||
|
vaddr_t vaddr = (vaddr_t)kva;
|
||||||
|
|
||||||
DPRINTF(("%s: t = %p, kva = %p, size = %d\n",
|
DPRINTF(("%s: t = %p, kva = %p, size = %d\n",
|
||||||
__func__, t, kva, size));
|
__func__, t, kva, size));
|
||||||
|
|
||||||
#ifdef DIAGNOSTIC
|
#ifdef DIAGNOSTIC
|
||||||
if ((u_long)kva & PAGE_MASK)
|
if (vaddr & PAGE_MASK)
|
||||||
panic("_bus_dmamem_unmap");
|
panic("_bus_dmamem_unmap");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/* nothing to do if we mapped it via P1SEG or P2SEG */
|
||||||
* Nothing to do if we mapped it with P[12]SEG.
|
if (SH3_P1SEG_BASE <= vaddr && vaddr <= SH3_P2SEG_END)
|
||||||
*/
|
|
||||||
if ((kva >= (void *)SH3_P1SEG_BASE)
|
|
||||||
&& (kva <= (void *)SH3_P2SEG_END)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
size = round_page(size);
|
size = round_page(size);
|
||||||
pmap_kremove((vaddr_t)kva, size);
|
pmap_kremove(vaddr, size);
|
||||||
pmap_update(pmap_kernel());
|
pmap_update(pmap_kernel());
|
||||||
uvm_km_free(kernel_map, (vaddr_t)kva, size, UVM_KMF_VAONLY);
|
uvm_km_free(kernel_map, vaddr, size, UVM_KMF_VAONLY);
|
||||||
}
|
}
|
||||||
|
|
||||||
paddr_t
|
paddr_t
|
||||||
|
|
Loading…
Reference in New Issue