Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 29 Dec 2012 18:40:47 +0000 (UTC)
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r244826 - projects/altix2/sys/kern
Message-ID:  <201212291840.qBTIell4027001@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: marcel
Date: Sat Dec 29 18:40:47 2012
New Revision: 244826
URL: http://svnweb.freebsd.org/changeset/base/244826

Log:
  Improve debugging a little bit:
  1.  Dump the DMA memory when busdma_sync is called (BUSDMA_DEBUG). We
      should probably limit it to 64 bytes or so.
  2.  Fail hard when we query segmnts and things aren't quite right.
  3.  When loading a buffer, preserve the virtual address for now. I
      don't like loosing information in the process. Then again, the
      load operation is impacted if we're unwilling to forget about
      the accidental virtual mapping -- the physical address is really
      all we care about.

Modified:
  projects/altix2/sys/kern/subr_busdma.c

Modified: projects/altix2/sys/kern/subr_busdma.c
==============================================================================
--- projects/altix2/sys/kern/subr_busdma.c	Sat Dec 29 17:41:50 2012	(r244825)
+++ projects/altix2/sys/kern/subr_busdma.c	Sat Dec 29 18:40:47 2012	(r244826)
@@ -217,6 +217,31 @@ _busdma_md_dump(const char *func, device
 #endif
 }
 
+static void
+_busdma_data_dump(const char *func, struct busdma_md *md, bus_addr_t addr,
+    bus_size_t len)
+{
+#ifdef BUSDMA_DEBUG
+	struct busdma_md_seg *seg;
+	void *va;
+	bus_addr_t pa;
+	int sz;
+
+	printf("[%s: %s: md=%p {\n", func,
+	    device_get_nameunit(md->md_tag->dt_device), md);
+	TAILQ_FOREACH(seg, &md->md_seg, mds_chain) {
+		if (seg->mds_busaddr + seg->mds_size <= addr ||
+		    addr + len <= seg->mds_busaddr)
+			continue;
+		pa = MAX(seg->mds_busaddr, addr);
+		sz = MIN(seg->mds_busaddr + seg->mds_size, addr + len) - pa;
+		va = (void *)(seg->mds_vaddr + (pa - seg->mds_busaddr));
+		printf("%#jx: %*D\n", (uintmax_t)pa, sz, va, " ");
+	}
+	printf("}]\n");
+#endif
+}
+
 /* Section 3.3: API support functions. */
 
 static struct busdma_md_seg *
@@ -231,7 +256,7 @@ _busdma_md_get_seg(struct busdma_md *md,
 		if (seg->mds_idx == idx)
 			return (seg);
 	}
-	/* XXX getting here means we probably have a bug... */
+
 	return (NULL);
 }
 
@@ -398,8 +423,10 @@ _busdma_md_load(struct busdma_md *md, pm
 		pgsz = PAGE_SIZE - (va & PAGE_MASK);
 		sz = MIN(len, maxsegsz);
 		sz = MIN(pgsz, sz);
+		/* Extend last segment if possible. */
 		if (seg != NULL && seg->mds_size < maxsegsz &&
-		    seg->mds_paddr + seg->mds_size == pa) {
+		    seg->mds_paddr + seg->mds_size == pa &&
+		    seg->mds_vaddr + seg->mds_size == va) {
 			catsz = maxsegsz - seg->mds_size;
 			catsz = MIN(sz, catsz);
 			seg->mds_size += catsz;
@@ -421,9 +448,9 @@ _busdma_md_load(struct busdma_md *md, pm
 		seg->mds_idx = idx++;
 		TAILQ_INSERT_TAIL(&md->md_seg, seg, mds_chain);
 		md->md_nsegs++;
-		seg->mds_busaddr = ~0U;
+		seg->mds_busaddr = ~0UL;
 		seg->mds_paddr = pa;
-		seg->mds_vaddr = 0;
+		seg->mds_vaddr = va;
 		seg->mds_size = sz;
 		len -= sz;
 		va += sz;
@@ -555,11 +582,14 @@ bus_addr_t
 busdma_md_get_busaddr(struct busdma_md *md, u_int idx)
 {
 	struct busdma_md_seg *seg;
+	bus_addr_t busaddr;
 
 	CTR3(KTR_BUSDMA, "%s: md=%p, idx=%u", __func__, md, idx);
 
 	seg = _busdma_md_get_seg(md, idx);
-	return ((seg != NULL) ? seg->mds_busaddr : ~0UL);
+	busaddr = (seg != NULL) ? seg->mds_busaddr : ~0UL;
+	KASSERT(busaddr != ~0UL, ("%s: invalid busaddr", __func__));
+	return (busaddr);
 }
 
 u_int
@@ -575,33 +605,42 @@ vm_paddr_t
 busdma_md_get_paddr(struct busdma_md *md, u_int idx)
 {
 	struct busdma_md_seg *seg;
+	vm_paddr_t paddr;
 
 	CTR3(KTR_BUSDMA, "%s: md=%p, idx=%u", __func__, md, idx);
 
 	seg = _busdma_md_get_seg(md, idx);
-	return ((seg != NULL) ? seg->mds_paddr : ~0UL);
+	paddr = (seg != NULL) ? seg->mds_paddr : ~0UL;
+	KASSERT(paddr != ~0UL, ("%s: invalid paddr", __func__));
+	return (paddr);
 }
 
 vm_size_t
 busdma_md_get_size(struct busdma_md *md, u_int idx)
 {
 	struct busdma_md_seg *seg;
+	vm_size_t size;
 
 	CTR3(KTR_BUSDMA, "%s: md=%p, idx=%u", __func__, md, idx);
 
 	seg = _busdma_md_get_seg(md, idx);
-	return ((seg != NULL) ? seg->mds_size : 0UL);
+	size = (seg != NULL) ? seg->mds_size : 0UL;
+	KASSERT(size != 0UL, ("%s: invalid size", __func__));
+	return (size);
 }
 
 vm_offset_t
 busdma_md_get_vaddr(struct busdma_md *md, u_int idx)
 {
 	struct busdma_md_seg *seg;
+	vm_offset_t vaddr;
 
 	CTR3(KTR_BUSDMA, "%s: md=%p, idx=%u", __func__, md, idx);
 
 	seg = _busdma_md_get_seg(md, idx);
-	return ((seg != NULL) ? seg->mds_vaddr : 0);
+	vaddr = (seg != NULL) ? seg->mds_vaddr : 0UL;
+	KASSERT(vaddr != 0UL, ("%s: invalid vaddr", __func__));
+	return (vaddr);
 }
 
 int
@@ -635,6 +674,7 @@ busdma_md_load_phys(struct busdma_md *md
 	    "cb=%p, arg=%p, flags=%#x", md, (uintmax_t)buf, len, cb, arg,
 	    flags);
 
+	panic(__func__);
 	(*cb)(arg, md, ENOSYS);
 	return (0);
 }
@@ -647,6 +687,7 @@ busdma_md_load_uio(struct busdma_md *md,
 	CTR6(KTR_BUSDMA, "%s: md=%p, uio=%p, cb=%p, arg=%p, flags=%#x",
 	    __func__, md, uio, cb, arg, flags);
 
+	panic(__func__);
 	(*cb)(arg, md, ENOSYS);
 	return (0);
 }
@@ -788,6 +829,9 @@ busdma_sync(struct busdma_md *md, u_int 
 {
 
 	CTR3(KTR_BUSDMA, "%s: md=%p, op=%#x", __func__, md, op);
+
+	if ((op & BUSDMA_SYNC_PREWRITE) || (op & BUSDMA_SYNC_POSTREAD))
+		_busdma_data_dump(__func__, md, 0UL, ~0UL);
 }
 
 void
@@ -796,5 +840,8 @@ busdma_sync_range(struct busdma_md *md, 
 {
 
 	CTR5(KTR_BUSDMA, "%s: md=%p, op=%#x, addr=%#jx, len=%#jx", __func__,
-	    md, op, addr, len);
+	    md, op, (uintmax_t)addr, (uintmax_t)len);
+
+	if ((op & BUSDMA_SYNC_PREWRITE) || (op & BUSDMA_SYNC_POSTREAD))
+		_busdma_data_dump(__func__, md, addr, len);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201212291840.qBTIell4027001>