Deleted Added
full compact
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 ---