usb_busdma.h revision 190633
1/* $FreeBSD: head/sys/dev/usb/usb_busdma.h 190633 2009-04-01 20:23:47Z piso $ */ 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 49struct usb2_xfer_root; 50struct usb2_dma_parent_tag; 51struct usb2_dma_tag; 52 53/* 54 * The following typedef defines the USB DMA load done callback. 55 */ 56 57typedef void (usb2_dma_callback_t)(struct usb2_dma_parent_tag *udpt); 58 59/* 60 * The following structure defines physical and non kernel virtual 61 * address of a memory page having size USB_PAGE_SIZE. 62 */ 63struct usb2_page { 64#if USB_HAVE_BUSDMA 65 bus_size_t physaddr; 66 void *buffer; /* non Kernel Virtual Address */ 67#endif 68}; 69 70/* 71 * The following structure is used when needing the kernel virtual 72 * pointer and the physical address belonging to an offset in an USB 73 * page cache. 74 */ 75struct usb2_page_search { 76 void *buffer; 77#if USB_HAVE_BUSDMA 78 bus_size_t physaddr; 79#endif 80 usb2_size_t length; 81}; 82 83/* 84 * The following structure is used to keep information about a DMA 85 * memory allocation. 86 */ 87struct usb2_page_cache { 88 89#if USB_HAVE_BUSDMA && defined(__FreeBSD__) 90 bus_dma_tag_t tag; 91 bus_dmamap_t map; 92#endif 93#if USB_HAVE_BUSDMA && defined(__NetBSD__) 94 bus_dma_tag_t tag; 95 bus_dmamap_t map; 96 bus_dma_segment_t *p_seg; 97#endif 98#if USB_HAVE_BUSDMA 99 struct usb2_page *page_start; 100#endif 101 struct usb2_dma_parent_tag *tag_parent; /* always set */ 102 void *buffer; /* virtual buffer pointer */ 103#if USB_HAVE_BUSDMA && defined(_NetBSD__) 104 int n_seg; 105#endif 106#if USB_HAVE_BUSDMA 107 usb2_size_t page_offset_buf; 108 usb2_size_t page_offset_end; 109 uint8_t isread:1; /* set if we are currently reading 110 * from the memory. Else write. */ 111 uint8_t ismultiseg:1; /* set if we can have multiple 112 * segments */ 113#endif 114}; 115 116/* 117 * The following structure describes the parent USB DMA tag. 118 */ 119#if USB_HAVE_BUSDMA 120struct usb2_dma_parent_tag { 121#if defined(__FreeBSD__) 122 struct cv cv[1]; /* internal condition variable */ 123#endif 124 bus_dma_tag_t tag; /* always set */ 125 126 struct mtx *mtx; /* private mutex, always set */ 127 usb2_dma_callback_t *func; /* load complete callback function */ 128 struct usb2_dma_tag *utag_first;/* pointer to first USB DMA tag */ 129 uint8_t dma_error; /* set if DMA load operation failed */ 130 uint8_t dma_bits; /* number of DMA address lines */ 131 uint8_t utag_max; /* number of USB DMA tags */ 132}; 133#else 134struct usb2_dma_parent_tag {}; /* empty struct */ 135#endif 136 137/* 138 * The following structure describes an USB DMA tag. 139 */ 140#if USB_HAVE_BUSDMA 141struct usb2_dma_tag { 142#if defined(__NetBSD__) 143 bus_dma_segment_t *p_seg; 144#endif 145 struct usb2_dma_parent_tag *tag_parent; 146 bus_dma_tag_t tag; 147 148 usb2_size_t align; 149 usb2_size_t size; 150#if defined(__NetBSD__) 151 usb2_size_t n_seg; 152#endif 153}; 154#else 155struct usb2_dma_tag {}; /* empty struct */ 156#endif 157 158/* function prototypes */ 159 160int usb2_uiomove(struct usb2_page_cache *pc, struct uio *uio, 161 usb2_frlength_t pc_offset, usb2_frlength_t len); 162struct usb2_dma_tag *usb2_dma_tag_find(struct usb2_dma_parent_tag *udpt, 163 usb2_size_t size, usb2_size_t align); 164uint8_t usb2_pc_alloc_mem(struct usb2_page_cache *pc, struct usb2_page *pg, 165 usb2_size_t size, usb2_size_t align); 166uint8_t usb2_pc_dmamap_create(struct usb2_page_cache *pc, usb2_size_t size); 167uint8_t usb2_pc_load_mem(struct usb2_page_cache *pc, usb2_size_t size, 168 uint8_t sync); 169void usb2_bdma_done_event(struct usb2_dma_parent_tag *udpt); 170void usb2_bdma_post_sync(struct usb2_xfer *xfer); 171void usb2_bdma_pre_sync(struct usb2_xfer *xfer); 172void usb2_bdma_work_loop(struct usb2_xfer_queue *pq); 173void usb2_bzero(struct usb2_page_cache *cache, usb2_frlength_t offset, 174 usb2_frlength_t len); 175void usb2_copy_in(struct usb2_page_cache *cache, usb2_frlength_t offset, 176 const void *ptr, usb2_frlength_t len); 177int usb2_copy_in_user(struct usb2_page_cache *cache, usb2_frlength_t offset, 178 const void *ptr, usb2_frlength_t len); 179void usb2_copy_out(struct usb2_page_cache *cache, usb2_frlength_t offset, 180 void *ptr, usb2_frlength_t len); 181int usb2_copy_out_user(struct usb2_page_cache *cache, usb2_frlength_t offset, 182 void *ptr, usb2_frlength_t len); 183void usb2_dma_tag_setup(struct usb2_dma_parent_tag *udpt, 184 struct usb2_dma_tag *udt, bus_dma_tag_t dmat, struct mtx *mtx, 185 usb2_dma_callback_t *func, uint8_t ndmabits, uint8_t nudt); 186void usb2_dma_tag_unsetup(struct usb2_dma_parent_tag *udpt); 187void usb2_get_page(struct usb2_page_cache *pc, usb2_frlength_t offset, 188 struct usb2_page_search *res); 189void usb2_m_copy_in(struct usb2_page_cache *cache, usb2_frlength_t dst_offset, 190 struct mbuf *m, usb2_size_t src_offset, usb2_frlength_t src_len); 191void usb2_pc_cpu_flush(struct usb2_page_cache *pc); 192void usb2_pc_cpu_invalidate(struct usb2_page_cache *pc); 193void usb2_pc_dmamap_destroy(struct usb2_page_cache *pc); 194void usb2_pc_free_mem(struct usb2_page_cache *pc); 195 196#endif /* _USB2_BUSDMA_H_ */ 197