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