summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJason Wright <jason@cvs.openbsd.org>2002-02-22 21:53:22 +0000
committerJason Wright <jason@cvs.openbsd.org>2002-02-22 21:53:22 +0000
commit01e0ff1a85844a952cf9ba2cf9643bbf3dedc338 (patch)
tree2eefaaf16fbdd69011e62b77e4db8b3a5efcd7c0 /sys
parentc876b8dec41fc84fa8a4c0b1b8d6ce4dc10593ef (diff)
Be sure to wait the whole 0.5 seconds (half a second!) for the streaming
cache to flush, not some fraction of it, before giving up.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/sparc64/dev/iommu.c42
1 files changed, 26 insertions, 16 deletions
diff --git a/sys/arch/sparc64/dev/iommu.c b/sys/arch/sparc64/dev/iommu.c
index 23944dbb371..141fec3b576 100644
--- a/sys/arch/sparc64/dev/iommu.c
+++ b/sys/arch/sparc64/dev/iommu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: iommu.c,v 1.10 2002/02/22 20:21:46 deraadt Exp $ */
+/* $OpenBSD: iommu.c,v 1.11 2002/02/22 21:53:21 jason Exp $ */
/* $NetBSD: iommu.c,v 1.47 2002/02/08 20:03:45 eeh Exp $ */
/*
@@ -83,6 +83,7 @@ int iommu_dvmamap_sync_seg(bus_dma_tag_t, struct iommu_state *,
} while (0)
static int iommu_strbuf_flush_done __P((struct iommu_state *));
+static int iommu_tv_comp(struct timeval *, struct timeval *);
/*
* initialise the UltraSPARC IOMMU (SBUS or PCI):
@@ -351,23 +352,28 @@ iommu_remove(is, va, len)
}
}
+static int
+iommu_tv_comp(t1, t2)
+ struct timeval *t1, *t2;
+{
+ if (t1->tv_sec < t2->tv_sec)
+ return (-1);
+ if (t1->tv_sec > t2->tv_sec)
+ return (1);
+ /* t1->tv_sec == t2->tv_sec */
+ if (t1->tv_usec < t2->tv_usec)
+ return (-1);
+ if (t1->tv_usec > t2->tv_usec)
+ return (1);
+ return (0);
+}
+
static int
iommu_strbuf_flush_done(is)
struct iommu_state *is;
{
struct timeval cur, flushtimeout;
-#define BUMPTIME(t, usec) { \
- register volatile struct timeval *tp = (t); \
- register long us; \
- \
- tp->tv_usec = us = tp->tv_usec + (usec); \
- if (us >= 1000000) { \
- tp->tv_usec = us - 1000000; \
- tp->tv_sec++; \
- } \
-}
-
if (!is->is_sb[0] && !is->is_sb[1])
return (0);
@@ -403,9 +409,13 @@ iommu_strbuf_flush_done(is)
BUS_SPACE_BARRIER_WRITE);
}
- microtime(&flushtimeout);
- cur = flushtimeout;
- BUMPTIME(&flushtimeout, 500000); /* 1/2 sec */
+ microtime(&cur);
+ flushtimeout.tv_usec = cur.tv_usec + 500000; /* 1/2 sec */
+ if (flushtimeout.tv_usec >= 1000000) {
+ flushtimeout.tv_usec -= 1000000;
+ flushtimeout.tv_sec = cur.tv_sec + 1;
+ } else
+ flushtimeout.tv_sec = cur.tv_sec;
DPRINTF(IDB_IOMMU, ("iommu_strbuf_flush_done: flush = %lx at va = %lx pa = %lx now=%lx:%lx until = %lx:%lx\n",
(long)is->is_flush, (long)&is->is_flush,
@@ -415,7 +425,7 @@ iommu_strbuf_flush_done(is)
/* Bypass non-coherent D$ */
while (((ldxa(is->is_flushpa, ASI_PHYS_CACHED) == 0) ||
(ldxa(is->is_flushpa + 8, ASI_PHYS_CACHED) == 0)) &&
- ((cur.tv_sec <= flushtimeout.tv_sec) && (cur.tv_usec <= flushtimeout.tv_usec))) {
+ (iommu_tv_comp(&cur, &flushtimeout) <= 0)) {
microtime(&cur);
}