Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/alpha/common Implement dmamap_load_uio for SGMAPs.



details:   https://anonhg.NetBSD.org/src/rev/26152742bf97
branches:  trunk
changeset: 512948:26152742bf97
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Thu Jul 19 18:08:54 2001 +0000

description:
Implement dmamap_load_uio for SGMAPs.

diffstat:

 sys/arch/alpha/common/sgmap_typedep.c |  70 +++++++++++++++++++++++++++++++++-
 1 files changed, 67 insertions(+), 3 deletions(-)

diffs (95 lines):

diff -r 83f9657e2ef4 -r 26152742bf97 sys/arch/alpha/common/sgmap_typedep.c
--- a/sys/arch/alpha/common/sgmap_typedep.c     Thu Jul 19 18:06:19 2001 +0000
+++ b/sys/arch/alpha/common/sgmap_typedep.c     Thu Jul 19 18:08:54 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sgmap_typedep.c,v 1.20 2001/07/19 17:08:44 thorpej Exp $ */
+/* $NetBSD: sgmap_typedep.c,v 1.21 2001/07/19 18:08:54 thorpej Exp $ */
 
 /*-
  * Copyright (c) 1997, 1998, 2001 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-__KERNEL_RCSID(0, "$NetBSD: sgmap_typedep.c,v 1.20 2001/07/19 17:08:44 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sgmap_typedep.c,v 1.21 2001/07/19 18:08:54 thorpej Exp $");
 
 #include "opt_ddb.h"
 
@@ -305,11 +305,75 @@
 __C(SGMAP_TYPE,_load_uio)(bus_dma_tag_t t, bus_dmamap_t map, struct uio *uio,
     int flags, struct alpha_sgmap *sgmap)
 {
+       bus_size_t minlen, resid;
+       struct proc *p = NULL;
+       struct iovec *iov;
+       caddr_t addr;
+       int i, seg, error;
+
+       /*
+        * Make sure that on error condition we return "no valid mappings".
+        */
+       map->dm_mapsize = 0;
+       map->dm_nsegs = 0;
 
        KASSERT((flags & (BUS_DMA_READ|BUS_DMA_WRITE)) !=
            (BUS_DMA_READ|BUS_DMA_WRITE));
 
-       panic(__S(__C(SGMAP_TYPE,_load_uio)) ": not implemented");
+       map->_dm_flags |= flags & (BUS_DMA_READ|BUS_DMA_WRITE);
+
+       resid = uio->uio_resid;
+       iov = uio->uio_iov;
+
+       if (uio->uio_segflg == UIO_USERSPACE) {
+               p = uio->uio_procp;
+#ifdef DIAGNOSTIC
+               if (p == NULL)
+                       panic(__S(__C(SGMAP_TYPE,_load_uio))
+                           ": USERSPACE but no proc");
+#endif
+       }
+
+       seg = 0;
+       error = 0;
+       for (i = 0; i < uio->uio_iovcnt && resid != 0 && error == 0;
+            i++, seg++) {
+               /*
+                * Now at the first iovec to load.  Load each iovec
+                * until we have exhausted the residual count.
+                */
+               minlen = resid < iov[i].iov_len ? resid : iov[i].iov_len;
+               addr = (caddr_t)iov[i].iov_base;
+
+               error = __C(SGMAP_TYPE,_load_buffer)(t, map,
+                   addr, minlen, p, flags, &seg, sgmap);
+
+               resid -= minlen;
+       }
+
+       alpha_mb();
+
+#if defined(SGMAP_DEBUG) && defined(DDB)
+       if (__C(SGMAP_TYPE,_debug) > 1)
+               Debugger();
+#endif
+
+       if (error == 0) {
+               map->dm_mapsize = uio->uio_resid;
+               map->dm_nsegs = seg;
+       } else {
+               /* Need to back out what we've done so far. */
+               map->dm_nsegs = seg - 1;
+               __C(SGMAP_TYPE,_unload)(t, map, sgmap);
+               map->_dm_flags &= ~(BUS_DMA_READ|BUS_DMA_WRITE);
+               if (t->_next_window != NULL) {
+                       /* Give the next window a chance. */
+                       error = bus_dmamap_load_uio(t->_next_window, map,
+                           uio, flags);
+               }
+       }
+
+       return (error);
 }
 
 int



Home | Main Index | Thread Index | Old Index