1 /* $FreeBSD$ */ 2 /*- 3 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #ifndef _USB2_BUSDMA_H_ 28 #define _USB2_BUSDMA_H_ 29 30 #include <sys/uio.h> 31 #include <sys/mbuf.h> 32 33 #include <machine/bus.h> 34 35 /* defines */ 36 37 #define USB_PAGE_SIZE PAGE_SIZE /* use system PAGE_SIZE */ 38 39 #ifdef __FreeBSD__ 40 #if (__FreeBSD_version >= 700020) 41 #define USB_GET_DMA_TAG(dev) bus_get_dma_tag(dev) 42 #else 43 #define USB_GET_DMA_TAG(dev) NULL /* XXX */ 44 #endif 45 #endif 46 47 /* structure prototypes */ 48 49 struct usb2_xfer_root; 50 struct usb2_dma_parent_tag; 51 52 /* 53 * The following typedef defines the USB DMA load done callback. 54 */ 55 56 typedef void (usb2_dma_callback_t)(struct usb2_dma_parent_tag *udpt); 57 58 /* 59 * The following structure defines physical and non kernel virtual 60 * address of a memory page having size USB_PAGE_SIZE. 61 */ 62 struct usb2_page { 63 bus_size_t physaddr; 64 void *buffer; /* non Kernel Virtual Address */ 65 }; 66 67 /* 68 * The following structure is used when needing the kernel virtual 69 * pointer and the physical address belonging to an offset in an USB 70 * page cache. 71 */ 72 struct usb2_page_search { 73 void *buffer; 74 bus_size_t physaddr; 75 uint32_t length; 76 }; 77 78 /* 79 * The following structure is used to keep information about a DMA 80 * memory allocation. 81 */ 82 struct usb2_page_cache { 83 84 #ifdef __FreeBSD__ 85 bus_dma_tag_t tag; 86 bus_dmamap_t map; 87 #endif 88 #ifdef __NetBSD__ 89 bus_dma_tag_t tag; 90 bus_dmamap_t map; 91 bus_dma_segment_t *p_seg; 92 #endif 93 struct usb2_page *page_start; 94 struct usb2_dma_parent_tag *tag_parent; /* always set */ 95 void *buffer; /* virtual buffer pointer */ 96 #ifdef __NetBSD__ 97 int n_seg; 98 #endif 99 uint32_t page_offset_buf; 100 uint32_t page_offset_end; 101 uint8_t isread:1; /* set if we are currently reading 102 * from the memory. Else write. */ 103 uint8_t ismultiseg:1; /* set if we can have multiple 104 * segments */ 105 }; 106 107 /* 108 * The following structure describes the parent USB DMA tag. 109 */ 110 struct usb2_dma_parent_tag { 111 #ifdef __FreeBSD__ 112 struct cv cv[1]; /* internal condition variable */ 113 #endif 114 115 bus_dma_tag_t tag; /* always set */ 116 117 struct mtx *mtx; /* private mutex, always set */ 118 struct usb2_xfer_root *info; /* used by the callback function */ 119 usb2_dma_callback_t *func; /* load complete callback function */ 120 struct usb2_dma_tag *utag_first;/* pointer to first USB DMA tag */ 121 122 uint8_t dma_error; /* set if DMA load operation failed */ 123 uint8_t dma_bits; /* number of DMA address lines */ 124 uint8_t utag_max; /* number of USB DMA tags */ 125 }; 126 127 /* 128 * The following structure describes an USB DMA tag. 129 */ 130 struct usb2_dma_tag { 131 #ifdef __NetBSD__ 132 bus_dma_segment_t *p_seg; 133 #endif 134 struct usb2_dma_parent_tag *tag_parent; 135 bus_dma_tag_t tag; 136 137 uint32_t align; 138 uint32_t size; 139 #ifdef __NetBSD__ 140 uint32_t n_seg; 141 #endif 142 }; 143 144 /* function prototypes */ 145 146 int usb2_uiomove(struct usb2_page_cache *pc, struct uio *uio, 147 uint32_t pc_offset, uint32_t len); 148 struct usb2_dma_tag *usb2_dma_tag_find(struct usb2_dma_parent_tag *udpt, 149 uint32_t size, uint32_t align); 150 uint8_t usb2_pc_alloc_mem(struct usb2_page_cache *pc, struct usb2_page *pg, 151 uint32_t size, uint32_t align); 152 uint8_t usb2_pc_dmamap_create(struct usb2_page_cache *pc, uint32_t size); 153 uint8_t usb2_pc_load_mem(struct usb2_page_cache *pc, uint32_t size, 154 uint8_t sync); 155 void usb2_bdma_done_event(struct usb2_dma_parent_tag *udpt); 156 void usb2_bdma_post_sync(struct usb2_xfer *xfer); 157 void usb2_bdma_pre_sync(struct usb2_xfer *xfer); 158 void usb2_bdma_work_loop(struct usb2_xfer_queue *pq); 159 void usb2_bzero(struct usb2_page_cache *cache, uint32_t offset, 160 uint32_t len); 161 void usb2_copy_in(struct usb2_page_cache *cache, uint32_t offset, 162 const void *ptr, uint32_t len); 163 int usb2_copy_in_user(struct usb2_page_cache *cache, uint32_t offset, 164 const void *ptr, uint32_t len); 165 void usb2_copy_out(struct usb2_page_cache *cache, uint32_t offset, 166 void *ptr, uint32_t len); 167 int usb2_copy_out_user(struct usb2_page_cache *cache, uint32_t offset, 168 void *ptr, uint32_t len); 169 void usb2_dma_tag_setup(struct usb2_dma_parent_tag *udpt, 170 struct usb2_dma_tag *udt, bus_dma_tag_t dmat, struct mtx *mtx, 171 usb2_dma_callback_t *func, struct usb2_xfer_root *info, 172 uint8_t ndmabits, uint8_t nudt); 173 void usb2_dma_tag_unsetup(struct usb2_dma_parent_tag *udpt); 174 void usb2_get_page(struct usb2_page_cache *pc, uint32_t offset, 175 struct usb2_page_search *res); 176 void usb2_m_copy_in(struct usb2_page_cache *cache, uint32_t dst_offset, 177 struct mbuf *m, uint32_t src_offset, uint32_t src_len); 178 void usb2_pc_cpu_flush(struct usb2_page_cache *pc); 179 void usb2_pc_cpu_invalidate(struct usb2_page_cache *pc); 180 void usb2_pc_dmamap_destroy(struct usb2_page_cache *pc); 181 void usb2_pc_free_mem(struct usb2_page_cache *pc); 182 183 #endif /* _USB2_BUSDMA_H_ */ 184