diff options
author | simokawa <simokawa@FreeBSD.org> | 2003-04-14 13:21:40 +0000 |
---|---|---|
committer | simokawa <simokawa@FreeBSD.org> | 2003-04-14 13:21:40 +0000 |
commit | bdfca1b9c1846e877c9f67228139c4b903037c29 (patch) | |
tree | abec1925792aebefc9393996f1e8215acaad0ee0 /sys | |
parent | bb06bbb4a0d1899ed3fe00f02ca2c92ae05f9b49 (diff) | |
download | FreeBSD-src-bdfca1b9c1846e877c9f67228139c4b903037c29.zip FreeBSD-src-bdfca1b9c1846e877c9f67228139c4b903037c29.tar.gz |
Restore delayed load support for the resource shortage case.
It was missed in the previous change.
Now, _bus_dmamap_load_buffer() accepts BUS_DMA_WAITOK/BUS_DMA_NOWAIT flags.
Original idea from: jake
Diffstat (limited to 'sys')
-rw-r--r-- | sys/amd64/amd64/busdma_machdep.c | 30 | ||||
-rw-r--r-- | sys/i386/i386/busdma_machdep.c | 30 |
2 files changed, 54 insertions, 6 deletions
diff --git a/sys/amd64/amd64/busdma_machdep.c b/sys/amd64/amd64/busdma_machdep.c index 83a8248..3f26419 100644 --- a/sys/amd64/amd64/busdma_machdep.c +++ b/sys/amd64/amd64/busdma_machdep.c @@ -464,9 +464,22 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dmat, /* Reserve Necessary Bounce Pages */ if (map->pagesneeded != 0) { mtx_lock(&bounce_lock); - if (reserve_bounce_pages(dmat, map, 0) != 0) { - mtx_unlock(&bounce_lock); - return (ENOMEM); + if (flags & BUS_DMA_NOWAIT) { + if (reserve_bounce_pages(dmat, map, 0) != 0) { + mtx_unlock(&bounce_lock); + return (ENOMEM); + } + } else { + if (reserve_bounce_pages(dmat, map, 1) != 0) { + /* Queue us for resources */ + map->dmat = dmat; + map->buf = buf; + map->buflen = buflen; + STAILQ_INSERT_TAIL(&bounce_map_waitinglist, + map, links); + mtx_unlock(&bounce_lock); + return (EINPROGRESS); + } } mtx_unlock(&bounce_lock); } @@ -556,9 +569,18 @@ bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, bus_addr_t lastaddr = 0; int error, nsegs = 0; + if (map != NULL) { + flags |= BUS_DMA_WAITOK; + map->callback = callback; + map->callback_arg = callback_arg; + } + error = _bus_dmamap_load_buffer(dmat, map, dm_segments, buf, buflen, NULL, flags, &lastaddr, &nsegs, 1); + if (error == EINPROGRESS) + return error; + if (error) (*callback)(callback_arg, dm_segments, 0, error); else @@ -587,6 +609,7 @@ bus_dmamap_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map, KASSERT(m0->m_flags & M_PKTHDR, ("bus_dmamap_load_mbuf: no packet header")); + flags |= BUS_DMA_NOWAIT; nsegs = 0; error = 0; if (m0->m_pkthdr.len <= dmat->maxsize) { @@ -638,6 +661,7 @@ bus_dmamap_load_uio(bus_dma_tag_t dmat, bus_dmamap_t map, struct iovec *iov; struct thread *td = NULL; + flags |= BUS_DMA_NOWAIT; resid = uio->uio_resid; iov = uio->uio_iov; diff --git a/sys/i386/i386/busdma_machdep.c b/sys/i386/i386/busdma_machdep.c index 83a8248..3f26419 100644 --- a/sys/i386/i386/busdma_machdep.c +++ b/sys/i386/i386/busdma_machdep.c @@ -464,9 +464,22 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dmat, /* Reserve Necessary Bounce Pages */ if (map->pagesneeded != 0) { mtx_lock(&bounce_lock); - if (reserve_bounce_pages(dmat, map, 0) != 0) { - mtx_unlock(&bounce_lock); - return (ENOMEM); + if (flags & BUS_DMA_NOWAIT) { + if (reserve_bounce_pages(dmat, map, 0) != 0) { + mtx_unlock(&bounce_lock); + return (ENOMEM); + } + } else { + if (reserve_bounce_pages(dmat, map, 1) != 0) { + /* Queue us for resources */ + map->dmat = dmat; + map->buf = buf; + map->buflen = buflen; + STAILQ_INSERT_TAIL(&bounce_map_waitinglist, + map, links); + mtx_unlock(&bounce_lock); + return (EINPROGRESS); + } } mtx_unlock(&bounce_lock); } @@ -556,9 +569,18 @@ bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, bus_addr_t lastaddr = 0; int error, nsegs = 0; + if (map != NULL) { + flags |= BUS_DMA_WAITOK; + map->callback = callback; + map->callback_arg = callback_arg; + } + error = _bus_dmamap_load_buffer(dmat, map, dm_segments, buf, buflen, NULL, flags, &lastaddr, &nsegs, 1); + if (error == EINPROGRESS) + return error; + if (error) (*callback)(callback_arg, dm_segments, 0, error); else @@ -587,6 +609,7 @@ bus_dmamap_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map, KASSERT(m0->m_flags & M_PKTHDR, ("bus_dmamap_load_mbuf: no packet header")); + flags |= BUS_DMA_NOWAIT; nsegs = 0; error = 0; if (m0->m_pkthdr.len <= dmat->maxsize) { @@ -638,6 +661,7 @@ bus_dmamap_load_uio(bus_dma_tag_t dmat, bus_dmamap_t map, struct iovec *iov; struct thread *td = NULL; + flags |= BUS_DMA_NOWAIT; resid = uio->uio_resid; iov = uio->uio_iov; |