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