Add bus_dmamap_load_ma() function to load map with the array of
vm_pages. Provide trivial implementation which forwards the load to _bus_dmamap_load_phys() page by page. Right now all architectures use bus_dmamap_load_ma_triv(). Tested by: pho (as part of the functional patch) Sponsored by: The FreeBSD Foundation MFC after: 1 month
This commit is contained in:
parent
e0b95cb532
commit
80938e75f0
@ -975,6 +975,16 @@ _bus_dmamap_load_phys(bus_dma_tag_t dmat,
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
_bus_dmamap_load_ma(bus_dma_tag_t dmat, bus_dmamap_t map,
|
||||
struct vm_page **ma, bus_size_t tlen, int ma_offs, int flags,
|
||||
bus_dma_segment_t *segs, int *segp)
|
||||
{
|
||||
|
||||
return (bus_dmamap_load_ma_triv(dmat, map, ma, tlen, ma_offs, flags,
|
||||
segs, segp));
|
||||
}
|
||||
|
||||
/*
|
||||
* Utility function to load a linear buffer. segp contains
|
||||
* the starting segment on entrace, and the ending segment on exit.
|
||||
|
@ -992,6 +992,17 @@ _bus_dmamap_load_phys(bus_dma_tag_t dmat, bus_dmamap_t map, vm_paddr_t buf,
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
_bus_dmamap_load_ma(bus_dma_tag_t dmat, bus_dmamap_t map,
|
||||
struct vm_page **ma, bus_size_t tlen, int ma_offs, int flags,
|
||||
bus_dma_segment_t *segs, int *segp)
|
||||
{
|
||||
|
||||
return (bus_dmamap_load_ma_triv(dmat, map, ma, tlen, ma_offs, flags,
|
||||
segs, segp));
|
||||
}
|
||||
|
||||
/*
|
||||
* Utility function to load a linear buffer. segp contains
|
||||
* the starting segment on entrance, and the ending segment on exit.
|
||||
|
@ -658,6 +658,17 @@ _bus_dmamap_load_phys(bus_dma_tag_t dmat, bus_dmamap_t map,
|
||||
*/
|
||||
return (buflen != 0 ? EFBIG : 0); /* XXX better return value here? */
|
||||
}
|
||||
|
||||
int
|
||||
_bus_dmamap_load_ma(bus_dma_tag_t dmat, bus_dmamap_t map,
|
||||
struct vm_page **ma, bus_size_t tlen, int ma_offs, int flags,
|
||||
bus_dma_segment_t *segs, int *segp)
|
||||
{
|
||||
|
||||
return (bus_dmamap_load_ma_triv(dmat, map, ma, tlen, ma_offs, flags,
|
||||
segs, segp));
|
||||
}
|
||||
|
||||
/*
|
||||
* Utility function to load a linear buffer. segp contains
|
||||
* the starting segment on entrace, and the ending segment on exit.
|
||||
|
@ -124,24 +124,33 @@ static int
|
||||
_bus_dmamap_load_bio(bus_dma_tag_t dmat, bus_dmamap_t map, struct bio *bio,
|
||||
int *nsegs, int flags)
|
||||
{
|
||||
vm_paddr_t paddr;
|
||||
bus_size_t len, tlen;
|
||||
int error, i, ma_offs;
|
||||
int error;
|
||||
|
||||
if ((bio->bio_flags & BIO_UNMAPPED) == 0) {
|
||||
error = _bus_dmamap_load_buffer(dmat, map, bio->bio_data,
|
||||
bio->bio_bcount, kernel_pmap, flags, NULL, nsegs);
|
||||
return (error);
|
||||
} else {
|
||||
error = _bus_dmamap_load_ma(dmat, map, bio->bio_ma,
|
||||
bio->bio_bcount, bio->bio_ma_offset, flags, NULL, nsegs);
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
bus_dmamap_load_ma_triv(bus_dma_tag_t dmat, bus_dmamap_t map,
|
||||
struct vm_page **ma, bus_size_t tlen, int ma_offs, int flags,
|
||||
bus_dma_segment_t *segs, int *segp)
|
||||
{
|
||||
vm_paddr_t paddr;
|
||||
bus_size_t len;
|
||||
int error, i;
|
||||
|
||||
error = 0;
|
||||
tlen = bio->bio_bcount;
|
||||
ma_offs = bio->bio_ma_offset;
|
||||
for (i = 0; tlen > 0; i++, tlen -= len) {
|
||||
len = min(PAGE_SIZE - ma_offs, tlen);
|
||||
paddr = VM_PAGE_TO_PHYS(bio->bio_ma[i]) + ma_offs;
|
||||
paddr = VM_PAGE_TO_PHYS(ma[i]) + ma_offs;
|
||||
error = _bus_dmamap_load_phys(dmat, map, paddr, len,
|
||||
flags, NULL, nsegs);
|
||||
flags, segs, segp);
|
||||
if (error != 0)
|
||||
break;
|
||||
ma_offs = 0;
|
||||
|
@ -878,6 +878,16 @@ _bus_dmamap_load_phys(bus_dma_tag_t dmat, bus_dmamap_t map,
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
_bus_dmamap_load_ma(bus_dma_tag_t dmat, bus_dmamap_t map,
|
||||
struct vm_page **ma, bus_size_t tlen, int ma_offs, int flags,
|
||||
bus_dma_segment_t *segs, int *segp)
|
||||
{
|
||||
|
||||
return (bus_dmamap_load_ma_triv(dmat, map, ma, tlen, ma_offs, flags,
|
||||
segs, segp));
|
||||
}
|
||||
|
||||
/*
|
||||
* Utility function to load a linear buffer. segp contains
|
||||
* the starting segment on entrance, and the ending segment on exit.
|
||||
|
@ -754,6 +754,16 @@ _bus_dmamap_load_phys(bus_dma_tag_t dmat,
|
||||
return (buflen != 0 ? EFBIG : 0); /* XXX better return value here? */
|
||||
}
|
||||
|
||||
int
|
||||
_bus_dmamap_load_ma(bus_dma_tag_t dmat, bus_dmamap_t map,
|
||||
struct vm_page **ma, bus_size_t tlen, int ma_offs, int flags,
|
||||
bus_dma_segment_t *segs, int *segp)
|
||||
{
|
||||
|
||||
return (bus_dmamap_load_ma_triv(dmat, map, ma, tlen, ma_offs, flags,
|
||||
segs, segp));
|
||||
}
|
||||
|
||||
/*
|
||||
* Utility function to load a linear buffer. segp contains
|
||||
* the starting segment on entrance, and the ending segment on exit.
|
||||
|
@ -146,5 +146,7 @@ struct bus_dma_tag {
|
||||
((t)->dt_mt->dm_dmamem_alloc((t), (v), (f), (m)))
|
||||
#define bus_dmamem_free(t, v, m) \
|
||||
((t)->dt_mt->dm_dmamem_free((t), (v), (m)))
|
||||
#define _bus_dmamap_load_ma(t, m, a, tt, o, f, s, p) \
|
||||
bus_dmamap_load_ma_triv((t), (m), (a), (tt), (o), (f), (s), (p))
|
||||
|
||||
#endif /* !_SPARC64_BUS_DMA_H_ */
|
||||
|
@ -246,6 +246,15 @@ int bus_dmamap_load_mem(bus_dma_tag_t dmat, bus_dmamap_t map,
|
||||
struct memdesc *mem, bus_dmamap_callback_t *callback,
|
||||
void *callback_arg, int flags);
|
||||
|
||||
/*
|
||||
* Placeholder for use by busdma implementations which do not benefit
|
||||
* from optimized procedure to load an array of vm_page_t. Falls back
|
||||
* to do _bus_dmamap_load_phys() in loop.
|
||||
*/
|
||||
int bus_dmamap_load_ma_triv(bus_dma_tag_t dmat, bus_dmamap_t map,
|
||||
struct vm_page **ma, bus_size_t tlen, int ma_offs, int flags,
|
||||
bus_dma_segment_t *segs, int *segp);
|
||||
|
||||
/*
|
||||
* XXX sparc64 uses the same interface, but a much different implementation.
|
||||
* <machine/bus_dma.h> for the sparc64 arch contains the equivalent
|
||||
@ -324,6 +333,10 @@ int _bus_dmamap_load_phys(bus_dma_tag_t dmat, bus_dmamap_t map,
|
||||
vm_paddr_t paddr, bus_size_t buflen,
|
||||
int flags, bus_dma_segment_t *segs, int *segp);
|
||||
|
||||
int _bus_dmamap_load_ma(bus_dma_tag_t dmat, bus_dmamap_t map,
|
||||
struct vm_page **ma, bus_size_t tlen, int ma_offs, int flags,
|
||||
bus_dma_segment_t *segs, int *segp);
|
||||
|
||||
bus_dma_segment_t *_bus_dmamap_complete(bus_dma_tag_t dmat,
|
||||
bus_dmamap_t map,
|
||||
bus_dma_segment_t *segs,
|
||||
|
@ -849,6 +849,16 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dmat,
|
||||
return (buflen != 0 ? EFBIG : 0); /* XXX better return value here? */
|
||||
}
|
||||
|
||||
int
|
||||
_bus_dmamap_load_ma(bus_dma_tag_t dmat, bus_dmamap_t map,
|
||||
struct vm_page **ma, bus_size_t tlen, int ma_offs, int flags,
|
||||
bus_dma_segment_t *segs, int *segp)
|
||||
{
|
||||
|
||||
return (bus_dmamap_load_ma_triv(dmat, map, ma, tlen, ma_offs, flags,
|
||||
segs, segp));
|
||||
}
|
||||
|
||||
void
|
||||
__bus_dmamap_waitok(bus_dma_tag_t dmat, bus_dmamap_t map,
|
||||
struct memdesc *mem, bus_dmamap_callback_t *callback,
|
||||
|
Loading…
Reference in New Issue
Block a user