Deleted Added
full compact
busdma_machdep-v4.c (137758) busdma_machdep-v4.c (137760)
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 137758 2004-11-15 23:59:28Z cognet $");
32__FBSDID("$FreeBSD: head/sys/arm/arm/busdma_machdep.c 137760 2004-11-16 00:57:44Z cognet $");
33
34/*
35 * MacPPC bus dma support routines
36 */
37
38#define _ARM32_BUS_DMA_PRIVATE
39#include <sys/param.h>
40#include <sys/systm.h>

--- 54 unchanged lines hidden (view full) ---

95
96/*
97 * Check to see if the specified page is in an allowed DMA range.
98 */
99
100static __inline int
101bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dma_segment_t segs[],
102 bus_dmamap_t map, void *buf, bus_size_t buflen, struct pmap *pmap,
33
34/*
35 * MacPPC bus dma support routines
36 */
37
38#define _ARM32_BUS_DMA_PRIVATE
39#include <sys/param.h>
40#include <sys/systm.h>

--- 54 unchanged lines hidden (view full) ---

95
96/*
97 * Check to see if the specified page is in an allowed DMA range.
98 */
99
100static __inline int
101bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dma_segment_t segs[],
102 bus_dmamap_t map, void *buf, bus_size_t buflen, struct pmap *pmap,
103 int flags, vm_offset_t *lastaddrp, int *segp,
104 int first);
103 int flags, vm_offset_t *lastaddrp, int *segp);
105
106static __inline struct arm32_dma_range *
107_bus_dma_inrange(struct arm32_dma_range *ranges, int nranges,
108 bus_addr_t curaddr)
109{
110 struct arm32_dma_range *dr;
111 int i;
112

--- 249 unchanged lines hidden (view full) ---

362 * Map the buffer buf into bus space using the dmamap map.
363 */
364int
365bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
366 bus_size_t buflen, bus_dmamap_callback_t *callback,
367 void *callback_arg, int flags)
368{
369 vm_offset_t lastaddr = 0;
104
105static __inline struct arm32_dma_range *
106_bus_dma_inrange(struct arm32_dma_range *ranges, int nranges,
107 bus_addr_t curaddr)
108{
109 struct arm32_dma_range *dr;
110 int i;
111

--- 249 unchanged lines hidden (view full) ---

361 * Map the buffer buf into bus space using the dmamap map.
362 */
363int
364bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
365 bus_size_t buflen, bus_dmamap_callback_t *callback,
366 void *callback_arg, int flags)
367{
368 vm_offset_t lastaddr = 0;
370 int error, nsegs = 0;
369 int error, nsegs = -1;
371#ifdef __GNUC__
372 bus_dma_segment_t dm_segments[dmat->nsegments];
373#else
374 bus_dma_segment_t dm_segments[BUS_DMAMAP_NSEGS];
375#endif
376
377 map->flags &= ~DMAMAP_TYPE_MASK;
378 map->flags |= DMAMAP_LINEAR|DMAMAP_COHERENT;
379 map->buffer = buf;
380 map->len = buflen;
381 error = bus_dmamap_load_buffer(dmat,
382 dm_segments, map, buf, buflen, kernel_pmap,
370#ifdef __GNUC__
371 bus_dma_segment_t dm_segments[dmat->nsegments];
372#else
373 bus_dma_segment_t dm_segments[BUS_DMAMAP_NSEGS];
374#endif
375
376 map->flags &= ~DMAMAP_TYPE_MASK;
377 map->flags |= DMAMAP_LINEAR|DMAMAP_COHERENT;
378 map->buffer = buf;
379 map->len = buflen;
380 error = bus_dmamap_load_buffer(dmat,
381 dm_segments, map, buf, buflen, kernel_pmap,
383 flags, &lastaddr, &nsegs, 1);
382 flags, &lastaddr, &nsegs);
384 if (error)
385 (*callback)(callback_arg, NULL, 0, error);
386 else
387 (*callback)(callback_arg, dm_segments, nsegs + 1, error);
388
389 return (0);
390}
391
392/*
393 * Utility function to load a linear buffer. lastaddrp holds state
394 * between invocations (for multiple-buffer loads). segp contains
395 * the starting segment on entrance, and the ending segment on exit.
396 * first indicates if this is the first invocation of this function.
397 */
398static int __inline
399bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dma_segment_t segs[],
400 bus_dmamap_t map, void *buf, bus_size_t buflen, struct pmap *pmap,
383 if (error)
384 (*callback)(callback_arg, NULL, 0, error);
385 else
386 (*callback)(callback_arg, dm_segments, nsegs + 1, error);
387
388 return (0);
389}
390
391/*
392 * Utility function to load a linear buffer. lastaddrp holds state
393 * between invocations (for multiple-buffer loads). segp contains
394 * the starting segment on entrance, and the ending segment on exit.
395 * first indicates if this is the first invocation of this function.
396 */
397static int __inline
398bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dma_segment_t segs[],
399 bus_dmamap_t map, void *buf, bus_size_t buflen, struct pmap *pmap,
401 int flags, vm_offset_t *lastaddrp, int *segp,
402 int first)
400 int flags, vm_offset_t *lastaddrp, int *segp)
403{
404 bus_size_t sgsize;
405 bus_addr_t curaddr, lastaddr, baddr, bmask;
406 vm_offset_t vaddr = (vm_offset_t)buf;
407 int seg;
408 int error = 0;
409 pd_entry_t *pde;
410 pt_entry_t pte;

--- 74 unchanged lines hidden (view full) ---

485 if (sgsize > (baddr - curaddr))
486 sgsize = (baddr - curaddr);
487 }
488
489 /*
490 * Insert chunk into a segment, coalescing with
491 * the previous segment if possible.
492 */
401{
402 bus_size_t sgsize;
403 bus_addr_t curaddr, lastaddr, baddr, bmask;
404 vm_offset_t vaddr = (vm_offset_t)buf;
405 int seg;
406 int error = 0;
407 pd_entry_t *pde;
408 pt_entry_t pte;

--- 74 unchanged lines hidden (view full) ---

483 if (sgsize > (baddr - curaddr))
484 sgsize = (baddr - curaddr);
485 }
486
487 /*
488 * Insert chunk into a segment, coalescing with
489 * the previous segment if possible.
490 */
493 if (first) {
491 if (seg >= 0 && curaddr == lastaddr &&
492 (segs[seg].ds_len + sgsize) <= dmat->maxsegsz &&
493 (dmat->boundary == 0 ||
494 (segs[seg].ds_addr & bmask) ==
495 (curaddr & bmask))) {
496 segs[seg].ds_len += sgsize;
497 goto segdone;
498 } else {
499 if (++seg >= dmat->nsegments)
500 break;
494 segs[seg].ds_addr = curaddr;
495 segs[seg].ds_len = sgsize;
501 segs[seg].ds_addr = curaddr;
502 segs[seg].ds_len = sgsize;
496 first = 0;
497 } else {
498 if (curaddr == lastaddr &&
499 (segs[seg].ds_len + sgsize) <= dmat->maxsegsz &&
500 (dmat->boundary == 0 ||
501 (segs[seg].ds_addr & bmask) ==
502 (curaddr & bmask))) {
503 segs[seg].ds_len += sgsize;
504 goto segdone;
505 }
506 else {
507 if (++seg >= dmat->nsegments)
508 break;
509 segs[seg].ds_addr = curaddr;
510 segs[seg].ds_len = sgsize;
511 }
512 }
503 }
513
514 if (error)
515 break;
516segdone:
517 lastaddr = curaddr + sgsize;
518 vaddr += sgsize;
519 buflen -= sgsize;
520 }
521

--- 16 unchanged lines hidden (view full) ---

538 bus_dmamap_callback2_t *callback, void *callback_arg,
539 int flags)
540{
541#ifdef __GNUC__
542 bus_dma_segment_t dm_segments[dmat->nsegments];
543#else
544 bus_dma_segment_t dm_segments[BUS_DMAMAP_NSEGS];
545#endif
504 if (error)
505 break;
506segdone:
507 lastaddr = curaddr + sgsize;
508 vaddr += sgsize;
509 buflen -= sgsize;
510 }
511

--- 16 unchanged lines hidden (view full) ---

528 bus_dmamap_callback2_t *callback, void *callback_arg,
529 int flags)
530{
531#ifdef __GNUC__
532 bus_dma_segment_t dm_segments[dmat->nsegments];
533#else
534 bus_dma_segment_t dm_segments[BUS_DMAMAP_NSEGS];
535#endif
546 int nsegs = 0, error = 0;
536 int nsegs = -1, error = 0;
547
548 M_ASSERTPKTHDR(m0);
549
550 map->flags &= ~DMAMAP_TYPE_MASK;
551 map->flags |= DMAMAP_MBUF | DMAMAP_COHERENT;
552 map->buffer = m0;
553 if (m0->m_pkthdr.len <= dmat->maxsize) {
537
538 M_ASSERTPKTHDR(m0);
539
540 map->flags &= ~DMAMAP_TYPE_MASK;
541 map->flags |= DMAMAP_MBUF | DMAMAP_COHERENT;
542 map->buffer = m0;
543 if (m0->m_pkthdr.len <= dmat->maxsize) {
554 int first = 1;
555 vm_offset_t lastaddr = 0;
556 struct mbuf *m;
557
558 for (m = m0; m != NULL && error == 0; m = m->m_next) {
544 vm_offset_t lastaddr = 0;
545 struct mbuf *m;
546
547 for (m = m0; m != NULL && error == 0; m = m->m_next) {
559 if (m->m_len > 0) {
548 if (m->m_len > 0)
560 error = bus_dmamap_load_buffer(dmat,
561 dm_segments, map, m->m_data, m->m_len,
549 error = bus_dmamap_load_buffer(dmat,
550 dm_segments, map, m->m_data, m->m_len,
562 pmap_kernel(), flags, &lastaddr, &nsegs,
563 first);
564 first = 0;
565 }
551 pmap_kernel(), flags, &lastaddr, &nsegs);
566 }
567 } else {
568 error = EINVAL;
569 }
570
571 if (error) {
572 /*
573 * force "no valid mappings" on error in callback.

--- 15 unchanged lines hidden (view full) ---

589 int flags)
590{
591 vm_offset_t lastaddr;
592#ifdef __GNUC__
593 bus_dma_segment_t dm_segments[dmat->nsegments];
594#else
595 bus_dma_segment_t dm_segments[BUS_DMAMAP_NSEGS];
596#endif
552 }
553 } else {
554 error = EINVAL;
555 }
556
557 if (error) {
558 /*
559 * force "no valid mappings" on error in callback.

--- 15 unchanged lines hidden (view full) ---

575 int flags)
576{
577 vm_offset_t lastaddr;
578#ifdef __GNUC__
579 bus_dma_segment_t dm_segments[dmat->nsegments];
580#else
581 bus_dma_segment_t dm_segments[BUS_DMAMAP_NSEGS];
582#endif
597 int nsegs, i, error, first;
583 int nsegs, i, error;
598 bus_size_t resid;
599 struct iovec *iov;
600 struct pmap *pmap;
601
602 resid = uio->uio_resid;
603 iov = uio->uio_iov;
604 map->flags &= ~DMAMAP_TYPE_MASK;
605 map->flags |= DMAMAP_UIO|DMAMAP_COHERENT;
606 map->buffer = uio;
607
608 if (uio->uio_segflg == UIO_USERSPACE) {
609 pmap = vmspace_pmap(uio->uio_td->td_proc->p_vmspace);
610 KASSERT(td != NULL,
611 ("bus_dmamap_load_uio: USERSPACE but no proc"));
612 } else
613 pmap = kernel_pmap;
614
584 bus_size_t resid;
585 struct iovec *iov;
586 struct pmap *pmap;
587
588 resid = uio->uio_resid;
589 iov = uio->uio_iov;
590 map->flags &= ~DMAMAP_TYPE_MASK;
591 map->flags |= DMAMAP_UIO|DMAMAP_COHERENT;
592 map->buffer = uio;
593
594 if (uio->uio_segflg == UIO_USERSPACE) {
595 pmap = vmspace_pmap(uio->uio_td->td_proc->p_vmspace);
596 KASSERT(td != NULL,
597 ("bus_dmamap_load_uio: USERSPACE but no proc"));
598 } else
599 pmap = kernel_pmap;
600
615 first = 1;
616 nsegs = error = 0;
601 error = 0;
602 nsegs = -1;
617 for (i = 0; i < uio->uio_iovcnt && resid != 0 && !error; i++) {
618 /*
619 * Now at the first iovec to load. Load each iovec
620 * until we have exhausted the residual count.
621 */
622 bus_size_t minlen =
623 resid < iov[i].iov_len ? resid : iov[i].iov_len;
624 caddr_t addr = (caddr_t) iov[i].iov_base;
625
626 if (minlen > 0) {
627 error = bus_dmamap_load_buffer(dmat, dm_segments, map,
603 for (i = 0; i < uio->uio_iovcnt && resid != 0 && !error; i++) {
604 /*
605 * Now at the first iovec to load. Load each iovec
606 * until we have exhausted the residual count.
607 */
608 bus_size_t minlen =
609 resid < iov[i].iov_len ? resid : iov[i].iov_len;
610 caddr_t addr = (caddr_t) iov[i].iov_base;
611
612 if (minlen > 0) {
613 error = bus_dmamap_load_buffer(dmat, dm_segments, map,
628 addr, minlen, pmap, flags, &lastaddr, &nsegs,
629 first);
614 addr, minlen, pmap, flags, &lastaddr, &nsegs);
630
615
631 first = 0;
632
633 resid -= minlen;
634 }
635 }
636
637 if (error) {
638 /*
639 * force "no valid mappings" on error in callback.
640 */

--- 80 unchanged lines hidden ---
616 resid -= minlen;
617 }
618 }
619
620 if (error) {
621 /*
622 * force "no valid mappings" on error in callback.
623 */

--- 80 unchanged lines hidden ---