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