- Free accumulated bounce pages in the bus dma map if we could not
reserved enough bounce pages.
- In bus_dmamap_load_mbuf(), if _bus_dmamap_load_buffer() returns
ENOMEM on non-first mbuf fragment, we adjust the error to EFBIG:
o There is at least one bounce page available, so we could expect
that after mbuf defragmentation, enough bounce pages (normally
one bounce page for non-jumbo frame) may be available.
o Most callers defragment the mbuf chain only if error is EFBIG.
if (flags & BUS_DMA_NOWAIT) {
if (reserve_bounce_pages(dmat, map, 0) != 0) {
BZ_UNLOCK(bz);
- return (ENOMEM);
+ error = ENOMEM;
+ goto free_bounce;
}
} else {
if (reserve_bounce_pages(dmat, map, 1) != 0) {
*segp = seg;
*lastpaddrp = nextpaddr;
+free_bounce:
if (error && (dmat->flags & BUS_DMA_COULD_BOUNCE) &&
map != &nobounce_dmamap) {
_bus_dmamap_unload(dmat, map);
m->m_data, m->m_len,
NULL, flags, &lastaddr,
&nsegs, first);
+ if (error == ENOMEM && !first) {
+ /*
+ * Out of bounce pages due to too many
+ * fragments in the mbuf chain; return
+ * EFBIG instead.
+ */
+ error = EFBIG;
+ }
first = 0;
}
} else {