From owner-svn-src-projects@FreeBSD.ORG Sat Dec 29 18:40:48 2012 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 05C15FDB; Sat, 29 Dec 2012 18:40:48 +0000 (UTC) (envelope-from marcel@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id D50428FC0A; Sat, 29 Dec 2012 18:40:47 +0000 (UTC) Received: from svn.freebsd.org (svn.FreeBSD.org [8.8.178.70]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id qBTIelHf027002; Sat, 29 Dec 2012 18:40:47 GMT (envelope-from marcel@svn.freebsd.org) Received: (from marcel@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id qBTIell4027001; Sat, 29 Dec 2012 18:40:47 GMT (envelope-from marcel@svn.freebsd.org) Message-Id: <201212291840.qBTIell4027001@svn.freebsd.org> From: Marcel Moolenaar Date: Sat, 29 Dec 2012 18:40:47 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r244826 - projects/altix2/sys/kern X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 29 Dec 2012 18:40:48 -0000 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); }