Hi, If you are testing pmemrange (you really should be), please also run with this diff. It fixes problems with isadma on i386.
This is technically three diffs squashed together (bad oga! I know, but I need to do real work and this should fix pmemrange). 1) when you have a wrapper function in a dmatag that just calls the _bus_dmamem original, you don't need it, just put the original function in the tag 2) don't trunc_page the avail_end/ISA_BOUNCE_THRESHOLD stuff (see icb for a discussion of why this is wrong about 00:00 gmt). make i386 and amd64 both do this the same (the amd64 way is cleaner and makes the third diff actually possible without a lot of pain). just do dmamem_alloc_range(0, threshold) and if that fails do a alloc_range(0, -1) and assume we'll bounce to pick up the pieces. Also using avail_end for alloc_range is not nice (miod has been trying to avoid these abuses iirc), so just use (paddr_t)-1, which is equivalent since you want "any" memory. 3) now this is the funny one. consider point 2. then considering why using the same bloody function to allocate your bouncebuffer is just f'ing wrong. instead allocate with alloc_range(0, threshold) to make sure that our bouncebuffer is actually uner 16megs. Cheers, -0- Index: arch//amd64/isa/isa_machdep.c =================================================================== RCS file: /cvs/src/sys/arch/amd64/isa/isa_machdep.c,v retrieving revision 1.20 diff -u -p -r1.20 isa_machdep.c --- arch//amd64/isa/isa_machdep.c 10 Mar 2009 15:03:17 -0000 1.20 +++ arch//amd64/isa/isa_machdep.c 24 Mar 2010 01:06:52 -0000 @@ -128,13 +128,6 @@ void _isa_bus_dmamap_sync(bus_dma_tag_t, int _isa_bus_dmamem_alloc(bus_dma_tag_t, bus_size_t, bus_size_t, bus_size_t, bus_dma_segment_t *, int, int *, int); -void _isa_bus_dmamem_free(bus_dma_tag_t, - bus_dma_segment_t *, int); -int _isa_bus_dmamem_map(bus_dma_tag_t, bus_dma_segment_t *, - int, size_t, caddr_t *, int); -void _isa_bus_dmamem_unmap(bus_dma_tag_t, caddr_t, size_t); -paddr_t _isa_bus_dmamem_mmap(bus_dma_tag_t, bus_dma_segment_t *, - int, off_t, int, int); int _isa_dma_check_buffer(void *, bus_size_t, int, bus_size_t, struct proc *); @@ -158,10 +151,10 @@ struct bus_dma_tag isa_bus_dma_tag = { _isa_bus_dmamap_unload, _isa_bus_dmamap_sync, _isa_bus_dmamem_alloc, - _isa_bus_dmamem_free, - _isa_bus_dmamem_map, - _isa_bus_dmamem_unmap, - _isa_bus_dmamem_mmap, + _bus_dmamem_free, + _bus_dmamem_map, + _bus_dmamem_unmap, + _bus_dmamem_mmap, }; #endif /* NISADMA > 0 */ @@ -676,52 +669,10 @@ _isa_bus_dmamem_alloc(bus_dma_tag_t t, b /* Otherwise try anywhere (we'll bounce later) */ error = _bus_dmamem_alloc_range(t, size, alignment, boundary, - segs, nsegs, rsegs, flags, 0, trunc_page(avail_end)); + segs, nsegs, rsegs, flags, (paddr_t)0, (paddr_t)-1); return (error); } -/* - * Free memory safe for ISA DMA. - */ -void -_isa_bus_dmamem_free(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs) -{ - - _bus_dmamem_free(t, segs, nsegs); -} - -/* - * Map ISA DMA-safe memory into kernel virtual address space. - */ -int -_isa_bus_dmamem_map(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs, - size_t size, caddr_t *kvap, int flags) -{ - - return (_bus_dmamem_map(t, segs, nsegs, size, kvap, flags)); -} - -/* - * Unmap ISA DMA-safe memory from kernel virtual address space. - */ -void -_isa_bus_dmamem_unmap(bus_dma_tag_t t, caddr_t kva, size_t size) -{ - - _bus_dmamem_unmap(t, kva, size); -} - -/* - * mmap(2) ISA DMA-safe memory. - */ -paddr_t -_isa_bus_dmamem_mmap(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs, - off_t off, int prot, int flags) -{ - - return (_bus_dmamem_mmap(t, segs, nsegs, off, prot, flags)); -} - /********************************************************************** * ISA DMA utility functions **********************************************************************/ @@ -795,18 +746,19 @@ _isa_dma_alloc_bouncebuf(bus_dma_tag_t t int error = 0; cookie->id_bouncebuflen = round_page(size); - error = _isa_bus_dmamem_alloc(t, cookie->id_bouncebuflen, + error = _bus_dmamem_alloc_range(t, cookie->id_bouncebuflen, NBPG, map->_dm_boundary, cookie->id_bouncesegs, - map->_dm_segcnt, &cookie->id_nbouncesegs, flags); + map->_dm_segcnt, &cookie->id_nbouncesegs, flags, + 0, ISA_DMA_BOUNCE_THRESHOLD); if (error) goto out; - error = _isa_bus_dmamem_map(t, cookie->id_bouncesegs, + error = _bus_dmamem_map(t, cookie->id_bouncesegs, cookie->id_nbouncesegs, cookie->id_bouncebuflen, (caddr_t *)&cookie->id_bouncebuf, flags); out: if (error) { - _isa_bus_dmamem_free(t, cookie->id_bouncesegs, + _bus_dmamem_free(t, cookie->id_bouncesegs, cookie->id_nbouncesegs); cookie->id_bouncebuflen = 0; cookie->id_nbouncesegs = 0; @@ -825,9 +777,9 @@ _isa_dma_free_bouncebuf(bus_dma_tag_t t, STAT_DECR(isa_dma_stats_nbouncebufs); - _isa_bus_dmamem_unmap(t, cookie->id_bouncebuf, + _bus_dmamem_unmap(t, cookie->id_bouncebuf, cookie->id_bouncebuflen); - _isa_bus_dmamem_free(t, cookie->id_bouncesegs, + _bus_dmamem_free(t, cookie->id_bouncesegs, cookie->id_nbouncesegs); cookie->id_bouncebuflen = 0; cookie->id_nbouncesegs = 0; Index: arch//i386/i386/bus_dma.c =================================================================== RCS file: /cvs/src/sys/arch/i386/i386/bus_dma.c,v retrieving revision 1.19 diff -u -p -r1.19 bus_dma.c --- arch//i386/i386/bus_dma.c 3 Nov 2009 17:21:46 -0000 1.19 +++ arch//i386/i386/bus_dma.c 24 Mar 2010 01:08:36 -0000 @@ -618,11 +618,8 @@ _bus_dmamem_alloc_range(bus_dma_tag_t t, plaflag |= UVM_PLA_ZERO; TAILQ_INIT(&mlist); - if (high <= ISA_DMA_BOUNCE_THRESHOLD || (error = uvm_pglistalloc(size, - round_page(ISA_DMA_BOUNCE_THRESHOLD), high, alignment, boundary, - &mlist, nsegs, plaflag))) - error = uvm_pglistalloc(size, low, high, alignment, boundary, - &mlist, nsegs, plaflag); + error = uvm_pglistalloc(size, low, high, alignment, boundary, + &mlist, nsegs, plaflag); if (error) return (error); Index: arch//i386/isa/isa_machdep.c =================================================================== RCS file: /cvs/src/sys/arch/i386/isa/isa_machdep.c,v retrieving revision 1.68 diff -u -p -r1.68 isa_machdep.c --- arch//i386/isa/isa_machdep.c 22 Aug 2009 02:54:50 -0000 1.68 +++ arch//i386/isa/isa_machdep.c 24 Mar 2010 01:07:09 -0000 @@ -125,13 +125,6 @@ void _isa_bus_dmamap_sync(bus_dma_tag_t, int _isa_bus_dmamem_alloc(bus_dma_tag_t, bus_size_t, bus_size_t, bus_size_t, bus_dma_segment_t *, int, int *, int); -void _isa_bus_dmamem_free(bus_dma_tag_t, - bus_dma_segment_t *, int); -int _isa_bus_dmamem_map(bus_dma_tag_t, bus_dma_segment_t *, - int, size_t, caddr_t *, int); -void _isa_bus_dmamem_unmap(bus_dma_tag_t, caddr_t, size_t); -paddr_t _isa_bus_dmamem_mmap(bus_dma_tag_t, bus_dma_segment_t *, - int, off_t, int, int); int _isa_dma_check_buffer(void *, bus_size_t, int, bus_size_t, struct proc *); @@ -155,10 +148,10 @@ struct bus_dma_tag isa_bus_dma_tag = { _isa_bus_dmamap_unload, _isa_bus_dmamap_sync, _isa_bus_dmamem_alloc, - _isa_bus_dmamem_free, - _isa_bus_dmamem_map, - _isa_bus_dmamem_unmap, - _isa_bus_dmamem_mmap, + _bus_dmamem_free, + _bus_dmamem_map, + _bus_dmamem_unmap, + _bus_dmamem_mmap, }; #endif /* NISADMA > 0 */ @@ -930,58 +923,20 @@ _isa_bus_dmamem_alloc(bus_dma_tag_t t, b bus_size_t boundary, bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags) { - paddr_t high; - - if (avail_end > ISA_DMA_BOUNCE_THRESHOLD) - high = trunc_page(ISA_DMA_BOUNCE_THRESHOLD); - else - high = trunc_page(avail_end); - - return (_bus_dmamem_alloc_range(t, size, alignment, boundary, - segs, nsegs, rsegs, flags, 0, high)); -} - -/* - * Free memory safe for ISA DMA. - */ -void -_isa_bus_dmamem_free(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs) -{ - - _bus_dmamem_free(t, segs, nsegs); -} - -/* - * Map ISA DMA-safe memory into kernel virtual address space. - */ -int -_isa_bus_dmamem_map(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs, - size_t size, caddr_t *kvap, int flags) -{ - - return (_bus_dmamem_map(t, segs, nsegs, size, kvap, flags)); -} + int error; -/* - * Unmap ISA DMA-safe memory from kernel virtual address space. - */ -void -_isa_bus_dmamem_unmap(bus_dma_tag_t t, caddr_t kva, size_t size) -{ + /* Try in ISA addressable region first */ + error = _bus_dmamem_alloc_range(t, size, alignment, boundary, + segs, nsegs, rsegs, flags, 0, ISA_DMA_BOUNCE_THRESHOLD); + if (!error) + return (error); - _bus_dmamem_unmap(t, kva, size); + /* Otherwise try anywhere (we'll bounce later) */ + error = _bus_dmamem_alloc_range(t, size, alignment, boundary, + segs, nsegs, rsegs, flags, (paddr_t)0, (paddr_t)-1); + return (error); } -/* - * mmap(2) ISA DMA-safe memory. - */ -paddr_t -_isa_bus_dmamem_mmap(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs, - off_t off, int prot, int flags) -{ - - return (_bus_dmamem_mmap(t, segs, nsegs, off, prot, flags)); -} /********************************************************************** * ISA DMA utility functions @@ -1055,18 +1010,19 @@ _isa_dma_alloc_bouncebuf(bus_dma_tag_t t int error = 0; cookie->id_bouncebuflen = round_page(size); - error = _isa_bus_dmamem_alloc(t, cookie->id_bouncebuflen, + error = _bus_dmamem_alloc_range(t, cookie->id_bouncebuflen, NBPG, map->_dm_boundary, cookie->id_bouncesegs, - map->_dm_segcnt, &cookie->id_nbouncesegs, flags); + map->_dm_segcnt, &cookie->id_nbouncesegs, flags, + 0, ISA_DMA_BOUNCE_THRESHOLD); if (error) goto out; - error = _isa_bus_dmamem_map(t, cookie->id_bouncesegs, + error = _bus_dmamem_map(t, cookie->id_bouncesegs, cookie->id_nbouncesegs, cookie->id_bouncebuflen, (caddr_t *)&cookie->id_bouncebuf, flags); out: if (error) { - _isa_bus_dmamem_free(t, cookie->id_bouncesegs, + _bus_dmamem_free(t, cookie->id_bouncesegs, cookie->id_nbouncesegs); cookie->id_bouncebuflen = 0; cookie->id_nbouncesegs = 0; @@ -1085,9 +1041,9 @@ _isa_dma_free_bouncebuf(bus_dma_tag_t t, STAT_DECR(isa_dma_stats_nbouncebufs); - _isa_bus_dmamem_unmap(t, cookie->id_bouncebuf, + _bus_dmamem_unmap(t, cookie->id_bouncebuf, cookie->id_bouncebuflen); - _isa_bus_dmamem_free(t, cookie->id_bouncesegs, + _bus_dmamem_free(t, cookie->id_bouncesegs, cookie->id_nbouncesegs); cookie->id_bouncebuflen = 0; cookie->id_nbouncesegs = 0;