1139749Simp/*- 2113584Ssimokawa * Copyright (C) 2003 3113584Ssimokawa * Hidetoshi Shimokawa. All rights reserved. 4113584Ssimokawa * 5113584Ssimokawa * Redistribution and use in source and binary forms, with or without 6113584Ssimokawa * modification, are permitted provided that the following conditions 7113584Ssimokawa * are met: 8113584Ssimokawa * 1. Redistributions of source code must retain the above copyright 9113584Ssimokawa * notice, this list of conditions and the following disclaimer. 10113584Ssimokawa * 2. Redistributions in binary form must reproduce the above copyright 11113584Ssimokawa * notice, this list of conditions and the following disclaimer in the 12113584Ssimokawa * documentation and/or other materials provided with the distribution. 13113584Ssimokawa * 3. All advertising materials mentioning features or use of this software 14113584Ssimokawa * must display the following acknowledgement: 15113584Ssimokawa * 16113584Ssimokawa * This product includes software developed by Hidetoshi Shimokawa. 17113584Ssimokawa * 18113584Ssimokawa * 4. Neither the name of the author nor the names of its contributors 19113584Ssimokawa * may be used to endorse or promote products derived from this software 20113584Ssimokawa * without specific prior written permission. 21113584Ssimokawa * 22113584Ssimokawa * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23113584Ssimokawa * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24113584Ssimokawa * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25113584Ssimokawa * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26113584Ssimokawa * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27113584Ssimokawa * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28113584Ssimokawa * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29113584Ssimokawa * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30113584Ssimokawa * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31113584Ssimokawa * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32113584Ssimokawa * SUCH DAMAGE. 33113584Ssimokawa * 34113584Ssimokawa * $FreeBSD$ 35113584Ssimokawa */ 36113584Ssimokawa 37113584Ssimokawastruct fwdma_alloc { 38113584Ssimokawa bus_dma_tag_t dma_tag; 39113584Ssimokawa bus_dmamap_t dma_map; 40113584Ssimokawa void * v_addr; 41113584Ssimokawa bus_addr_t bus_addr; 42113584Ssimokawa}; 43113584Ssimokawa 44113584Ssimokawastruct fwdma_seg { 45113584Ssimokawa bus_dmamap_t dma_map; 46113584Ssimokawa void * v_addr; 47113584Ssimokawa bus_addr_t bus_addr; 48113584Ssimokawa}; 49113584Ssimokawa 50113584Ssimokawastruct fwdma_alloc_multi { 51113584Ssimokawa bus_size_t ssize; 52113584Ssimokawa bus_size_t esize; 53113584Ssimokawa int nseg; 54113584Ssimokawa bus_dma_tag_t dma_tag; 55113584Ssimokawa struct fwdma_seg seg[0]; 56113584Ssimokawa}; 57113584Ssimokawa 58113584Ssimokawastatic __inline void * 59113584Ssimokawafwdma_v_addr(struct fwdma_alloc_multi *am, int index) 60113584Ssimokawa{ 61113584Ssimokawa bus_size_t ssize = am->ssize; 62113584Ssimokawa int offset = am->esize * index; 63113584Ssimokawa 64113584Ssimokawa return ((caddr_t)am->seg[offset / ssize].v_addr + (offset % ssize)); 65113584Ssimokawa} 66113584Ssimokawa 67113584Ssimokawastatic __inline bus_addr_t 68113584Ssimokawafwdma_bus_addr(struct fwdma_alloc_multi *am, int index) 69113584Ssimokawa{ 70113584Ssimokawa bus_size_t ssize = am->ssize; 71113584Ssimokawa int offset = am->esize * index; 72113584Ssimokawa 73113584Ssimokawa return (am->seg[offset / ssize].bus_addr + (offset % ssize)); 74113584Ssimokawa} 75113584Ssimokawa 76113584Ssimokawastatic __inline void 77113584Ssimokawafwdma_sync(struct fwdma_alloc *dma, bus_dmasync_op_t op) 78113584Ssimokawa{ 79113584Ssimokawa bus_dmamap_sync(dma->dma_tag, dma->dma_map, op); 80113584Ssimokawa} 81113584Ssimokawa 82113584Ssimokawastatic __inline void 83113584Ssimokawafwdma_sync_multiseg(struct fwdma_alloc_multi *am, 84113584Ssimokawa int start, int end, bus_dmasync_op_t op) 85113584Ssimokawa{ 86113584Ssimokawa struct fwdma_seg *seg, *eseg; 87113584Ssimokawa 88113584Ssimokawa seg = &am->seg[am->esize * start / am->ssize]; 89113584Ssimokawa eseg = &am->seg[am->esize * end / am->ssize]; 90113584Ssimokawa for (; seg <= eseg; seg ++) 91113584Ssimokawa bus_dmamap_sync(am->dma_tag, seg->dma_map, op); 92113584Ssimokawa} 93113584Ssimokawa 94113584Ssimokawastatic __inline void 95113584Ssimokawafwdma_sync_multiseg_all(struct fwdma_alloc_multi *am, bus_dmasync_op_t op) 96113584Ssimokawa{ 97113584Ssimokawa struct fwdma_seg *seg; 98113584Ssimokawa int i; 99113584Ssimokawa 100113584Ssimokawa seg = &am->seg[0]; 101113584Ssimokawa for (i = 0; i < am->nseg; i++, seg++) 102113584Ssimokawa bus_dmamap_sync(am->dma_tag, seg->dma_map, op); 103113584Ssimokawa} 104113584Ssimokawa 105113584Ssimokawavoid *fwdma_malloc(struct firewire_comm *, int, bus_size_t, struct fwdma_alloc *, int); 106113584Ssimokawavoid fwdma_free(struct firewire_comm *, struct fwdma_alloc *); 107113584Ssimokawavoid *fwdma_malloc_size(bus_dma_tag_t, bus_dmamap_t *, bus_size_t, bus_addr_t *, int); 108113584Ssimokawavoid fwdma_free_size(bus_dma_tag_t, bus_dmamap_t, void *, bus_size_t); 109113584Ssimokawastruct fwdma_alloc_multi *fwdma_malloc_multiseg(struct firewire_comm *, 110113584Ssimokawa int, int, int, int); 111113584Ssimokawavoid fwdma_free_multiseg(struct fwdma_alloc_multi *); 112113584Ssimokawa 113