diff options
author | Henric Jungheim <henric@cvs.openbsd.org> | 2003-03-06 08:26:09 +0000 |
---|---|---|
committer | Henric Jungheim <henric@cvs.openbsd.org> | 2003-03-06 08:26:09 +0000 |
commit | efca87016057d41201643e65d1f1c5d44716db0b (patch) | |
tree | 0a757cfc249bf077773a2182e04fd490183c3e6c /sys/arch/sparc64/dev/schizo.c | |
parent | 6216a22d89b680747bfb42b651aed1076b9dbf92 (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.c | 109 |
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 |