summaryrefslogtreecommitdiff
path: root/sys/arch/sparc64/dev/schizo.c
diff options
context:
space:
mode:
authorHenric Jungheim <henric@cvs.openbsd.org>2003-03-06 08:26:09 +0000
committerHenric Jungheim <henric@cvs.openbsd.org>2003-03-06 08:26:09 +0000
commitefca87016057d41201643e65d1f1c5d44716db0b (patch)
tree0a757cfc249bf077773a2182e04fd490183c3e6c /sys/arch/sparc64/dev/schizo.c
parent6216a22d89b680747bfb42b651aed1076b9dbf92 (diff)
The existing IOMMU code had a rounding problem that was most noticeable
on faster systems under heavy network load. This replaces some of the unreadable iommu functions with something a little less dense and a lot less crash prone. The bus_dma function pointer/cookie handling was broken. Change them to work like the stacked bus_space drivers (where "work" is the key word). Tested my many (thanks). ok jason@ deraadt@
Diffstat (limited to 'sys/arch/sparc64/dev/schizo.c')
-rw-r--r--sys/arch/sparc64/dev/schizo.c109
1 files changed, 67 insertions, 42 deletions
diff --git a/sys/arch/sparc64/dev/schizo.c b/sys/arch/sparc64/dev/schizo.c
index 77691e871fb..84c0b603d66 100644
--- a/sys/arch/sparc64/dev/schizo.c
+++ b/sys/arch/sparc64/dev/schizo.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: schizo.c,v 1.10 2003/02/22 19:54:43 jason Exp $ */
+/* $OpenBSD: schizo.c,v 1.11 2003/03/06 08:26:08 henric Exp $ */
/*
* Copyright (c) 2002 Jason L. Wright (jason@thought.net)
@@ -90,19 +90,22 @@ void *_schizo_intr_establish(bus_space_tag_t, bus_space_tag_t, int, int, int,
int (*)(void *), void *);
paddr_t _schizo_bus_mmap(bus_space_tag_t, bus_space_tag_t, bus_addr_t, off_t, int, int);
-int schizo_dmamap_load(bus_dma_tag_t, bus_dmamap_t, void *,
+int schizo_dmamap_create(bus_dma_tag_t, bus_dma_tag_t, bus_size_t, int,
+ bus_size_t, bus_size_t, int, bus_dmamap_t *);
+void schizo_dmamap_destroy(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t);
+int schizo_dmamap_load(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t, void *,
bus_size_t, struct proc *, int);
-void schizo_dmamap_unload(bus_dma_tag_t, bus_dmamap_t);
-int schizo_dmamap_load_raw(bus_dma_tag_t, bus_dmamap_t,
+void schizo_dmamap_unload(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t);
+int schizo_dmamap_load_raw(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t,
bus_dma_segment_t *, int, bus_size_t, int);
-void schizo_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
+void schizo_dmamap_sync(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
bus_size_t, int);
-int schizo_dmamem_alloc(bus_dma_tag_t, bus_size_t, bus_size_t, bus_size_t,
- bus_dma_segment_t *, int, int *, int);
-void schizo_dmamem_free(bus_dma_tag_t, bus_dma_segment_t *, int);
-int schizo_dmamem_map(bus_dma_tag_t, bus_dma_segment_t *, int, size_t,
- caddr_t *, int);
-void schizo_dmamem_unmap(bus_dma_tag_t, caddr_t, size_t);
+int schizo_dmamem_alloc(bus_dma_tag_t, bus_dma_tag_t, bus_size_t, bus_size_t,
+ bus_size_t, bus_dma_segment_t *, int, int *, int);
+void schizo_dmamem_free(bus_dma_tag_t, bus_dma_tag_t, bus_dma_segment_t *, int);
+int schizo_dmamem_map(bus_dma_tag_t, bus_dma_tag_t, bus_dma_segment_t *, int,
+ size_t, caddr_t *, int);
+void schizo_dmamem_unmap(bus_dma_tag_t, bus_dma_tag_t, caddr_t, size_t);
int
schizo_match(struct device *parent, void *match, void *aux)
@@ -338,12 +341,9 @@ schizo_alloc_dma_tag(struct schizo_pbm *pbm)
bzero(dt, sizeof(*dt));
dt->_cookie = pbm;
dt->_parent = pdt;
-#define PCOPY(x) dt->x = pdt->x
- PCOPY(_dmamap_create);
- PCOPY(_dmamap_destroy);
+ dt->_dmamap_create = schizo_dmamap_create;
+ dt->_dmamap_destroy = schizo_dmamap_destroy;
dt->_dmamap_load = schizo_dmamap_load;
- PCOPY(_dmamap_load_mbuf);
- PCOPY(_dmamap_load_uio);
dt->_dmamap_load_raw = schizo_dmamap_load_raw;
dt->_dmamap_unload = schizo_dmamap_unload;
dt->_dmamap_sync = schizo_dmamap_sync;
@@ -351,8 +351,6 @@ schizo_alloc_dma_tag(struct schizo_pbm *pbm)
dt->_dmamem_free = schizo_dmamem_free;
dt->_dmamem_map = schizo_dmamem_map;
dt->_dmamem_unmap = schizo_dmamem_unmap;
- PCOPY(_dmamem_mmap);
-#undef PCOPY
return (dt);
}
@@ -372,85 +370,112 @@ schizo_alloc_chipset(struct schizo_pbm *pbm, int node, pci_chipset_tag_t pc)
}
int
-schizo_dmamap_load(bus_dma_tag_t t, bus_dmamap_t map, void *buf,
- bus_size_t buflen, struct proc *p, int flags)
+schizo_dmamap_create(bus_dma_tag_t t, bus_dma_tag_t t0, bus_size_t size,
+ int nsegments, bus_size_t maxsegsz, bus_size_t boundary, int flags,
+ bus_dmamap_t *dmamp)
+{
+ struct schizo_pbm *sp = t->_cookie;
+
+ return (iommu_dvmamap_create(t0, &sp->sp_is, &sp->sp_sb, size,
+ nsegments, maxsegsz, boundary, flags, dmamp));
+}
+
+void
+schizo_dmamap_destroy(bus_dma_tag_t t, bus_dma_tag_t t0, bus_dmamap_t map)
+{
+ iommu_dvmamap_destroy(t0, map);
+}
+
+int
+schizo_dmamap_load(bus_dma_tag_t t, bus_dma_tag_t t0, bus_dmamap_t map,
+ void *buf, bus_size_t buflen, struct proc *p, int flags)
{
struct schizo_pbm *pbm = t->_cookie;
- return (iommu_dvmamap_load(t, &pbm->sp_is, map, buf, buflen, p, flags));
+ return (iommu_dvmamap_load(t0, &pbm->sp_is, map, buf, buflen, p,
+ flags));
}
void
-schizo_dmamap_unload(bus_dma_tag_t t, bus_dmamap_t map)
+schizo_dmamap_unload(bus_dma_tag_t t, bus_dma_tag_t t0, bus_dmamap_t map)
{
struct schizo_pbm *pbm = t->_cookie;
- iommu_dvmamap_unload(t, &pbm->sp_is, map);
+ iommu_dvmamap_unload(t0, &pbm->sp_is, map);
}
int
-schizo_dmamap_load_raw(bus_dma_tag_t t, bus_dmamap_t map,
+schizo_dmamap_load_raw(bus_dma_tag_t t, bus_dma_tag_t t0, bus_dmamap_t map,
bus_dma_segment_t *segs, int nsegs, bus_size_t size, int flags)
{
struct schizo_pbm *pbm = t->_cookie;
- return (iommu_dvmamap_load_raw(t, &pbm->sp_is, map, segs, nsegs,
+ return (iommu_dvmamap_load_raw(t0, &pbm->sp_is, map, segs, nsegs,
flags, size));
}
void
-schizo_dmamap_sync(bus_dma_tag_t t, bus_dmamap_t map, bus_addr_t offset,
- bus_size_t len, int ops)
+schizo_dmamap_sync(bus_dma_tag_t t, bus_dma_tag_t t0, bus_dmamap_t map,
+ bus_addr_t offset, bus_size_t len, int ops)
{
struct schizo_pbm *pbm = t->_cookie;
+ if (t->_parent == NULL)
+ panic("schizo_dmamap_sync: no parent");
+
+ for (t = t->_parent; t->_dmamap_sync == NULL; t = t->_parent)
+ if (t == NULL)
+ panic("schizo_dmamap_sync: can't find implementation");
+
+
if (ops & (BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE)) {
/* Flush the CPU then the IOMMU */
- bus_dmamap_sync(t->_parent, map, offset, len, ops);
- iommu_dvmamap_sync(t, &pbm->sp_is, map, offset, len, ops);
+ (*t->_dmamap_sync)(t, t0, map, offset, len, ops);
+ iommu_dvmamap_sync(t0, &pbm->sp_is, map, offset, len, ops);
}
if (ops & (BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE)) {
/* Flush the IOMMU then the CPU */
- iommu_dvmamap_sync(t, &pbm->sp_is, map, offset, len, ops);
- bus_dmamap_sync(t->_parent, map, offset, len, ops);
+ iommu_dvmamap_sync(t0, &pbm->sp_is, map, offset, len, ops);
+ (*t->_dmamap_sync)(t, t0, map, offset, len, ops);
}
}
int
-schizo_dmamem_alloc(bus_dma_tag_t t, bus_size_t size, bus_size_t alignment,
- bus_size_t boundary, bus_dma_segment_t *segs, int nsegs, int *rsegs,
- int flags)
+schizo_dmamem_alloc(bus_dma_tag_t t, bus_dma_tag_t t0, bus_size_t size,
+ bus_size_t alignment, bus_size_t boundary, bus_dma_segment_t *segs,
+ int nsegs, int *rsegs, int flags)
{
struct schizo_pbm *pbm = t->_cookie;
- return (iommu_dvmamem_alloc(t, &pbm->sp_is, size, alignment, boundary,
+ return (iommu_dvmamem_alloc(t0, &pbm->sp_is, size, alignment, boundary,
segs, nsegs, rsegs, flags));
}
void
-schizo_dmamem_free(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs)
+schizo_dmamem_free(bus_dma_tag_t t, bus_dma_tag_t t0, bus_dma_segment_t *segs,
+ int nsegs)
{
struct schizo_pbm *pbm = t->_cookie;
- iommu_dvmamem_free(t, &pbm->sp_is, segs, nsegs);
+ iommu_dvmamem_free(t0, &pbm->sp_is, segs, nsegs);
}
int
-schizo_dmamem_map(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs,
- size_t size, caddr_t *kvap, int flags)
+schizo_dmamem_map(bus_dma_tag_t t, bus_dma_tag_t t0, bus_dma_segment_t *segs,
+ int nsegs, size_t size, caddr_t *kvap, int flags)
{
struct schizo_pbm *pbm = t->_cookie;
- return (iommu_dvmamem_map(t, &pbm->sp_is, segs, nsegs, size,
+ return (iommu_dvmamem_map(t0, &pbm->sp_is, segs, nsegs, size,
kvap, flags));
}
void
-schizo_dmamem_unmap(bus_dma_tag_t t, caddr_t kva, size_t size)
+schizo_dmamem_unmap(bus_dma_tag_t t, bus_dma_tag_t t0, caddr_t kva, size_t size)
{
struct schizo_pbm *pbm = t->_cookie;
- iommu_dvmamem_unmap(t, &pbm->sp_is, kva, size);
+ iommu_dvmamem_unmap(t0, &pbm->sp_is, kva, size);
}
int