busdma_machdep.c (232356) | busdma_machdep.c (240177) |
---|---|
1/*- 2 * Copyright (c) 2006 Oleksandr Tymoshenko 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 13 unchanged lines hidden (view full) --- 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * From i386/busdma_machdep.c,v 1.26 2002/04/19 22:58:09 alfred 27 */ 28 29#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2006 Oleksandr Tymoshenko 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 13 unchanged lines hidden (view full) --- 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * From i386/busdma_machdep.c,v 1.26 2002/04/19 22:58:09 alfred 27 */ 28 29#include <sys/cdefs.h> |
30__FBSDID("$FreeBSD: head/sys/mips/mips/busdma_machdep.c 232356 2012-03-01 19:58:34Z jhb $"); | 30__FBSDID("$FreeBSD: head/sys/mips/mips/busdma_machdep.c 240177 2012-09-06 20:16:59Z jhb $"); |
31 32/* 33 * MIPS bus dma support routines 34 */ 35 36#include <sys/param.h> 37#include <sys/systm.h> 38#include <sys/malloc.h> --- 36 unchanged lines hidden (view full) --- 75 bus_size_t maxsize; 76 u_int nsegments; 77 bus_size_t maxsegsz; 78 int flags; 79 int ref_count; 80 int map_count; 81 bus_dma_lock_t *lockfunc; 82 void *lockfuncarg; | 31 32/* 33 * MIPS bus dma support routines 34 */ 35 36#include <sys/param.h> 37#include <sys/systm.h> 38#include <sys/malloc.h> --- 36 unchanged lines hidden (view full) --- 75 bus_size_t maxsize; 76 u_int nsegments; 77 bus_size_t maxsegsz; 78 int flags; 79 int ref_count; 80 int map_count; 81 bus_dma_lock_t *lockfunc; 82 void *lockfuncarg; |
83 bus_dma_segment_t *segments; |
|
83 struct bounce_zone *bounce_zone; 84}; 85 86struct bounce_page { 87 vm_offset_t vaddr; /* kva of bounce buffer */ 88 vm_offset_t vaddr_nocache; /* kva of bounce buffer uncached */ 89 bus_addr_t busaddr; /* Physical address */ 90 vm_offset_t datavaddr; /* kva of client data */ --- 256 unchanged lines hidden (view full) --- 347 newtag->map_count = 0; 348 if (lockfunc != NULL) { 349 newtag->lockfunc = lockfunc; 350 newtag->lockfuncarg = lockfuncarg; 351 } else { 352 newtag->lockfunc = dflt_lock; 353 newtag->lockfuncarg = NULL; 354 } | 84 struct bounce_zone *bounce_zone; 85}; 86 87struct bounce_page { 88 vm_offset_t vaddr; /* kva of bounce buffer */ 89 vm_offset_t vaddr_nocache; /* kva of bounce buffer uncached */ 90 bus_addr_t busaddr; /* Physical address */ 91 vm_offset_t datavaddr; /* kva of client data */ --- 256 unchanged lines hidden (view full) --- 348 newtag->map_count = 0; 349 if (lockfunc != NULL) { 350 newtag->lockfunc = lockfunc; 351 newtag->lockfuncarg = lockfuncarg; 352 } else { 353 newtag->lockfunc = dflt_lock; 354 newtag->lockfuncarg = NULL; 355 } |
356 newtag->segments = NULL; 357 |
|
355 /* 356 * Take into account any restrictions imposed by our parent tag 357 */ 358 if (parent != NULL) { 359 newtag->lowaddr = MIN(parent->lowaddr, newtag->lowaddr); 360 newtag->highaddr = MAX(parent->highaddr, newtag->highaddr); 361 if (newtag->boundary == 0) 362 newtag->boundary = parent->boundary; --- 66 unchanged lines hidden (view full) --- 429 return (EBUSY); 430 431 while (dmat != NULL) { 432 bus_dma_tag_t parent; 433 434 parent = dmat->parent; 435 atomic_subtract_int(&dmat->ref_count, 1); 436 if (dmat->ref_count == 0) { | 358 /* 359 * Take into account any restrictions imposed by our parent tag 360 */ 361 if (parent != NULL) { 362 newtag->lowaddr = MIN(parent->lowaddr, newtag->lowaddr); 363 newtag->highaddr = MAX(parent->highaddr, newtag->highaddr); 364 if (newtag->boundary == 0) 365 newtag->boundary = parent->boundary; --- 66 unchanged lines hidden (view full) --- 432 return (EBUSY); 433 434 while (dmat != NULL) { 435 bus_dma_tag_t parent; 436 437 parent = dmat->parent; 438 atomic_subtract_int(&dmat->ref_count, 1); 439 if (dmat->ref_count == 0) { |
440 if (dmat->segments != NULL) 441 free(dmat->segments, M_DEVBUF); |
|
437 free(dmat, M_DEVBUF); 438 /* 439 * Last reference count, so 440 * release our reference 441 * count on our parent. 442 */ 443 dmat = parent; 444 } else | 442 free(dmat, M_DEVBUF); 443 /* 444 * Last reference count, so 445 * release our reference 446 * count on our parent. 447 */ 448 dmat = parent; 449 } else |
445 dmat = NULL; | 450 dmat = NULL; |
446 } 447 } 448 CTR2(KTR_BUSDMA, "%s tag %p", __func__, dmat_copy); 449 450 return (0); 451} 452 453#include <sys/kdb.h> 454/* 455 * Allocate a handle for mapping from kva/uva/physical 456 * address space into bus device space. 457 */ 458int 459bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp) 460{ 461 bus_dmamap_t newmap; 462 int error = 0; 463 | 451 } 452 } 453 CTR2(KTR_BUSDMA, "%s tag %p", __func__, dmat_copy); 454 455 return (0); 456} 457 458#include <sys/kdb.h> 459/* 460 * Allocate a handle for mapping from kva/uva/physical 461 * address space into bus device space. 462 */ 463int 464bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp) 465{ 466 bus_dmamap_t newmap; 467 int error = 0; 468 |
469 if (dmat->segments == NULL) { 470 dmat->segments = (bus_dma_segment_t *)malloc( 471 sizeof(bus_dma_segment_t) * dmat->nsegments, M_DEVBUF, 472 M_NOWAIT); 473 if (dmat->segments == NULL) { 474 CTR3(KTR_BUSDMA, "%s: tag %p error %d", 475 __func__, dmat, ENOMEM); 476 return (ENOMEM); 477 } 478 } 479 |
|
464 newmap = _busdma_alloc_dmamap(); 465 if (newmap == NULL) { 466 CTR3(KTR_BUSDMA, "%s: tag %p error %d", __func__, dmat, ENOMEM); 467 return (ENOMEM); 468 } 469 *mapp = newmap; 470 newmap->dmat = dmat; 471 newmap->allocbuffer = NULL; --- 86 unchanged lines hidden (view full) --- 558 bus_dmamap_t newmap = NULL; 559 560 int mflags; 561 562 if (flags & BUS_DMA_NOWAIT) 563 mflags = M_NOWAIT; 564 else 565 mflags = M_WAITOK; | 480 newmap = _busdma_alloc_dmamap(); 481 if (newmap == NULL) { 482 CTR3(KTR_BUSDMA, "%s: tag %p error %d", __func__, dmat, ENOMEM); 483 return (ENOMEM); 484 } 485 *mapp = newmap; 486 newmap->dmat = dmat; 487 newmap->allocbuffer = NULL; --- 86 unchanged lines hidden (view full) --- 574 bus_dmamap_t newmap = NULL; 575 576 int mflags; 577 578 if (flags & BUS_DMA_NOWAIT) 579 mflags = M_NOWAIT; 580 else 581 mflags = M_WAITOK; |
582 if (dmat->segments == NULL) { 583 dmat->segments = (bus_dma_segment_t *)malloc( 584 sizeof(bus_dma_segment_t) * dmat->nsegments, M_DEVBUF, 585 mflags); 586 if (dmat->segments == NULL) { 587 CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d", 588 __func__, dmat, dmat->flags, ENOMEM); 589 return (ENOMEM); 590 } 591 } |
|
566 if (flags & BUS_DMA_ZERO) 567 mflags |= M_ZERO; 568 569 newmap = _busdma_alloc_dmamap(); 570 if (newmap == NULL) { 571 CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d", 572 __func__, dmat, dmat->flags, ENOMEM); 573 return (ENOMEM); --- 245 unchanged lines hidden (view full) --- 819 */ 820int 821bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, 822 bus_size_t buflen, bus_dmamap_callback_t *callback, 823 void *callback_arg, int flags) 824{ 825 vm_offset_t lastaddr = 0; 826 int error, nsegs = -1; | 592 if (flags & BUS_DMA_ZERO) 593 mflags |= M_ZERO; 594 595 newmap = _busdma_alloc_dmamap(); 596 if (newmap == NULL) { 597 CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d", 598 __func__, dmat, dmat->flags, ENOMEM); 599 return (ENOMEM); --- 245 unchanged lines hidden (view full) --- 845 */ 846int 847bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, 848 bus_size_t buflen, bus_dmamap_callback_t *callback, 849 void *callback_arg, int flags) 850{ 851 vm_offset_t lastaddr = 0; 852 int error, nsegs = -1; |
827#ifdef __CC_SUPPORTS_DYNAMIC_ARRAY_INIT 828 bus_dma_segment_t dm_segments[dmat->nsegments]; 829#else 830 bus_dma_segment_t dm_segments[BUS_DMAMAP_NSEGS]; 831#endif | |
832 833 KASSERT(dmat != NULL, ("dmatag is NULL")); 834 KASSERT(map != NULL, ("dmamap is NULL")); 835 map->callback = callback; 836 map->callback_arg = callback_arg; 837 map->flags &= ~DMAMAP_TYPE_MASK; 838 map->flags |= DMAMAP_LINEAR; 839 map->buffer = buf; 840 map->len = buflen; 841 error = bus_dmamap_load_buffer(dmat, | 853 854 KASSERT(dmat != NULL, ("dmatag is NULL")); 855 KASSERT(map != NULL, ("dmamap is NULL")); 856 map->callback = callback; 857 map->callback_arg = callback_arg; 858 map->flags &= ~DMAMAP_TYPE_MASK; 859 map->flags |= DMAMAP_LINEAR; 860 map->buffer = buf; 861 map->len = buflen; 862 error = bus_dmamap_load_buffer(dmat, |
842 dm_segments, map, buf, buflen, kernel_pmap, | 863 dmat->segments, map, buf, buflen, kernel_pmap, |
843 flags, &lastaddr, &nsegs); 844 if (error == EINPROGRESS) 845 return (error); 846 if (error) 847 (*callback)(callback_arg, NULL, 0, error); 848 else | 864 flags, &lastaddr, &nsegs); 865 if (error == EINPROGRESS) 866 return (error); 867 if (error) 868 (*callback)(callback_arg, NULL, 0, error); 869 else |
849 (*callback)(callback_arg, dm_segments, nsegs + 1, error); | 870 (*callback)(callback_arg, dmat->segments, nsegs + 1, error); |
850 851 CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d", 852 __func__, dmat, dmat->flags, nsegs + 1, error); 853 854 return (error); 855} 856 857/* 858 * Like bus_dmamap_load(), but for mbufs. 859 */ 860int 861bus_dmamap_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map, struct mbuf *m0, 862 bus_dmamap_callback2_t *callback, void *callback_arg, 863 int flags) 864{ | 871 872 CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d", 873 __func__, dmat, dmat->flags, nsegs + 1, error); 874 875 return (error); 876} 877 878/* 879 * Like bus_dmamap_load(), but for mbufs. 880 */ 881int 882bus_dmamap_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map, struct mbuf *m0, 883 bus_dmamap_callback2_t *callback, void *callback_arg, 884 int flags) 885{ |
865#ifdef __CC_SUPPORTS_DYNAMIC_ARRAY_INIT 866 bus_dma_segment_t dm_segments[dmat->nsegments]; 867#else 868 bus_dma_segment_t dm_segments[BUS_DMAMAP_NSEGS]; 869#endif | |
870 int nsegs = -1, error = 0; 871 872 M_ASSERTPKTHDR(m0); 873 874 map->flags &= ~DMAMAP_TYPE_MASK; 875 map->flags |= DMAMAP_MBUF; 876 map->buffer = m0; 877 map->len = 0; 878 if (m0->m_pkthdr.len <= dmat->maxsize) { 879 vm_offset_t lastaddr = 0; 880 struct mbuf *m; 881 882 for (m = m0; m != NULL && error == 0; m = m->m_next) { 883 if (m->m_len > 0) { 884 error = bus_dmamap_load_buffer(dmat, | 886 int nsegs = -1, error = 0; 887 888 M_ASSERTPKTHDR(m0); 889 890 map->flags &= ~DMAMAP_TYPE_MASK; 891 map->flags |= DMAMAP_MBUF; 892 map->buffer = m0; 893 map->len = 0; 894 if (m0->m_pkthdr.len <= dmat->maxsize) { 895 vm_offset_t lastaddr = 0; 896 struct mbuf *m; 897 898 for (m = m0; m != NULL && error == 0; m = m->m_next) { 899 if (m->m_len > 0) { 900 error = bus_dmamap_load_buffer(dmat, |
885 dm_segments, map, m->m_data, m->m_len, | 901 dmat->segments, map, m->m_data, m->m_len, |
886 kernel_pmap, flags, &lastaddr, &nsegs); 887 map->len += m->m_len; 888 } 889 } 890 } else { 891 error = EINVAL; 892 } 893 894 if (error) { 895 /* 896 * force "no valid mappings" on error in callback. 897 */ | 902 kernel_pmap, flags, &lastaddr, &nsegs); 903 map->len += m->m_len; 904 } 905 } 906 } else { 907 error = EINVAL; 908 } 909 910 if (error) { 911 /* 912 * force "no valid mappings" on error in callback. 913 */ |
898 (*callback)(callback_arg, dm_segments, 0, 0, error); | 914 (*callback)(callback_arg, dmat->segments, 0, 0, error); |
899 } else { | 915 } else { |
900 (*callback)(callback_arg, dm_segments, nsegs + 1, | 916 (*callback)(callback_arg, dmat->segments, nsegs + 1, |
901 m0->m_pkthdr.len, error); 902 } 903 CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d", 904 __func__, dmat, dmat->flags, error, nsegs + 1); 905 906 return (error); 907} 908 --- 39 unchanged lines hidden (view full) --- 948 * Like bus_dmamap_load(), but for uios. 949 */ 950int 951bus_dmamap_load_uio(bus_dma_tag_t dmat, bus_dmamap_t map, struct uio *uio, 952 bus_dmamap_callback2_t *callback, void *callback_arg, 953 int flags) 954{ 955 vm_offset_t lastaddr = 0; | 917 m0->m_pkthdr.len, error); 918 } 919 CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d", 920 __func__, dmat, dmat->flags, error, nsegs + 1); 921 922 return (error); 923} 924 --- 39 unchanged lines hidden (view full) --- 964 * Like bus_dmamap_load(), but for uios. 965 */ 966int 967bus_dmamap_load_uio(bus_dma_tag_t dmat, bus_dmamap_t map, struct uio *uio, 968 bus_dmamap_callback2_t *callback, void *callback_arg, 969 int flags) 970{ 971 vm_offset_t lastaddr = 0; |
956#ifdef __CC_SUPPORTS_DYNAMIC_ARRAY_INIT 957 bus_dma_segment_t dm_segments[dmat->nsegments]; 958#else 959 bus_dma_segment_t dm_segments[BUS_DMAMAP_NSEGS]; 960#endif | |
961 int nsegs, i, error; 962 bus_size_t resid; 963 struct iovec *iov; 964 struct pmap *pmap; 965 966 resid = uio->uio_resid; 967 iov = uio->uio_iov; 968 map->flags &= ~DMAMAP_TYPE_MASK; --- 16 unchanged lines hidden (view full) --- 985 * Now at the first iovec to load. Load each iovec 986 * until we have exhausted the residual count. 987 */ 988 bus_size_t minlen = 989 resid < iov[i].iov_len ? resid : iov[i].iov_len; 990 caddr_t addr = (caddr_t) iov[i].iov_base; 991 992 if (minlen > 0) { | 972 int nsegs, i, error; 973 bus_size_t resid; 974 struct iovec *iov; 975 struct pmap *pmap; 976 977 resid = uio->uio_resid; 978 iov = uio->uio_iov; 979 map->flags &= ~DMAMAP_TYPE_MASK; --- 16 unchanged lines hidden (view full) --- 996 * Now at the first iovec to load. Load each iovec 997 * until we have exhausted the residual count. 998 */ 999 bus_size_t minlen = 1000 resid < iov[i].iov_len ? resid : iov[i].iov_len; 1001 caddr_t addr = (caddr_t) iov[i].iov_base; 1002 1003 if (minlen > 0) { |
993 error = bus_dmamap_load_buffer(dmat, dm_segments, map, 994 addr, minlen, pmap, flags, &lastaddr, &nsegs); | 1004 error = bus_dmamap_load_buffer(dmat, dmat->segments, 1005 map, addr, minlen, pmap, flags, &lastaddr, &nsegs); |
995 996 map->len += minlen; 997 resid -= minlen; 998 } 999 } 1000 1001 if (error) { 1002 /* 1003 * force "no valid mappings" on error in callback. 1004 */ | 1006 1007 map->len += minlen; 1008 resid -= minlen; 1009 } 1010 } 1011 1012 if (error) { 1013 /* 1014 * force "no valid mappings" on error in callback. 1015 */ |
1005 (*callback)(callback_arg, dm_segments, 0, 0, error); | 1016 (*callback)(callback_arg, dmat->segments, 0, 0, error); |
1006 } else { | 1017 } else { |
1007 (*callback)(callback_arg, dm_segments, nsegs+1, | 1018 (*callback)(callback_arg, dmat->segments, nsegs+1, |
1008 uio->uio_resid, error); 1009 } 1010 1011 CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d", 1012 __func__, dmat, dmat->flags, error, nsegs + 1); 1013 return (error); 1014} 1015 --- 462 unchanged lines hidden --- | 1019 uio->uio_resid, error); 1020 } 1021 1022 CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d", 1023 __func__, dmat, dmat->flags, error, nsegs + 1); 1024 return (error); 1025} 1026 --- 462 unchanged lines hidden --- |