PERFORCE change 122942 for review
Oleksandr Tymoshenko
gonzo at FreeBSD.org
Thu Jul 5 12:49:21 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=122942
Change 122942 by gonzo at gonzo_jeeves on 2007/07/05 12:48:54
o Set _wsize to whole physical memory region (it's how things are in
NetBSD)
o Allocate map region with M_ZERO
o Borrow bus_dmamap_load implementation from -arm tree
o Remove panic from _bus_dmamap_unload which is a noop now
Tested with: ADM5120 switch engine
Affected files ...
.. //depot/projects/mips2/src/sys/mips/mips/busdma_machdep.c#4 edit
Differences ...
==== //depot/projects/mips2/src/sys/mips/mips/busdma_machdep.c#4 (text+ko) ====
@@ -111,9 +111,6 @@
vm_offset_t _wsize;
};
-/* XXXMIPS: waith with DMA till real hardware will be used */
-#define NO_DMA
-
#define DMAMAP_LINEAR 0x1
#define DMAMAP_MBUF 0x2
#define DMAMAP_UIO 0x4
@@ -151,8 +148,6 @@
SYSINIT(busdma, SI_SUB_VM, SI_ORDER_ANY, mips_dmamap_freelist_init, NULL);
-
-
/*
* Check to see if the specified page is in an allowed DMA range.
*/
@@ -215,7 +210,7 @@
TAILQ_REMOVE(&dmamap_freelist, map, freelist);
mtx_unlock(&busdma_mtx);
if (!map) {
- map = malloc(sizeof(*map), M_DEVBUF, M_NOWAIT);
+ map = malloc(sizeof(*map), M_DEVBUF, M_NOWAIT | M_ZERO);
if (map)
map->flags = DMAMAP_ALLOCATED;
} else
@@ -278,7 +273,8 @@
newtag->map_count = 0;
newtag->_wbase = 0;
newtag->_physbase = 0;
- newtag->_wsize = 64 * 1024 * 1024;
+ /* XXXMIPS: Should we limit window size to amount of physical memory */
+ newtag->_wsize = MIPS_KSEG1_START - MIPS_KSEG0_START;
if (lockfunc != NULL) {
newtag->lockfunc = lockfunc;
newtag->lockfuncarg = lockfuncarg;
@@ -449,11 +445,6 @@
return (ENOMEM);
}
if (flags & BUS_DMA_COHERENT) {
- /* XXXMIPS: check this later
- void *tmpaddr = arm_remap_nocache(
- (void *)((vm_offset_t)*vaddr &~ PAGE_MASK),
- dmat->maxsize + ((vm_offset_t)*vaddr & PAGE_MASK));
- */
void *tmpaddr = (void *)*vaddr;
if (tmpaddr) {
@@ -461,7 +452,7 @@
((vm_offset_t)*vaddr & PAGE_MASK));
newmap->origbuffer = *vaddr;
newmap->allocbuffer = tmpaddr;
- mips_dcache_wbinv_range((vm_offset_t)*vaddr,
+ mips_dcache_wbinv_range((vm_offset_t)*vaddr,
dmat->maxsize);
*vaddr = tmpaddr;
} else
@@ -521,20 +512,17 @@
/*
* Get the physical address for this segment.
*/
- curaddr = pmap_extract(pmap, vaddr);
+ KASSERT(kernel_pmap == pmap, ("pmap is not kernel pmap"));
+ curaddr = pmap_kextract(vaddr);
/*
* If we're beyond the current DMA window, indicate
* that and try to fall back onto something else.
*/
- /* XXXMIPS: check for range validity */
if (curaddr < dmat->_physbase ||
curaddr >= (dmat->_physbase + dmat->_wsize))
return (EINVAL);
-#if 0
- printf("dma: addr 0x%08lx -> 0x%08lx\n", curaddr,
- (curaddr - t->_physbase) + t->_wbase);
-#endif
+
/*
* In a valid DMA range. Translate the physical
* memory address to an address in the DMA window.
@@ -611,6 +599,7 @@
error = bus_dmamap_load_buffer(dmat,
dm_segments, map, buf, buflen, kernel_pmap,
flags, &lastaddr, &nsegs);
+
if (error)
(*callback)(callback_arg, NULL, 0, error);
else
@@ -631,8 +620,49 @@
bus_dmamap_callback2_t *callback, void *callback_arg,
int flags)
{
- panic("Unimplemented %s at %s:%d\n", __func__, __FILE__, __LINE__);
- return (0);
+#ifdef __CC_SUPPORTS_DYNAMIC_ARRAY_INIT
+ bus_dma_segment_t dm_segments[dmat->nsegments];
+#else
+ bus_dma_segment_t dm_segments[BUS_DMAMAP_NSEGS];
+#endif
+ int nsegs = -1, error = 0;
+
+ M_ASSERTPKTHDR(m0);
+
+ map->flags &= ~DMAMAP_TYPE_MASK;
+ map->flags |= DMAMAP_MBUF | DMAMAP_COHERENT;
+ map->buffer = m0;
+ map->len = 0;
+
+ if (m0->m_pkthdr.len <= dmat->maxsize) {
+ vm_offset_t lastaddr = 0;
+ struct mbuf *m;
+
+ for (m = m0; m != NULL && error == 0; m = m->m_next) {
+ if (m->m_len > 0) {
+ error = bus_dmamap_load_buffer(dmat,
+ dm_segments, map, m->m_data, m->m_len,
+ pmap_kernel(), flags, &lastaddr, &nsegs);
+ map->len += m->m_len;
+ }
+ }
+ } else {
+ error = EINVAL;
+ }
+
+ if (error) {
+ /*
+ * force "no valid mappings" on error in callback.
+ */
+ (*callback)(callback_arg, dm_segments, 0, 0, error);
+ } else {
+ (*callback)(callback_arg, dm_segments, nsegs + 1,
+ m0->m_pkthdr.len, error);
+ }
+ CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d",
+ __func__, dmat, dmat->flags, error, nsegs + 1);
+
+ return (error);
}
int
@@ -641,6 +671,7 @@
int flags)
{
int error = 0;
+
panic("Unimplemented %s at %s:%d\n", __func__, __FILE__, __LINE__);
return (error);
}
@@ -653,6 +684,7 @@
bus_dmamap_callback2_t *callback, void *callback_arg,
int flags)
{
+
panic("Unimplemented %s at %s:%d\n", __func__, __FILE__, __LINE__);
return (0);
}
@@ -663,7 +695,7 @@
void
_bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map)
{
- panic("Unimplemented %s at %s:%d\n", __func__, __FILE__, __LINE__);
+
return;
}
@@ -672,11 +704,13 @@
static __inline void
bus_dmamap_sync_buf(void *buf, int len, bus_dmasync_op_t op)
{
+
panic("Unimplemented %s at %s:%d\n", __func__, __FILE__, __LINE__);
}
void
_bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op)
{
- panic("Unimplemented %s at %s:%d\n", __func__, __FILE__, __LINE__);
+
+ /* XXXMIPS: flush caches or whatever */
}
More information about the p4-projects
mailing list