Module Name: src Committed By: nakayama Date: Mon Dec 7 11:18:38 UTC 2009
Modified Files: src/sys/arch/sparc64/dev: iommu.c Log Message: Calculate DVMA pages correctly. To generate a diff of this commit: cvs rdiff -u -r1.92 -r1.93 src/sys/arch/sparc64/dev/iommu.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/sparc64/dev/iommu.c diff -u src/sys/arch/sparc64/dev/iommu.c:1.92 src/sys/arch/sparc64/dev/iommu.c:1.93 --- src/sys/arch/sparc64/dev/iommu.c:1.92 Mon Dec 7 11:14:27 2009 +++ src/sys/arch/sparc64/dev/iommu.c Mon Dec 7 11:18:38 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: iommu.c,v 1.92 2009/12/07 11:14:27 nakayama Exp $ */ +/* $NetBSD: iommu.c,v 1.93 2009/12/07 11:18:38 nakayama Exp $ */ /* * Copyright (c) 1999, 2000 Matthew R. Green @@ -59,7 +59,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: iommu.c,v 1.92 2009/12/07 11:14:27 nakayama Exp $"); +__KERNEL_RCSID(0, "$NetBSD: iommu.c,v 1.93 2009/12/07 11:18:38 nakayama Exp $"); #include "opt_ddb.h" @@ -682,17 +682,18 @@ */ map->dm_nsegs = 0; /* Count up the total number of pages we need */ - pa = segs[0].ds_addr; + pa = trunc_page(segs[0].ds_addr); sgsize = 0; left = size; - for (i = 0; left && i < nsegs; i++) { + for (i = 0; left > 0 && i < nsegs; i++) { if (round_page(pa) != round_page(segs[i].ds_addr)) - sgsize = round_page(sgsize); + sgsize = round_page(sgsize) + + (segs[i].ds_addr & PGOFSET); sgsize += min(left, segs[i].ds_len); left -= segs[i].ds_len; pa = segs[i].ds_addr + segs[i].ds_len; } - sgsize = round_page(sgsize) + PAGE_SIZE; /* XXX reserve extra dvma page */ + sgsize = round_page(sgsize); s = splhigh(); /* @@ -766,6 +767,8 @@ ((offset == 0) || (pa == prev_pa))) { /* Just append to the previous segment. */ map->dm_segs[--j].ds_len += left; + /* Restore sgstart for boundary check */ + sgstart = map->dm_segs[j].ds_addr; DPRINTF(IDB_INFO, ("iommu_dvmamap_load_raw: " "appending seg %d start %lx size %lx\n", j, (long)map->dm_segs[j].ds_addr, @@ -799,7 +802,7 @@ last_va - map->_dm_dvmastart); goto fail; } - sgstart = roundup(sgstart, boundary); + sgstart += map->dm_segs[j-1].ds_len; map->dm_segs[j].ds_addr = sgstart; map->dm_segs[j].ds_len = sgend - sgstart + 1; } @@ -871,7 +874,7 @@ /* Too many segments. Fail the operation. */ goto fail; } - sgstart = roundup(sgstart, boundary); + sgstart += map->dm_segs[i-1].ds_len; map->dm_segs[i].ds_addr = sgstart; } DPRINTF(IDB_INFO, ("iommu_dvmamap_load_raw: "