Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/sparc64/dev Fix address calculation for split segme...



details:   https://anonhg.NetBSD.org/src/rev/5fbab5a22fb6
branches:  trunk
changeset: 555411:5fbab5a22fb6
user:      tsutsui <tsutsui%NetBSD.org@localhost>
date:      Sun Nov 16 18:18:59 2003 +0000

description:
Fix address calculation for split segment address when the buffer is
crossing boundary in iommu_dvmamap_load().
Fixes E2BIG error on dmamap with smaller boundary size than maxxfersize
(which is used by recent changed pcscp(4)).

While here, some KNF around debug printf etc.

diffstat:

 sys/arch/sparc64/dev/iommu.c |  50 ++++++++++++++++++++++----------------------
 1 files changed, 25 insertions(+), 25 deletions(-)

diffs (120 lines):

diff -r f25c879e9053 -r 5fbab5a22fb6 sys/arch/sparc64/dev/iommu.c
--- a/sys/arch/sparc64/dev/iommu.c      Sun Nov 16 18:06:01 2003 +0000
+++ b/sys/arch/sparc64/dev/iommu.c      Sun Nov 16 18:18:59 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: iommu.c,v 1.70 2003/10/26 19:14:22 christos Exp $      */
+/*     $NetBSD: iommu.c,v 1.71 2003/11/16 18:18:59 tsutsui Exp $       */
 
 /*
  * Copyright (c) 2001, 2002 Eduardo Horvath
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: iommu.c,v 1.70 2003/10/26 19:14:22 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: iommu.c,v 1.71 2003/11/16 18:18:59 tsutsui Exp $");
 
 #include "opt_ddb.h"
 
@@ -429,7 +429,7 @@
        bus_size_t sgsize;
        paddr_t curaddr;
        u_long dvmaddr, sgstart, sgend;
-       bus_size_t align, boundary;
+       bus_size_t align, boundary, len;
        vaddr_t vaddr = (vaddr_t)buf;
        int seg;
        struct pmap *pmap;
@@ -469,13 +469,12 @@
         */
        s = splhigh();
        err = extent_alloc(is->is_dvmamap, sgsize, align,
-               (sgsize > boundary) ? 0 : boundary,
-               EX_NOWAIT|EX_BOUNDZERO, &dvmaddr);
+           (sgsize > boundary) ? 0 : boundary,
+           EX_NOWAIT|EX_BOUNDZERO, &dvmaddr);
        splx(s);
 
 #ifdef DEBUG
-       if (err || (dvmaddr == (u_long)-1))
-       {
+       if (err || (dvmaddr == (u_long)-1)) {
                printf("iommu_dvmamap_load(): extent_alloc(%d, %x) failed!\n",
                    (int)sgsize, flags);
 #ifdef DDB
@@ -501,37 +500,38 @@
        sgstart = dvmaddr + (vaddr & PGOFSET);
        sgend = sgstart + buflen - 1;
        map->dm_segs[seg].ds_addr = sgstart;
-       DPRINTF(IDB_INFO, ("iommu_dvmamap_load: boundary %lx boundary-1 %lx "
-               "~(boundary-1) %lx\n", (long)boundary, (long)(boundary-1), (long)~(boundary-1)));
+       DPRINTF(IDB_INFO, ("iommu_dvmamap_load: boundary %lx boundary - 1 %lx "
+           "~(boundary - 1) %lx\n", (long)boundary, (long)(boundary - 1),
+           (long)~(boundary - 1)));
        while ((sgstart & ~(boundary - 1)) != (sgend & ~(boundary - 1))) {
                /* Oops.  We crossed a boundary.  Split the xfer. */
+               len = boundary - (sgstart & (boundary - 1));
+               map->dm_segs[seg].ds_len = len;
                DPRINTF(IDB_INFO, ("iommu_dvmamap_load: "
-                       "seg %d start %lx size %lx\n", seg,
-                       (long)map->dm_segs[seg].ds_addr,
-                       (long)map->dm_segs[seg].ds_len));
-               map->dm_segs[seg].ds_len =
-                   boundary - (sgstart & (boundary - 1));
+                   "seg %d start %lx size %lx\n", seg,
+                   (long)map->dm_segs[seg].ds_addr,
+                   (long)map->dm_segs[seg].ds_len));
                if (++seg >= map->_dm_segcnt) {
                        /* Too many segments.  Fail the operation. */
                        DPRINTF(IDB_INFO, ("iommu_dvmamap_load: "
-                               "too many segments %d\n", seg));
+                           "too many segments %d\n", seg));
                        s = splhigh();
                        /* How can this fail?  And if it does what can we do? */
                        err = extent_free(is->is_dvmamap,
-                               dvmaddr, sgsize, EX_NOWAIT);
+                           dvmaddr, sgsize, EX_NOWAIT);
                        map->_dm_dvmastart = 0;
                        map->_dm_dvmasize = 0;
                        splx(s);
                        return (E2BIG);
                }
-               sgstart = roundup(sgstart, boundary);
+               sgstart += len;
                map->dm_segs[seg].ds_addr = sgstart;
        }
        map->dm_segs[seg].ds_len = sgend - sgstart + 1;
        DPRINTF(IDB_INFO, ("iommu_dvmamap_load: "
-               "seg %d start %lx size %lx\n", seg,
-               (long)map->dm_segs[seg].ds_addr, (long)map->dm_segs[seg].ds_len));
-       map->dm_nsegs = seg+1;
+           "seg %d start %lx size %lx\n", seg,
+           (long)map->dm_segs[seg].ds_addr, (long)map->dm_segs[seg].ds_len));
+       map->dm_nsegs = seg + 1;
        map->dm_mapsize = buflen;
 
        if (p != NULL)
@@ -558,9 +558,9 @@
 
                DPRINTF(IDB_BUSDMA,
                    ("iommu_dvmamap_load: map %p loading va %p "
-                           "dva %lx at pa %lx\n",
-                           map, (void *)vaddr, (long)dvmaddr,
-                           (long)(curaddr & ~(PAGE_SIZE-1))));
+                   "dva %lx at pa %lx\n",
+                   map, (void *)vaddr, (long)dvmaddr,
+                   (long)(curaddr & ~(PAGE_SIZE-1))));
                iommu_enter(sb, trunc_page(dvmaddr), trunc_page(curaddr),
                    flags|0x4000);
 
@@ -573,8 +573,8 @@
                if (map->dm_segs[seg].ds_addr < is->is_dvmabase ||
                        map->dm_segs[seg].ds_addr > is->is_dvmaend) {
                        printf("seg %d dvmaddr %lx out of range %x - %x\n",
-                               seg, (long)map->dm_segs[seg].ds_addr,
-                               is->is_dvmabase, is->is_dvmaend);
+                           seg, (long)map->dm_segs[seg].ds_addr,
+                           is->is_dvmabase, is->is_dvmaend);
 #ifdef DDB
                        Debugger();
 #endif



Home | Main Index | Thread Index | Old Index