busdma_machdep-v4.c (236991) | busdma_machdep-v4.c (240177) |
---|---|
1/*- 2 * Copyright (c) 2004 Olivier Houchard 3 * Copyright (c) 2002 Peter Grehan 4 * Copyright (c) 1997, 1998 Justin T. Gibbs. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 15 unchanged lines hidden (view full) --- 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 * From i386/busdma_machdep.c,v 1.26 2002/04/19 22:58:09 alfred 29 */ 30 31#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2004 Olivier Houchard 3 * Copyright (c) 2002 Peter Grehan 4 * Copyright (c) 1997, 1998 Justin T. Gibbs. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 15 unchanged lines hidden (view full) --- 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 * From i386/busdma_machdep.c,v 1.26 2002/04/19 22:58:09 alfred 29 */ 30 31#include <sys/cdefs.h> |
32__FBSDID("$FreeBSD: head/sys/arm/arm/busdma_machdep.c 236991 2012-06-13 04:59:55Z imp $"); | 32__FBSDID("$FreeBSD: head/sys/arm/arm/busdma_machdep.c 240177 2012-09-06 20:16:59Z jhb $"); |
33 34/* 35 * ARM bus dma support routines 36 */ 37 38#define _ARM32_BUS_DMA_PRIVATE 39#include <sys/param.h> 40#include <sys/systm.h> --- 35 unchanged lines hidden (view full) --- 76 bus_size_t maxsize; 77 u_int nsegments; 78 bus_size_t maxsegsz; 79 int flags; 80 int ref_count; 81 int map_count; 82 bus_dma_lock_t *lockfunc; 83 void *lockfuncarg; | 33 34/* 35 * ARM bus dma support routines 36 */ 37 38#define _ARM32_BUS_DMA_PRIVATE 39#include <sys/param.h> 40#include <sys/systm.h> --- 35 unchanged lines hidden (view full) --- 76 bus_size_t maxsize; 77 u_int nsegments; 78 bus_size_t maxsegsz; 79 int flags; 80 int ref_count; 81 int map_count; 82 bus_dma_lock_t *lockfunc; 83 void *lockfuncarg; |
84 bus_dma_segment_t *segments; |
|
84 /* 85 * DMA range for this tag. If the page doesn't fall within 86 * one of these ranges, an error is returned. The caller 87 * may then decide what to do with the transfer. If the 88 * range pointer is NULL, it is ignored. 89 */ 90 struct arm32_dma_range *ranges; 91 int _nranges; --- 277 unchanged lines hidden (view full) --- 369 newtag->_nranges = bus_dma_get_range_nb(); 370 if (lockfunc != NULL) { 371 newtag->lockfunc = lockfunc; 372 newtag->lockfuncarg = lockfuncarg; 373 } else { 374 newtag->lockfunc = dflt_lock; 375 newtag->lockfuncarg = NULL; 376 } | 85 /* 86 * DMA range for this tag. If the page doesn't fall within 87 * one of these ranges, an error is returned. The caller 88 * may then decide what to do with the transfer. If the 89 * range pointer is NULL, it is ignored. 90 */ 91 struct arm32_dma_range *ranges; 92 int _nranges; --- 277 unchanged lines hidden (view full) --- 370 newtag->_nranges = bus_dma_get_range_nb(); 371 if (lockfunc != NULL) { 372 newtag->lockfunc = lockfunc; 373 newtag->lockfuncarg = lockfuncarg; 374 } else { 375 newtag->lockfunc = dflt_lock; 376 newtag->lockfuncarg = NULL; 377 } |
378 newtag->segments = NULL; 379 |
|
377 /* 378 * Take into account any restrictions imposed by our parent tag 379 */ 380 if (parent != NULL) { 381 newtag->lowaddr = MIN(parent->lowaddr, newtag->lowaddr); 382 newtag->highaddr = MAX(parent->highaddr, newtag->highaddr); 383 if (newtag->boundary == 0) 384 newtag->boundary = parent->boundary; --- 57 unchanged lines hidden (view full) --- 442int 443bus_dma_tag_destroy(bus_dma_tag_t dmat) 444{ 445#ifdef KTR 446 bus_dma_tag_t dmat_copy = dmat; 447#endif 448 449 if (dmat != NULL) { | 380 /* 381 * Take into account any restrictions imposed by our parent tag 382 */ 383 if (parent != NULL) { 384 newtag->lowaddr = MIN(parent->lowaddr, newtag->lowaddr); 385 newtag->highaddr = MAX(parent->highaddr, newtag->highaddr); 386 if (newtag->boundary == 0) 387 newtag->boundary = parent->boundary; --- 57 unchanged lines hidden (view full) --- 445int 446bus_dma_tag_destroy(bus_dma_tag_t dmat) 447{ 448#ifdef KTR 449 bus_dma_tag_t dmat_copy = dmat; 450#endif 451 452 if (dmat != NULL) { |
450 | |
451 if (dmat->map_count != 0) 452 return (EBUSY); 453 454 while (dmat != NULL) { 455 bus_dma_tag_t parent; 456 457 parent = dmat->parent; 458 atomic_subtract_int(&dmat->ref_count, 1); 459 if (dmat->ref_count == 0) { | 453 if (dmat->map_count != 0) 454 return (EBUSY); 455 456 while (dmat != NULL) { 457 bus_dma_tag_t parent; 458 459 parent = dmat->parent; 460 atomic_subtract_int(&dmat->ref_count, 1); 461 if (dmat->ref_count == 0) { |
462 if (dmat->segments != NULL) 463 free(dmat->segments, M_DEVBUF); |
|
460 free(dmat, M_DEVBUF); 461 /* 462 * Last reference count, so 463 * release our reference 464 * count on our parent. 465 */ 466 dmat = parent; 467 } else --- 11 unchanged lines hidden (view full) --- 479 * address space into bus device space. 480 */ 481int 482bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp) 483{ 484 bus_dmamap_t newmap; 485 int error = 0; 486 | 464 free(dmat, M_DEVBUF); 465 /* 466 * Last reference count, so 467 * release our reference 468 * count on our parent. 469 */ 470 dmat = parent; 471 } else --- 11 unchanged lines hidden (view full) --- 483 * address space into bus device space. 484 */ 485int 486bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp) 487{ 488 bus_dmamap_t newmap; 489 int error = 0; 490 |
491 if (dmat->segments == NULL) { 492 dmat->segments = (bus_dma_segment_t *)malloc( 493 sizeof(bus_dma_segment_t) * dmat->nsegments, M_DEVBUF, 494 M_NOWAIT); 495 if (dmat->segments == NULL) { 496 CTR3(KTR_BUSDMA, "%s: tag %p error %d", 497 __func__, dmat, ENOMEM); 498 return (ENOMEM); 499 } 500 } 501 |
|
487 newmap = _busdma_alloc_dmamap(); 488 if (newmap == NULL) { 489 CTR3(KTR_BUSDMA, "%s: tag %p error %d", __func__, dmat, ENOMEM); 490 return (ENOMEM); 491 } 492 *mapp = newmap; 493 newmap->dmat = dmat; 494 newmap->allocbuffer = NULL; --- 85 unchanged lines hidden (view full) --- 580 bus_dmamap_t newmap = NULL; 581 582 int mflags; 583 584 if (flags & BUS_DMA_NOWAIT) 585 mflags = M_NOWAIT; 586 else 587 mflags = M_WAITOK; | 502 newmap = _busdma_alloc_dmamap(); 503 if (newmap == NULL) { 504 CTR3(KTR_BUSDMA, "%s: tag %p error %d", __func__, dmat, ENOMEM); 505 return (ENOMEM); 506 } 507 *mapp = newmap; 508 newmap->dmat = dmat; 509 newmap->allocbuffer = NULL; --- 85 unchanged lines hidden (view full) --- 595 bus_dmamap_t newmap = NULL; 596 597 int mflags; 598 599 if (flags & BUS_DMA_NOWAIT) 600 mflags = M_NOWAIT; 601 else 602 mflags = M_WAITOK; |
603 if (dmat->segments == NULL) { 604 dmat->segments = (bus_dma_segment_t *)malloc( 605 sizeof(bus_dma_segment_t) * dmat->nsegments, M_DEVBUF, 606 mflags); 607 if (dmat->segments == NULL) { 608 CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d", 609 __func__, dmat, dmat->flags, ENOMEM); 610 return (ENOMEM); 611 } 612 } |
|
588 if (flags & BUS_DMA_ZERO) 589 mflags |= M_ZERO; 590 591 newmap = _busdma_alloc_dmamap(); 592 if (newmap == NULL) { 593 CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d", 594 __func__, dmat, dmat->flags, ENOMEM); 595 return (ENOMEM); --- 282 unchanged lines hidden (view full) --- 878 */ 879int 880bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, 881 bus_size_t buflen, bus_dmamap_callback_t *callback, 882 void *callback_arg, int flags) 883{ 884 vm_offset_t lastaddr = 0; 885 int error, nsegs = -1; | 613 if (flags & BUS_DMA_ZERO) 614 mflags |= M_ZERO; 615 616 newmap = _busdma_alloc_dmamap(); 617 if (newmap == NULL) { 618 CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d", 619 __func__, dmat, dmat->flags, ENOMEM); 620 return (ENOMEM); --- 282 unchanged lines hidden (view full) --- 903 */ 904int 905bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, 906 bus_size_t buflen, bus_dmamap_callback_t *callback, 907 void *callback_arg, int flags) 908{ 909 vm_offset_t lastaddr = 0; 910 int error, nsegs = -1; |
886#ifdef __CC_SUPPORTS_DYNAMIC_ARRAY_INIT 887 bus_dma_segment_t dm_segments[dmat->nsegments]; 888#else 889 bus_dma_segment_t dm_segments[BUS_DMAMAP_NSEGS]; 890#endif | |
891 892 KASSERT(dmat != NULL, ("dmatag is NULL")); 893 KASSERT(map != NULL, ("dmamap is NULL")); 894 map->callback = callback; 895 map->callback_arg = callback_arg; 896 map->flags &= ~DMAMAP_TYPE_MASK; 897 map->flags |= DMAMAP_LINEAR|DMAMAP_COHERENT; 898 map->buffer = buf; 899 map->len = buflen; 900 error = bus_dmamap_load_buffer(dmat, | 911 912 KASSERT(dmat != NULL, ("dmatag is NULL")); 913 KASSERT(map != NULL, ("dmamap is NULL")); 914 map->callback = callback; 915 map->callback_arg = callback_arg; 916 map->flags &= ~DMAMAP_TYPE_MASK; 917 map->flags |= DMAMAP_LINEAR|DMAMAP_COHERENT; 918 map->buffer = buf; 919 map->len = buflen; 920 error = bus_dmamap_load_buffer(dmat, |
901 dm_segments, map, buf, buflen, kernel_pmap, | 921 dmat->segments, map, buf, buflen, kernel_pmap, |
902 flags, &lastaddr, &nsegs); 903 if (error == EINPROGRESS) 904 return (error); 905 if (error) 906 (*callback)(callback_arg, NULL, 0, error); 907 else | 922 flags, &lastaddr, &nsegs); 923 if (error == EINPROGRESS) 924 return (error); 925 if (error) 926 (*callback)(callback_arg, NULL, 0, error); 927 else |
908 (*callback)(callback_arg, dm_segments, nsegs + 1, error); | 928 (*callback)(callback_arg, dmat->segments, nsegs + 1, error); |
909 910 CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d", 911 __func__, dmat, dmat->flags, nsegs + 1, error); 912 913 return (error); 914} 915 916/* 917 * Like bus_dmamap_load(), but for mbufs. 918 */ 919int 920bus_dmamap_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map, struct mbuf *m0, 921 bus_dmamap_callback2_t *callback, void *callback_arg, 922 int flags) 923{ | 929 930 CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d", 931 __func__, dmat, dmat->flags, nsegs + 1, error); 932 933 return (error); 934} 935 936/* 937 * Like bus_dmamap_load(), but for mbufs. 938 */ 939int 940bus_dmamap_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map, struct mbuf *m0, 941 bus_dmamap_callback2_t *callback, void *callback_arg, 942 int flags) 943{ |
924#ifdef __CC_SUPPORTS_DYNAMIC_ARRAY_INIT 925 bus_dma_segment_t dm_segments[dmat->nsegments]; 926#else 927 bus_dma_segment_t dm_segments[BUS_DMAMAP_NSEGS]; 928#endif | |
929 int nsegs = -1, error = 0; 930 931 M_ASSERTPKTHDR(m0); 932 933 map->flags &= ~DMAMAP_TYPE_MASK; 934 map->flags |= DMAMAP_MBUF | DMAMAP_COHERENT; 935 map->buffer = m0; 936 map->len = 0; 937 if (m0->m_pkthdr.len <= dmat->maxsize) { 938 vm_offset_t lastaddr = 0; 939 struct mbuf *m; 940 941 for (m = m0; m != NULL && error == 0; m = m->m_next) { 942 if (m->m_len > 0) { 943 error = bus_dmamap_load_buffer(dmat, | 944 int nsegs = -1, error = 0; 945 946 M_ASSERTPKTHDR(m0); 947 948 map->flags &= ~DMAMAP_TYPE_MASK; 949 map->flags |= DMAMAP_MBUF | DMAMAP_COHERENT; 950 map->buffer = m0; 951 map->len = 0; 952 if (m0->m_pkthdr.len <= dmat->maxsize) { 953 vm_offset_t lastaddr = 0; 954 struct mbuf *m; 955 956 for (m = m0; m != NULL && error == 0; m = m->m_next) { 957 if (m->m_len > 0) { 958 error = bus_dmamap_load_buffer(dmat, |
944 dm_segments, map, m->m_data, m->m_len, | 959 dmat->segments, map, m->m_data, m->m_len, |
945 pmap_kernel(), flags, &lastaddr, &nsegs); 946 map->len += m->m_len; 947 } 948 } 949 } else { 950 error = EINVAL; 951 } 952 953 if (error) { 954 /* 955 * force "no valid mappings" on error in callback. 956 */ | 960 pmap_kernel(), flags, &lastaddr, &nsegs); 961 map->len += m->m_len; 962 } 963 } 964 } else { 965 error = EINVAL; 966 } 967 968 if (error) { 969 /* 970 * force "no valid mappings" on error in callback. 971 */ |
957 (*callback)(callback_arg, dm_segments, 0, 0, error); | 972 (*callback)(callback_arg, dmat->segments, 0, 0, error); |
958 } else { | 973 } else { |
959 (*callback)(callback_arg, dm_segments, nsegs + 1, | 974 (*callback)(callback_arg, dmat->segments, nsegs + 1, |
960 m0->m_pkthdr.len, error); 961 } 962 CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d", 963 __func__, dmat, dmat->flags, error, nsegs + 1); 964 965 return (error); 966} 967 --- 39 unchanged lines hidden (view full) --- 1007 * Like bus_dmamap_load(), but for uios. 1008 */ 1009int 1010bus_dmamap_load_uio(bus_dma_tag_t dmat, bus_dmamap_t map, struct uio *uio, 1011 bus_dmamap_callback2_t *callback, void *callback_arg, 1012 int flags) 1013{ 1014 vm_offset_t lastaddr = 0; | 975 m0->m_pkthdr.len, error); 976 } 977 CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d", 978 __func__, dmat, dmat->flags, error, nsegs + 1); 979 980 return (error); 981} 982 --- 39 unchanged lines hidden (view full) --- 1022 * Like bus_dmamap_load(), but for uios. 1023 */ 1024int 1025bus_dmamap_load_uio(bus_dma_tag_t dmat, bus_dmamap_t map, struct uio *uio, 1026 bus_dmamap_callback2_t *callback, void *callback_arg, 1027 int flags) 1028{ 1029 vm_offset_t lastaddr = 0; |
1015#ifdef __CC_SUPPORTS_DYNAMIC_ARRAY_INIT 1016 bus_dma_segment_t dm_segments[dmat->nsegments]; 1017#else 1018 bus_dma_segment_t dm_segments[BUS_DMAMAP_NSEGS]; 1019#endif | |
1020 int nsegs, i, error; 1021 bus_size_t resid; 1022 struct iovec *iov; 1023 struct pmap *pmap; 1024 1025 resid = uio->uio_resid; 1026 iov = uio->uio_iov; 1027 map->flags &= ~DMAMAP_TYPE_MASK; --- 15 unchanged lines hidden (view full) --- 1043 * Now at the first iovec to load. Load each iovec 1044 * until we have exhausted the residual count. 1045 */ 1046 bus_size_t minlen = 1047 resid < iov[i].iov_len ? resid : iov[i].iov_len; 1048 caddr_t addr = (caddr_t) iov[i].iov_base; 1049 1050 if (minlen > 0) { | 1030 int nsegs, i, error; 1031 bus_size_t resid; 1032 struct iovec *iov; 1033 struct pmap *pmap; 1034 1035 resid = uio->uio_resid; 1036 iov = uio->uio_iov; 1037 map->flags &= ~DMAMAP_TYPE_MASK; --- 15 unchanged lines hidden (view full) --- 1053 * Now at the first iovec to load. Load each iovec 1054 * until we have exhausted the residual count. 1055 */ 1056 bus_size_t minlen = 1057 resid < iov[i].iov_len ? resid : iov[i].iov_len; 1058 caddr_t addr = (caddr_t) iov[i].iov_base; 1059 1060 if (minlen > 0) { |
1051 error = bus_dmamap_load_buffer(dmat, dm_segments, map, 1052 addr, minlen, pmap, flags, &lastaddr, &nsegs); | 1061 error = bus_dmamap_load_buffer(dmat, dmat->segments, 1062 map, addr, minlen, pmap, flags, &lastaddr, &nsegs); |
1053 1054 map->len += minlen; 1055 resid -= minlen; 1056 } 1057 } 1058 1059 if (error) { 1060 /* 1061 * force "no valid mappings" on error in callback. 1062 */ | 1063 1064 map->len += minlen; 1065 resid -= minlen; 1066 } 1067 } 1068 1069 if (error) { 1070 /* 1071 * force "no valid mappings" on error in callback. 1072 */ |
1063 (*callback)(callback_arg, dm_segments, 0, 0, error); | 1073 (*callback)(callback_arg, dmat->segments, 0, 0, error); |
1064 } else { | 1074 } else { |
1065 (*callback)(callback_arg, dm_segments, nsegs+1, | 1075 (*callback)(callback_arg, dmat->segments, nsegs+1, |
1066 uio->uio_resid, error); 1067 } 1068 1069 CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d", 1070 __func__, dmat, dmat->flags, error, nsegs + 1); 1071 return (error); 1072} 1073 --- 419 unchanged lines hidden --- | 1076 uio->uio_resid, error); 1077 } 1078 1079 CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d", 1080 __func__, dmat, dmat->flags, error, nsegs + 1); 1081 return (error); 1082} 1083 --- 419 unchanged lines hidden --- |