summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorsimokawa <simokawa@FreeBSD.org>2003-04-14 13:21:40 +0000
committersimokawa <simokawa@FreeBSD.org>2003-04-14 13:21:40 +0000
commitbdfca1b9c1846e877c9f67228139c4b903037c29 (patch)
treeabec1925792aebefc9393996f1e8215acaad0ee0 /sys
parentbb06bbb4a0d1899ed3fe00f02ca2c92ae05f9b49 (diff)
downloadFreeBSD-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.c30
-rw-r--r--sys/i386/i386/busdma_machdep.c30
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;
OpenPOWER on IntegriCloud