xref: /freebsd/sys/dev/usb/usb_busdma.h (revision 39beb93c3f8bdbf72a61fda42300b5ebed7390c8)
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