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 --- |