cvs commit: src/sys/i386/i386 busdma_machdep.c

Hidetoshi Shimokawa simokawa at sat.t.u-tokyo.ac.jp
Mon Apr 14 01:55:04 PDT 2003


At Mon, 14 Apr 2003 03:33:29 -0400,
Jake Burkholder wrote:
> 
> Apparently, On Sun, Apr 13, 2003 at 09:19:42PM -0700,
> 	Hidetoshi Shimokawa said words to the effect of;
> 
> > simokawa    2003/04/13 21:19:42 PDT
> > 
> >   FreeBSD src repository
> > 
> >   Modified files:
> >     sys/i386/i386        busdma_machdep.c 
> >   Log:
> >   * Use _bus_dmamap_load_buffer() and respect maxsegsz in bus_dmamap_load().
> >   Ignoring maxsegsz may lead to fatal data corruption for some devices.
> >   ex. SBP-2/FireWire
> 
> Hmm.  _bus_dmamap_load_buffer doesn't handle delayed loads due to lack
> of resources like bus_dmamap_load does (did).  I think you will need to
> respect BUS_DMA_WAITOK/BUS_DMA_NOWAIT in the flags argument to
> _bus_dmamap_load_buffer, and pass BUS_DMA_WAITOK in bus_dmamap_load and
> BUS_DMA_NOWAIT in other cases.  If _bus_dmamap_load_buffer runs out of
> resources it should return EINPROGRESS and queue the request if
> BUS_DMA_WAITOK is specified, or return ENOMEM if BUS_DMA_NOWAIT is specified.

You are right. How about this patch?

/\ Hidetoshi Shimokawa
\/  simokawa at sat.t.u-tokyo.ac.jp
PGP public key: http://www.sat.t.u-tokyo.ac.jp/~simokawa/pgp.html

Index: busdma_machdep.c
===================================================================
RCS file: /home/ncvs/src/sys/i386/i386/busdma_machdep.c,v
retrieving revision 1.41
diff -u -r1.41 busdma_machdep.c
--- busdma_machdep.c	14 Apr 2003 04:19:42 -0000	1.41
+++ busdma_machdep.c	14 Apr 2003 08:52:48 -0000
@@ -464,9 +464,22 @@
 	/* 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,16 @@
         bus_addr_t		lastaddr = 0;
 	int			error, nsegs = 0;
 
+	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 +607,7 @@
 	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 +659,7 @@
 	struct iovec *iov;
 	struct thread *td = NULL;
 
+	flags |= BUS_DMA_NOWAIT;
 	resid = uio->uio_resid;
 	iov = uio->uio_iov;
 


More information about the cvs-src mailing list