Wed Feb 13 23:08:46 2013 UTC ()
bounce buffer fixes + convert some kassert -> kassertmsg


(matt)
diff -r1.73 -r1.74 src/sys/arch/arm/arm32/bus_dma.c

cvs diff -r1.73 -r1.74 src/sys/arch/arm/arm32/bus_dma.c (expand / switch to unified diff)

--- src/sys/arch/arm/arm32/bus_dma.c 2013/02/04 13:26:19 1.73
+++ src/sys/arch/arm/arm32/bus_dma.c 2013/02/13 23:08:45 1.74
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: bus_dma.c,v 1.73 2013/02/04 13:26:19 macallan Exp $ */ 1/* $NetBSD: bus_dma.c,v 1.74 2013/02/13 23:08:45 matt Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. 4 * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9 * NASA Ames Research Center. 9 * NASA Ames Research Center.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
@@ -23,27 +23,27 @@ @@ -23,27 +23,27 @@
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE. 30 * POSSIBILITY OF SUCH DAMAGE.
31 */ 31 */
32 32
33#define _ARM32_BUS_DMA_PRIVATE 33#define _ARM32_BUS_DMA_PRIVATE
34 34
35#include <sys/cdefs.h> 35#include <sys/cdefs.h>
36__KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v 1.73 2013/02/04 13:26:19 macallan Exp $"); 36__KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v 1.74 2013/02/13 23:08:45 matt Exp $");
37 37
38#include <sys/param.h> 38#include <sys/param.h>
39#include <sys/systm.h> 39#include <sys/systm.h>
40#include <sys/kernel.h> 40#include <sys/kernel.h>
41#include <sys/proc.h> 41#include <sys/proc.h>
42#include <sys/buf.h> 42#include <sys/buf.h>
43#include <sys/reboot.h> 43#include <sys/reboot.h>
44#include <sys/conf.h> 44#include <sys/conf.h>
45#include <sys/file.h> 45#include <sys/file.h>
46#include <sys/malloc.h> 46#include <sys/malloc.h>
47#include <sys/mbuf.h> 47#include <sys/mbuf.h>
48#include <sys/vnode.h> 48#include <sys/vnode.h>
49#include <sys/device.h> 49#include <sys/device.h>
@@ -441,27 +441,29 @@ _bus_dmamap_load(bus_dma_tag_t t, bus_dm @@ -441,27 +441,29 @@ _bus_dmamap_load(bus_dma_tag_t t, bus_dm
441 map->_dm_flags &= ~_BUS_DMAMAP_IS_BOUNCING; 441 map->_dm_flags &= ~_BUS_DMAMAP_IS_BOUNCING;
442 } 442 }
443 } else 443 } else
444#endif 444#endif
445 STAT_INCR(unloads); 445 STAT_INCR(unloads);
446 } 446 }
447 447
448 /* 448 /*
449 * Make sure that on error condition we return "no valid mappings". 449 * Make sure that on error condition we return "no valid mappings".
450 */ 450 */
451 map->dm_mapsize = 0; 451 map->dm_mapsize = 0;
452 map->dm_nsegs = 0; 452 map->dm_nsegs = 0;
453 map->_dm_buftype = _BUS_DMA_BUFTYPE_INVALID; 453 map->_dm_buftype = _BUS_DMA_BUFTYPE_INVALID;
454 KASSERT(map->dm_maxsegsz <= map->_dm_maxmaxsegsz); 454 KASSERTMSG(map->dm_maxsegsz <= map->_dm_maxmaxsegsz,
 455 "dm_maxsegsz %lu _dm_maxmaxsegsz %lu",
 456 map->dm_maxsegsz, map->_dm_maxmaxsegsz);
455 457
456 if (buflen > map->_dm_size) 458 if (buflen > map->_dm_size)
457 return (EINVAL); 459 return (EINVAL);
458 460
459 if (p != NULL) { 461 if (p != NULL) {
460 vm = p->p_vmspace; 462 vm = p->p_vmspace;
461 } else { 463 } else {
462 vm = vmspace_kernel(); 464 vm = vmspace_kernel();
463 } 465 }
464 466
465 /* _bus_dmamap_load_buffer() clears this if we're not... */ 467 /* _bus_dmamap_load_buffer() clears this if we're not... */
466 map->_dm_flags |= _BUS_DMAMAP_COHERENT; 468 map->_dm_flags |= _BUS_DMAMAP_COHERENT;
467 469
@@ -508,27 +510,29 @@ _bus_dmamap_load_mbuf(bus_dma_tag_t t, b @@ -508,27 +510,29 @@ _bus_dmamap_load_mbuf(bus_dma_tag_t t, b
508 map->_dm_flags &= ~_BUS_DMAMAP_IS_BOUNCING; 510 map->_dm_flags &= ~_BUS_DMAMAP_IS_BOUNCING;
509 } 511 }
510 } else 512 } else
511#endif 513#endif
512 STAT_INCR(unloads); 514 STAT_INCR(unloads);
513 } 515 }
514 516
515 /* 517 /*
516 * Make sure that on error condition we return "no valid mappings." 518 * Make sure that on error condition we return "no valid mappings."
517 */ 519 */
518 map->dm_mapsize = 0; 520 map->dm_mapsize = 0;
519 map->dm_nsegs = 0; 521 map->dm_nsegs = 0;
520 map->_dm_buftype = _BUS_DMA_BUFTYPE_INVALID; 522 map->_dm_buftype = _BUS_DMA_BUFTYPE_INVALID;
521 KASSERT(map->dm_maxsegsz <= map->_dm_maxmaxsegsz); 523 KASSERTMSG(map->dm_maxsegsz <= map->_dm_maxmaxsegsz,
 524 "dm_maxsegsz %lu _dm_maxmaxsegsz %lu",
 525 map->dm_maxsegsz, map->_dm_maxmaxsegsz);
522 526
523#ifdef DIAGNOSTIC 527#ifdef DIAGNOSTIC
524 if ((m0->m_flags & M_PKTHDR) == 0) 528 if ((m0->m_flags & M_PKTHDR) == 0)
525 panic("_bus_dmamap_load_mbuf: no packet header"); 529 panic("_bus_dmamap_load_mbuf: no packet header");
526#endif /* DIAGNOSTIC */ 530#endif /* DIAGNOSTIC */
527 531
528 if (m0->m_pkthdr.len > map->_dm_size) 532 if (m0->m_pkthdr.len > map->_dm_size)
529 return (EINVAL); 533 return (EINVAL);
530 534
531 /* _bus_dmamap_load_paddr() clears this if we're not... */ 535 /* _bus_dmamap_load_paddr() clears this if we're not... */
532 map->_dm_flags |= _BUS_DMAMAP_COHERENT; 536 map->_dm_flags |= _BUS_DMAMAP_COHERENT;
533 537
534 error = 0; 538 error = 0;
@@ -630,27 +634,29 @@ int @@ -630,27 +634,29 @@ int
630_bus_dmamap_load_uio(bus_dma_tag_t t, bus_dmamap_t map, struct uio *uio, 634_bus_dmamap_load_uio(bus_dma_tag_t t, bus_dmamap_t map, struct uio *uio,
631 int flags) 635 int flags)
632{ 636{
633 int i, error; 637 int i, error;
634 bus_size_t minlen, resid; 638 bus_size_t minlen, resid;
635 struct iovec *iov; 639 struct iovec *iov;
636 void *addr; 640 void *addr;
637 641
638 /* 642 /*
639 * Make sure that on error condition we return "no valid mappings." 643 * Make sure that on error condition we return "no valid mappings."
640 */ 644 */
641 map->dm_mapsize = 0; 645 map->dm_mapsize = 0;
642 map->dm_nsegs = 0; 646 map->dm_nsegs = 0;
643 KASSERT(map->dm_maxsegsz <= map->_dm_maxmaxsegsz); 647 KASSERTMSG(map->dm_maxsegsz <= map->_dm_maxmaxsegsz,
 648 "dm_maxsegsz %lu _dm_maxmaxsegsz %lu",
 649 map->dm_maxsegsz, map->_dm_maxmaxsegsz);
644 650
645 resid = uio->uio_resid; 651 resid = uio->uio_resid;
646 iov = uio->uio_iov; 652 iov = uio->uio_iov;
647 653
648 /* _bus_dmamap_load_buffer() clears this if we're not... */ 654 /* _bus_dmamap_load_buffer() clears this if we're not... */
649 map->_dm_flags |= _BUS_DMAMAP_COHERENT; 655 map->_dm_flags |= _BUS_DMAMAP_COHERENT;
650 656
651 error = 0; 657 error = 0;
652 for (i = 0; i < uio->uio_iovcnt && resid != 0 && error == 0; i++) { 658 for (i = 0; i < uio->uio_iovcnt && resid != 0 && error == 0; i++) {
653 /* 659 /*
654 * Now at the first iovec to load. Load each iovec 660 * Now at the first iovec to load. Load each iovec
655 * until we have exhausted the residual count. 661 * until we have exhausted the residual count.
656 */ 662 */
@@ -947,41 +953,42 @@ _bus_dmamap_sync(bus_dma_tag_t t, bus_dm @@ -947,41 +953,42 @@ _bus_dmamap_sync(bus_dma_tag_t t, bus_dm
947 * here in case a write-back is required by the back-end. 953 * here in case a write-back is required by the back-end.
948 * 954 *
949 * PREWRITE -- Write-back the D-cache. Note that if 955 * PREWRITE -- Write-back the D-cache. Note that if
950 * we are doing a PREREAD|PREWRITE, we can collapse 956 * we are doing a PREREAD|PREWRITE, we can collapse
951 * the whole thing into a single Wb-Inv. 957 * the whole thing into a single Wb-Inv.
952 * 958 *
953 * POSTREAD -- Re-invalidate the D-cache in case speculative 959 * POSTREAD -- Re-invalidate the D-cache in case speculative
954 * memory accesses caused cachelines to become valid with now 960 * memory accesses caused cachelines to become valid with now
955 * invalid data. 961 * invalid data.
956 * 962 *
957 * POSTWRITE -- Nothing. 963 * POSTWRITE -- Nothing.
958 */ 964 */
959#ifdef _ARM32_NEED_BUS_DMA_BOUNCE 965#ifdef _ARM32_NEED_BUS_DMA_BOUNCE
960 const bool bouncing = (map->_dm_flags & _BUS_DMA_IS_BOUNCING); 966 const bool bouncing = (map->_dm_flags & _BUS_DMAMAP_IS_BOUNCING);
961#else 967#else
962 const bool bouncing = false; 968 const bool bouncing = false;
963#endif 969#endif
964 970
965 const int pre_ops = ops & (BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 971 const int pre_ops = ops & (BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
966#ifdef CPU_CORTEX 972#ifdef CPU_CORTEX
967 const int post_ops = ops & (BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 973 const int post_ops = ops & (BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
968#else 974#else
969 const int post_ops = 0; 975 const int post_ops = 0;
970#endif 976#endif
971 if (!bouncing && pre_ops == 0 && post_ops == BUS_DMASYNC_POSTWRITE) { 977 if (!bouncing && pre_ops == 0 && post_ops == BUS_DMASYNC_POSTWRITE) {
972 return; 978 return;
973 } 979 }
974 KASSERT(pre_ops != 0 || (post_ops & BUS_DMASYNC_POSTREAD)); 980 KASSERTMSG(bouncing || pre_ops != 0 || (post_ops & BUS_DMASYNC_POSTREAD),
 981 "pre_ops %#x post_ops %#x", pre_ops, post_ops);
975#ifdef _ARM32_NEED_BUS_DMA_BOUNCE 982#ifdef _ARM32_NEED_BUS_DMA_BOUNCE
976 if (bouncing && (ops & BUS_DMASYNC_PREWRITE)) { 983 if (bouncing && (ops & BUS_DMASYNC_PREWRITE)) {
977 struct arm32_bus_dma_cookie * const cookie = map->_dm_cookie; 984 struct arm32_bus_dma_cookie * const cookie = map->_dm_cookie;
978 STAT_INCR(write_bounces); 985 STAT_INCR(write_bounces);
979 char * const dataptr = (char *)cookie->id_bouncebuf + offset; 986 char * const dataptr = (char *)cookie->id_bouncebuf + offset;
980 /* 987 /*
981 * Copy the caller's buffer to the bounce buffer. 988 * Copy the caller's buffer to the bounce buffer.
982 */ 989 */
983 switch (map->_dm_buftype) { 990 switch (map->_dm_buftype) {
984 case _BUS_DMA_BUFTYPE_LINEAR: 991 case _BUS_DMA_BUFTYPE_LINEAR:
985 memcpy(dataptr, cookie->id_origlinearbuf + offset, len); 992 memcpy(dataptr, cookie->id_origlinearbuf + offset, len);
986 break; 993 break;
987 case _BUS_DMA_BUFTYPE_MBUF: 994 case _BUS_DMA_BUFTYPE_MBUF:
@@ -999,27 +1006,28 @@ _bus_dmamap_sync(bus_dma_tag_t t, bus_dm @@ -999,27 +1006,28 @@ _bus_dmamap_sync(bus_dma_tag_t t, bus_dm
999 panic("_bus_dmamap_sync(pre): _BUS_DMA_BUFTYPE_INVALID"); 1006 panic("_bus_dmamap_sync(pre): _BUS_DMA_BUFTYPE_INVALID");
1000 break; 1007 break;
1001 1008
1002 default: 1009 default:
1003 panic("_bus_dmamap_sync(pre): map %p: unknown buffer type %d\n", 1010 panic("_bus_dmamap_sync(pre): map %p: unknown buffer type %d\n",
1004 map, map->_dm_buftype); 1011 map, map->_dm_buftype);
1005 break; 1012 break;
1006#endif /* DIAGNOSTIC */ 1013#endif /* DIAGNOSTIC */
1007 } 1014 }
1008 } 1015 }
1009#endif /* _ARM32_NEED_BUS_DMA_BOUNCE */ 1016#endif /* _ARM32_NEED_BUS_DMA_BOUNCE */
1010 1017
1011 /* Skip cache frobbing if mapping was COHERENT. */ 1018 /* Skip cache frobbing if mapping was COHERENT. */
1012 if (!bouncing && (map->_dm_flags & _BUS_DMAMAP_COHERENT)) { 1019 if (!bouncing && pre_ops == 0
 1020 && (map->_dm_flags & _BUS_DMAMAP_COHERENT)) {
1013 /* Drain the write buffer. */ 1021 /* Drain the write buffer. */
1014 cpu_drain_writebuf(); 1022 cpu_drain_writebuf();
1015 return; 1023 return;
1016 } 1024 }
1017 1025
1018#ifdef _ARM32_NEED_BUS_DMA_BOUNCE 1026#ifdef _ARM32_NEED_BUS_DMA_BOUNCE
1019 if (bouncing && ((map->_dm_flags & _BUS_DMAMAP_COHERENT) || pre_ops == 0)) { 1027 if (bouncing && ((map->_dm_flags & _BUS_DMAMAP_COHERENT) || pre_ops == 0)) {
1020 goto bounce_it; 1028 goto bounce_it;
1021 } 1029 }
1022#endif /* _ARM32_NEED_BUS_DMA_BOUNCE */ 1030#endif /* _ARM32_NEED_BUS_DMA_BOUNCE */
1023 1031
1024 /* 1032 /*
1025 * If the mapping belongs to a non-kernel vmspace, and the 1033 * If the mapping belongs to a non-kernel vmspace, and the