busdma_machdep.c (112436) | busdma_machdep.c (112569) |
---|---|
1/* 2 * Copyright (c) 1997, 1998 Justin T. Gibbs. 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 --- 9 unchanged lines hidden (view full) --- 18 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 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 * | 1/* 2 * Copyright (c) 1997, 1998 Justin T. Gibbs. 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 --- 9 unchanged lines hidden (view full) --- 18 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 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 * $FreeBSD: head/sys/i386/i386/busdma_machdep.c 112436 2003-03-20 19:45:26Z mux $ | 26 * $FreeBSD: head/sys/i386/i386/busdma_machdep.c 112569 2003-03-25 00:07:06Z jake $ |
27 */ 28 29#include <sys/param.h> 30#include <sys/systm.h> 31#include <sys/malloc.h> 32#include <sys/bus.h> 33#include <sys/interrupt.h> 34#include <sys/kernel.h> --- 60 unchanged lines hidden (view full) --- 95 96static STAILQ_HEAD(, bus_dmamap) bounce_map_waitinglist; 97static STAILQ_HEAD(, bus_dmamap) bounce_map_callbacklist; 98static struct bus_dmamap nobounce_dmamap; 99 100static void init_bounce_pages(void *dummy); 101static int alloc_bounce_pages(bus_dma_tag_t dmat, u_int numpages); 102static int reserve_bounce_pages(bus_dma_tag_t dmat, bus_dmamap_t map); | 27 */ 28 29#include <sys/param.h> 30#include <sys/systm.h> 31#include <sys/malloc.h> 32#include <sys/bus.h> 33#include <sys/interrupt.h> 34#include <sys/kernel.h> --- 60 unchanged lines hidden (view full) --- 95 96static STAILQ_HEAD(, bus_dmamap) bounce_map_waitinglist; 97static STAILQ_HEAD(, bus_dmamap) bounce_map_callbacklist; 98static struct bus_dmamap nobounce_dmamap; 99 100static void init_bounce_pages(void *dummy); 101static int alloc_bounce_pages(bus_dma_tag_t dmat, u_int numpages); 102static int reserve_bounce_pages(bus_dma_tag_t dmat, bus_dmamap_t map); |
103static vm_offset_t add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, | 103static bus_addr_t add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, |
104 vm_offset_t vaddr, bus_size_t size); 105static void free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage); 106static __inline int run_filter(bus_dma_tag_t dmat, bus_addr_t paddr); 107 108/* To protect all the the bounce pages related lists and data. */ 109static struct mtx bounce_lock; 110 111/* --- 41 unchanged lines hidden (view full) --- 153 154 newtag = (bus_dma_tag_t)malloc(sizeof(*newtag), M_DEVBUF, M_NOWAIT); 155 if (newtag == NULL) 156 return (ENOMEM); 157 158 newtag->parent = parent; 159 newtag->alignment = alignment; 160 newtag->boundary = boundary; | 104 vm_offset_t vaddr, bus_size_t size); 105static void free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage); 106static __inline int run_filter(bus_dma_tag_t dmat, bus_addr_t paddr); 107 108/* To protect all the the bounce pages related lists and data. */ 109static struct mtx bounce_lock; 110 111/* --- 41 unchanged lines hidden (view full) --- 153 154 newtag = (bus_dma_tag_t)malloc(sizeof(*newtag), M_DEVBUF, M_NOWAIT); 155 if (newtag == NULL) 156 return (ENOMEM); 157 158 newtag->parent = parent; 159 newtag->alignment = alignment; 160 newtag->boundary = boundary; |
161 newtag->lowaddr = trunc_page((vm_offset_t)lowaddr) + (PAGE_SIZE - 1); 162 newtag->highaddr = trunc_page((vm_offset_t)highaddr) + (PAGE_SIZE - 1); | 161 newtag->lowaddr = trunc_page((vm_paddr_t)lowaddr) + (PAGE_SIZE - 1); 162 newtag->highaddr = trunc_page((vm_paddr_t)highaddr) + 163 (PAGE_SIZE - 1); |
163 newtag->filter = filter; 164 newtag->filterarg = filterarg; 165 newtag->maxsize = maxsize; 166 newtag->nsegments = nsegments; 167 newtag->maxsegsz = maxsegsz; 168 newtag->flags = flags; 169 newtag->ref_count = 1; /* Count ourself */ 170 newtag->map_count = 0; --- 15 unchanged lines hidden (view full) --- 186 newtag->filter = parent->filter; 187 newtag->filterarg = parent->filterarg; 188 newtag->parent = parent->parent; 189 } 190 if (newtag->parent != NULL) 191 atomic_add_int(&parent->ref_count, 1); 192 } 193 | 164 newtag->filter = filter; 165 newtag->filterarg = filterarg; 166 newtag->maxsize = maxsize; 167 newtag->nsegments = nsegments; 168 newtag->maxsegsz = maxsegsz; 169 newtag->flags = flags; 170 newtag->ref_count = 1; /* Count ourself */ 171 newtag->map_count = 0; --- 15 unchanged lines hidden (view full) --- 187 newtag->filter = parent->filter; 188 newtag->filterarg = parent->filterarg; 189 newtag->parent = parent->parent; 190 } 191 if (newtag->parent != NULL) 192 atomic_add_int(&parent->ref_count, 1); 193 } 194 |
194 if (newtag->lowaddr < ptoa(Maxmem) && (flags & BUS_DMA_ALLOCNOW) != 0) { | 195 if (newtag->lowaddr < ptoa((vm_paddr_t)Maxmem) && 196 (flags & BUS_DMA_ALLOCNOW) != 0) { |
195 /* Must bounce */ 196 197 if (lowaddr > bounce_lowaddr) { 198 /* 199 * Go through the pool and kill any pages 200 * that don't reside below lowaddr. 201 */ 202 panic("bus_dma_tag_create: page reallocation " --- 54 unchanged lines hidden (view full) --- 257 */ 258int 259bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp) 260{ 261 int error; 262 263 error = 0; 264 | 197 /* Must bounce */ 198 199 if (lowaddr > bounce_lowaddr) { 200 /* 201 * Go through the pool and kill any pages 202 * that don't reside below lowaddr. 203 */ 204 panic("bus_dma_tag_create: page reallocation " --- 54 unchanged lines hidden (view full) --- 259 */ 260int 261bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp) 262{ 263 int error; 264 265 error = 0; 266 |
265 if (dmat->lowaddr < ptoa(Maxmem)) { | 267 if (dmat->lowaddr < ptoa((vm_paddr_t)Maxmem)) { |
266 /* Must bounce */ 267 int maxpages; 268 269 *mapp = (bus_dmamap_t)malloc(sizeof(**mapp), M_DEVBUF, 270 M_NOWAIT | M_ZERO); 271 if (*mapp == NULL) 272 return (ENOMEM); 273 --- 65 unchanged lines hidden (view full) --- 339{ 340 341 if (size > dmat->maxsize) 342 return (ENOMEM); 343 344 /* If we succeed, no mapping/bouncing will be required */ 345 *mapp = NULL; 346 | 268 /* Must bounce */ 269 int maxpages; 270 271 *mapp = (bus_dmamap_t)malloc(sizeof(**mapp), M_DEVBUF, 272 M_NOWAIT | M_ZERO); 273 if (*mapp == NULL) 274 return (ENOMEM); 275 --- 65 unchanged lines hidden (view full) --- 341{ 342 343 if (size > dmat->maxsize) 344 return (ENOMEM); 345 346 /* If we succeed, no mapping/bouncing will be required */ 347 *mapp = NULL; 348 |
347 if ((size <= PAGE_SIZE) && dmat->lowaddr >= ptoa(Maxmem)) { | 349 if ((size <= PAGE_SIZE) && 350 dmat->lowaddr >= ptoa((vm_paddr_t)Maxmem)) { |
348 *vaddr = malloc(size, M_DEVBUF, 349 (flags & BUS_DMA_NOWAIT) ? M_NOWAIT : M_WAITOK); 350 } else { 351 /* 352 * XXX Use Contigmalloc until it is merged into this facility 353 * and handles multi-seg allocations. Nobody is doing 354 * multi-seg allocations yet though. 355 */ --- 25 unchanged lines hidden (view full) --- 381 bus_size_t size) 382{ 383 /* 384 * dmamem does not need to be bounced, so the map should be 385 * NULL 386 */ 387 if (map != NULL) 388 panic("bus_dmamem_free: Invalid map freed\n"); | 351 *vaddr = malloc(size, M_DEVBUF, 352 (flags & BUS_DMA_NOWAIT) ? M_NOWAIT : M_WAITOK); 353 } else { 354 /* 355 * XXX Use Contigmalloc until it is merged into this facility 356 * and handles multi-seg allocations. Nobody is doing 357 * multi-seg allocations yet though. 358 */ --- 25 unchanged lines hidden (view full) --- 384 bus_size_t size) 385{ 386 /* 387 * dmamem does not need to be bounced, so the map should be 388 * NULL 389 */ 390 if (map != NULL) 391 panic("bus_dmamem_free: Invalid map freed\n"); |
389 if ((size <= PAGE_SIZE) && dmat->lowaddr >= ptoa(Maxmem)) | 392 if ((size <= PAGE_SIZE) && dmat->lowaddr >= ptoa((vm_paddr_t)Maxmem)) |
390 free(vaddr, M_DEVBUF); 391 else { 392 mtx_lock(&Giant); 393 contigfree(vaddr, size, M_DEVBUF); 394 mtx_unlock(&Giant); 395 } 396} 397 --- 9 unchanged lines hidden (view full) --- 407 * Map the buffer buf into bus space using the dmamap map. 408 */ 409int 410bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, 411 bus_size_t buflen, bus_dmamap_callback_t *callback, 412 void *callback_arg, int flags) 413{ 414 vm_offset_t vaddr; | 393 free(vaddr, M_DEVBUF); 394 else { 395 mtx_lock(&Giant); 396 contigfree(vaddr, size, M_DEVBUF); 397 mtx_unlock(&Giant); 398 } 399} 400 --- 9 unchanged lines hidden (view full) --- 410 * Map the buffer buf into bus space using the dmamap map. 411 */ 412int 413bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, 414 bus_size_t buflen, bus_dmamap_callback_t *callback, 415 void *callback_arg, int flags) 416{ 417 vm_offset_t vaddr; |
415 vm_offset_t paddr; | 418 vm_paddr_t paddr; |
416#ifdef __GNUC__ 417 bus_dma_segment_t dm_segments[dmat->nsegments]; 418#else 419 bus_dma_segment_t dm_segments[BUS_DMAMAP_NSEGS]; 420#endif 421 bus_dma_segment_t *sg; 422 int seg; 423 int error; | 419#ifdef __GNUC__ 420 bus_dma_segment_t dm_segments[dmat->nsegments]; 421#else 422 bus_dma_segment_t dm_segments[BUS_DMAMAP_NSEGS]; 423#endif 424 bus_dma_segment_t *sg; 425 int seg; 426 int error; |
424 vm_offset_t nextpaddr; | 427 vm_paddr_t nextpaddr; |
425 426 if (map == NULL) 427 map = &nobounce_dmamap; 428 429 error = 0; 430 /* 431 * If we are being called during a callback, pagesneeded will 432 * be non-zero, so we can avoid doing the work twice. 433 */ | 428 429 if (map == NULL) 430 map = &nobounce_dmamap; 431 432 error = 0; 433 /* 434 * If we are being called during a callback, pagesneeded will 435 * be non-zero, so we can avoid doing the work twice. 436 */ |
434 if (dmat->lowaddr < ptoa(Maxmem) && map->pagesneeded == 0) { | 437 if (dmat->lowaddr < ptoa((vm_paddr_t)Maxmem) && 438 map->pagesneeded == 0) { |
435 vm_offset_t vendaddr; 436 437 /* 438 * Count the number of bounce pages 439 * needed in order to complete this transfer 440 */ 441 vaddr = trunc_page((vm_offset_t)buf); 442 vendaddr = (vm_offset_t)buf + buflen; --- 178 unchanged lines hidden (view full) --- 621{ 622#ifdef __GNUC__ 623 bus_dma_segment_t dm_segments[dmat->nsegments]; 624#else 625 bus_dma_segment_t dm_segments[BUS_DMAMAP_NSEGS]; 626#endif 627 int nsegs, error; 628 | 439 vm_offset_t vendaddr; 440 441 /* 442 * Count the number of bounce pages 443 * needed in order to complete this transfer 444 */ 445 vaddr = trunc_page((vm_offset_t)buf); 446 vendaddr = (vm_offset_t)buf + buflen; --- 178 unchanged lines hidden (view full) --- 625{ 626#ifdef __GNUC__ 627 bus_dma_segment_t dm_segments[dmat->nsegments]; 628#else 629 bus_dma_segment_t dm_segments[BUS_DMAMAP_NSEGS]; 630#endif 631 int nsegs, error; 632 |
629 KASSERT(dmat->lowaddr >= ptoa(Maxmem) || map != NULL, | 633 KASSERT(dmat->lowaddr >= ptoa((vm_paddr_t)Maxmem) || map != NULL, |
630 ("bus_dmamap_load_mbuf: No support for bounce pages!")); 631 KASSERT(m0->m_flags & M_PKTHDR, 632 ("bus_dmamap_load_mbuf: no packet header")); 633 634 nsegs = 0; 635 error = 0; 636 if (m0->m_pkthdr.len <= dmat->maxsize) { 637 int first = 1; --- 39 unchanged lines hidden (view full) --- 677#else 678 bus_dma_segment_t dm_segments[BUS_DMAMAP_NSEGS]; 679#endif 680 int nsegs, error, first, i; 681 bus_size_t resid; 682 struct iovec *iov; 683 struct thread *td = NULL; 684 | 634 ("bus_dmamap_load_mbuf: No support for bounce pages!")); 635 KASSERT(m0->m_flags & M_PKTHDR, 636 ("bus_dmamap_load_mbuf: no packet header")); 637 638 nsegs = 0; 639 error = 0; 640 if (m0->m_pkthdr.len <= dmat->maxsize) { 641 int first = 1; --- 39 unchanged lines hidden (view full) --- 681#else 682 bus_dma_segment_t dm_segments[BUS_DMAMAP_NSEGS]; 683#endif 684 int nsegs, error, first, i; 685 bus_size_t resid; 686 struct iovec *iov; 687 struct thread *td = NULL; 688 |
685 KASSERT(dmat->lowaddr >= ptoa(Maxmem) || map != NULL, | 689 KASSERT(dmat->lowaddr >= ptoa((vm_paddr_t)Maxmem) || map != NULL, |
686 ("bus_dmamap_load_uio: No support for bounce pages!")); 687 688 resid = uio->uio_resid; 689 iov = uio->uio_iov; 690 691 if (uio->uio_segflg == UIO_USERSPACE) { 692 td = uio->uio_td; 693 KASSERT(td != NULL, --- 147 unchanged lines hidden (view full) --- 841 free_bpages -= pages; 842 reserved_bpages += pages; 843 map->pagesreserved += pages; 844 pages = map->pagesneeded - map->pagesreserved; 845 846 return (pages); 847} 848 | 690 ("bus_dmamap_load_uio: No support for bounce pages!")); 691 692 resid = uio->uio_resid; 693 iov = uio->uio_iov; 694 695 if (uio->uio_segflg == UIO_USERSPACE) { 696 td = uio->uio_td; 697 KASSERT(td != NULL, --- 147 unchanged lines hidden (view full) --- 845 free_bpages -= pages; 846 reserved_bpages += pages; 847 map->pagesreserved += pages; 848 pages = map->pagesneeded - map->pagesreserved; 849 850 return (pages); 851} 852 |
849static vm_offset_t | 853static bus_addr_t |
850add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, vm_offset_t vaddr, 851 bus_size_t size) 852{ 853 struct bounce_page *bpage; 854 855 if (map->pagesneeded == 0) 856 panic("add_bounce_page: map doesn't need any pages"); 857 map->pagesneeded--; --- 60 unchanged lines hidden --- | 854add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, vm_offset_t vaddr, 855 bus_size_t size) 856{ 857 struct bounce_page *bpage; 858 859 if (map->pagesneeded == 0) 860 panic("add_bounce_page: map doesn't need any pages"); 861 map->pagesneeded--; --- 60 unchanged lines hidden --- |