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