xref: /freebsd/sys/dev/usb/usb_busdma.c (revision 195ebc7e9e4b129de810833791a19dfb4349d6a9)
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 #include <dev/usb/usb_mfunc.h>
28 #include <dev/usb/usb_error.h>
29 #include <dev/usb/usb.h>
30 
31 #define	USB_DEBUG_VAR usb2_debug
32 
33 #include <dev/usb/usb_core.h>
34 #include <dev/usb/usb_busdma.h>
35 #include <dev/usb/usb_process.h>
36 #include <dev/usb/usb_transfer.h>
37 #include <dev/usb/usb_device.h>
38 #include <dev/usb/usb_util.h>
39 #include <dev/usb/usb_debug.h>
40 
41 #include <dev/usb/usb_controller.h>
42 #include <dev/usb/usb_bus.h>
43 
44 #if USB_HAVE_BUSDMA
45 static void	usb2_dma_tag_create(struct usb_dma_tag *, usb_size_t, usb_size_t);
46 static void	usb2_dma_tag_destroy(struct usb_dma_tag *);
47 static void	usb2_dma_lock_cb(void *, bus_dma_lock_op_t);
48 static void	usb2_pc_alloc_mem_cb(void *, bus_dma_segment_t *, int, int);
49 static void	usb2_pc_load_mem_cb(void *, bus_dma_segment_t *, int, int);
50 static void	usb2_pc_common_mem_cb(void *, bus_dma_segment_t *, int, int,
51 		    uint8_t);
52 #endif
53 
54 /*------------------------------------------------------------------------*
55  *  usb2_get_page - lookup DMA-able memory for the given offset
56  *
57  * NOTE: Only call this function when the "page_cache" structure has
58  * been properly initialized !
59  *------------------------------------------------------------------------*/
60 void
61 usb2_get_page(struct usb_page_cache *pc, usb_frlength_t offset,
62     struct usb_page_search *res)
63 {
64 	struct usb_page *page;
65 
66 #if USB_HAVE_BUSDMA
67 	if (pc->page_start) {
68 
69 		/* Case 1 - something has been loaded into DMA */
70 
71 		if (pc->buffer) {
72 
73 			/* Case 1a - Kernel Virtual Address */
74 
75 			res->buffer = USB_ADD_BYTES(pc->buffer, offset);
76 		}
77 		offset += pc->page_offset_buf;
78 
79 		/* compute destination page */
80 
81 		page = pc->page_start;
82 
83 		if (pc->ismultiseg) {
84 
85 			page += (offset / USB_PAGE_SIZE);
86 
87 			offset %= USB_PAGE_SIZE;
88 
89 			res->length = USB_PAGE_SIZE - offset;
90 			res->physaddr = page->physaddr + offset;
91 		} else {
92 			res->length = 0 - 1;
93 			res->physaddr = page->physaddr + offset;
94 		}
95 		if (!pc->buffer) {
96 
97 			/* Case 1b - Non Kernel Virtual Address */
98 
99 			res->buffer = USB_ADD_BYTES(page->buffer, offset);
100 		}
101 		return;
102 	}
103 #endif
104 	/* Case 2 - Plain PIO */
105 
106 	res->buffer = USB_ADD_BYTES(pc->buffer, offset);
107 	res->length = 0 - 1;
108 #if USB_HAVE_BUSDMA
109 	res->physaddr = 0;
110 #endif
111 }
112 
113 /*------------------------------------------------------------------------*
114  *  usb2_copy_in - copy directly to DMA-able memory
115  *------------------------------------------------------------------------*/
116 void
117 usb2_copy_in(struct usb_page_cache *cache, usb_frlength_t offset,
118     const void *ptr, usb_frlength_t len)
119 {
120 	struct usb_page_search buf_res;
121 
122 	while (len != 0) {
123 
124 		usb2_get_page(cache, offset, &buf_res);
125 
126 		if (buf_res.length > len) {
127 			buf_res.length = len;
128 		}
129 		bcopy(ptr, buf_res.buffer, buf_res.length);
130 
131 		offset += buf_res.length;
132 		len -= buf_res.length;
133 		ptr = USB_ADD_BYTES(ptr, buf_res.length);
134 	}
135 }
136 
137 /*------------------------------------------------------------------------*
138  *  usb2_copy_in_user - copy directly to DMA-able memory from userland
139  *
140  * Return values:
141  *    0: Success
142  * Else: Failure
143  *------------------------------------------------------------------------*/
144 #if USB_HAVE_USER_IO
145 int
146 usb2_copy_in_user(struct usb_page_cache *cache, usb_frlength_t offset,
147     const void *ptr, usb_frlength_t len)
148 {
149 	struct usb_page_search buf_res;
150 	int error;
151 
152 	while (len != 0) {
153 
154 		usb2_get_page(cache, offset, &buf_res);
155 
156 		if (buf_res.length > len) {
157 			buf_res.length = len;
158 		}
159 		error = copyin(ptr, buf_res.buffer, buf_res.length);
160 		if (error)
161 			return (error);
162 
163 		offset += buf_res.length;
164 		len -= buf_res.length;
165 		ptr = USB_ADD_BYTES(ptr, buf_res.length);
166 	}
167 	return (0);			/* success */
168 }
169 #endif
170 
171 /*------------------------------------------------------------------------*
172  *  usb2_m_copy_in - copy a mbuf chain directly into DMA-able memory
173  *------------------------------------------------------------------------*/
174 #if USB_HAVE_MBUF
175 struct usb2_m_copy_in_arg {
176 	struct usb_page_cache *cache;
177 	usb_frlength_t dst_offset;
178 };
179 
180 static int
181 usb2_m_copy_in_cb(void *arg, void *src, uint32_t count)
182 {
183 	register struct usb2_m_copy_in_arg *ua = arg;
184 
185 	usb2_copy_in(ua->cache, ua->dst_offset, src, count);
186 	ua->dst_offset += count;
187 	return (0);
188 }
189 
190 void
191 usb2_m_copy_in(struct usb_page_cache *cache, usb_frlength_t dst_offset,
192     struct mbuf *m, usb_size_t src_offset, usb_frlength_t src_len)
193 {
194 	struct usb2_m_copy_in_arg arg = {cache, dst_offset};
195 	int error;
196 
197 	error = m_apply(m, src_offset, src_len, &usb2_m_copy_in_cb, &arg);
198 }
199 #endif
200 
201 /*------------------------------------------------------------------------*
202  *  usb2_uiomove - factored out code
203  *------------------------------------------------------------------------*/
204 #if USB_HAVE_USER_IO
205 int
206 usb2_uiomove(struct usb_page_cache *pc, struct uio *uio,
207     usb_frlength_t pc_offset, usb_frlength_t len)
208 {
209 	struct usb_page_search res;
210 	int error = 0;
211 
212 	while (len != 0) {
213 
214 		usb2_get_page(pc, pc_offset, &res);
215 
216 		if (res.length > len) {
217 			res.length = len;
218 		}
219 		/*
220 		 * "uiomove()" can sleep so one needs to make a wrapper,
221 		 * exiting the mutex and checking things
222 		 */
223 		error = uiomove(res.buffer, res.length, uio);
224 
225 		if (error) {
226 			break;
227 		}
228 		pc_offset += res.length;
229 		len -= res.length;
230 	}
231 	return (error);
232 }
233 #endif
234 
235 /*------------------------------------------------------------------------*
236  *  usb2_copy_out - copy directly from DMA-able memory
237  *------------------------------------------------------------------------*/
238 void
239 usb2_copy_out(struct usb_page_cache *cache, usb_frlength_t offset,
240     void *ptr, usb_frlength_t len)
241 {
242 	struct usb_page_search res;
243 
244 	while (len != 0) {
245 
246 		usb2_get_page(cache, offset, &res);
247 
248 		if (res.length > len) {
249 			res.length = len;
250 		}
251 		bcopy(res.buffer, ptr, res.length);
252 
253 		offset += res.length;
254 		len -= res.length;
255 		ptr = USB_ADD_BYTES(ptr, res.length);
256 	}
257 }
258 
259 /*------------------------------------------------------------------------*
260  *  usb2_copy_out_user - copy directly from DMA-able memory to userland
261  *
262  * Return values:
263  *    0: Success
264  * Else: Failure
265  *------------------------------------------------------------------------*/
266 #if USB_HAVE_USER_IO
267 int
268 usb2_copy_out_user(struct usb_page_cache *cache, usb_frlength_t offset,
269     void *ptr, usb_frlength_t len)
270 {
271 	struct usb_page_search res;
272 	int error;
273 
274 	while (len != 0) {
275 
276 		usb2_get_page(cache, offset, &res);
277 
278 		if (res.length > len) {
279 			res.length = len;
280 		}
281 		error = copyout(res.buffer, ptr, res.length);
282 		if (error)
283 			return (error);
284 
285 		offset += res.length;
286 		len -= res.length;
287 		ptr = USB_ADD_BYTES(ptr, res.length);
288 	}
289 	return (0);			/* success */
290 }
291 #endif
292 
293 /*------------------------------------------------------------------------*
294  *  usb2_bzero - zero DMA-able memory
295  *------------------------------------------------------------------------*/
296 void
297 usb2_bzero(struct usb_page_cache *cache, usb_frlength_t offset,
298     usb_frlength_t len)
299 {
300 	struct usb_page_search res;
301 
302 	while (len != 0) {
303 
304 		usb2_get_page(cache, offset, &res);
305 
306 		if (res.length > len) {
307 			res.length = len;
308 		}
309 		bzero(res.buffer, res.length);
310 
311 		offset += res.length;
312 		len -= res.length;
313 	}
314 }
315 
316 #if USB_HAVE_BUSDMA
317 
318 /*------------------------------------------------------------------------*
319  *	usb2_dma_lock_cb - dummy callback
320  *------------------------------------------------------------------------*/
321 static void
322 usb2_dma_lock_cb(void *arg, bus_dma_lock_op_t op)
323 {
324 	/* we use "mtx_owned()" instead of this function */
325 }
326 
327 /*------------------------------------------------------------------------*
328  *	usb2_dma_tag_create - allocate a DMA tag
329  *
330  * NOTE: If the "align" parameter has a value of 1 the DMA-tag will
331  * allow multi-segment mappings. Else all mappings are single-segment.
332  *------------------------------------------------------------------------*/
333 static void
334 usb2_dma_tag_create(struct usb_dma_tag *udt,
335     usb_size_t size, usb_size_t align)
336 {
337 	bus_dma_tag_t tag;
338 
339 	if (bus_dma_tag_create
340 	    ( /* parent    */ udt->tag_parent->tag,
341 	     /* alignment */ align,
342 	     /* boundary  */ USB_PAGE_SIZE,
343 	     /* lowaddr   */ (2ULL << (udt->tag_parent->dma_bits - 1)) - 1,
344 	     /* highaddr  */ BUS_SPACE_MAXADDR,
345 	     /* filter    */ NULL,
346 	     /* filterarg */ NULL,
347 	     /* maxsize   */ size,
348 	     /* nsegments */ (align == 1) ?
349 	    (2 + (size / USB_PAGE_SIZE)) : 1,
350 	     /* maxsegsz  */ (align == 1) ?
351 	    USB_PAGE_SIZE : size,
352 	     /* flags     */ BUS_DMA_KEEP_PG_OFFSET,
353 	     /* lockfn    */ &usb2_dma_lock_cb,
354 	     /* lockarg   */ NULL,
355 	    &tag)) {
356 		tag = NULL;
357 	}
358 	udt->tag = tag;
359 }
360 
361 /*------------------------------------------------------------------------*
362  *	usb2_dma_tag_free - free a DMA tag
363  *------------------------------------------------------------------------*/
364 static void
365 usb2_dma_tag_destroy(struct usb_dma_tag *udt)
366 {
367 	bus_dma_tag_destroy(udt->tag);
368 }
369 
370 /*------------------------------------------------------------------------*
371  *	usb2_pc_alloc_mem_cb - BUS-DMA callback function
372  *------------------------------------------------------------------------*/
373 static void
374 usb2_pc_alloc_mem_cb(void *arg, bus_dma_segment_t *segs,
375     int nseg, int error)
376 {
377 	usb2_pc_common_mem_cb(arg, segs, nseg, error, 0);
378 }
379 
380 /*------------------------------------------------------------------------*
381  *	usb2_pc_load_mem_cb - BUS-DMA callback function
382  *------------------------------------------------------------------------*/
383 static void
384 usb2_pc_load_mem_cb(void *arg, bus_dma_segment_t *segs,
385     int nseg, int error)
386 {
387 	usb2_pc_common_mem_cb(arg, segs, nseg, error, 1);
388 }
389 
390 /*------------------------------------------------------------------------*
391  *	usb2_pc_common_mem_cb - BUS-DMA callback function
392  *------------------------------------------------------------------------*/
393 static void
394 usb2_pc_common_mem_cb(void *arg, bus_dma_segment_t *segs,
395     int nseg, int error, uint8_t isload)
396 {
397 	struct usb_dma_parent_tag *uptag;
398 	struct usb_page_cache *pc;
399 	struct usb_page *pg;
400 	usb_size_t rem;
401 	uint8_t owned;
402 
403 	pc = arg;
404 	uptag = pc->tag_parent;
405 
406 	/*
407 	 * XXX There is sometimes recursive locking here.
408 	 * XXX We should try to find a better solution.
409 	 * XXX Until further the "owned" variable does
410 	 * XXX the trick.
411 	 */
412 
413 	if (error) {
414 		goto done;
415 	}
416 	pg = pc->page_start;
417 	pg->physaddr = segs->ds_addr & ~(USB_PAGE_SIZE - 1);
418 	rem = segs->ds_addr & (USB_PAGE_SIZE - 1);
419 	pc->page_offset_buf = rem;
420 	pc->page_offset_end += rem;
421 	nseg--;
422 #if (USB_DEBUG != 0)
423 	if (rem != (USB_P2U(pc->buffer) & (USB_PAGE_SIZE - 1))) {
424 		/*
425 		 * This check verifies that the physical address is correct:
426 		 */
427 		DPRINTFN(0, "Page offset was not preserved!\n");
428 		error = 1;
429 		goto done;
430 	}
431 #endif
432 	while (nseg > 0) {
433 		nseg--;
434 		segs++;
435 		pg++;
436 		pg->physaddr = segs->ds_addr & ~(USB_PAGE_SIZE - 1);
437 	}
438 
439 done:
440 	owned = mtx_owned(uptag->mtx);
441 	if (!owned)
442 		mtx_lock(uptag->mtx);
443 
444 	uptag->dma_error = (error ? 1 : 0);
445 	if (isload) {
446 		(uptag->func) (uptag);
447 	} else {
448 		usb2_cv_broadcast(uptag->cv);
449 	}
450 	if (!owned)
451 		mtx_unlock(uptag->mtx);
452 }
453 
454 /*------------------------------------------------------------------------*
455  *	usb2_pc_alloc_mem - allocate DMA'able memory
456  *
457  * Returns:
458  *    0: Success
459  * Else: Failure
460  *------------------------------------------------------------------------*/
461 uint8_t
462 usb2_pc_alloc_mem(struct usb_page_cache *pc, struct usb_page *pg,
463     usb_size_t size, usb_size_t align)
464 {
465 	struct usb_dma_parent_tag *uptag;
466 	struct usb_dma_tag *utag;
467 	bus_dmamap_t map;
468 	void *ptr;
469 	int err;
470 
471 	uptag = pc->tag_parent;
472 
473 	if (align != 1) {
474 		/*
475 	         * The alignment must be greater or equal to the
476 	         * "size" else the object can be split between two
477 	         * memory pages and we get a problem!
478 	         */
479 		while (align < size) {
480 			align *= 2;
481 			if (align == 0) {
482 				goto error;
483 			}
484 		}
485 #if 1
486 		/*
487 		 * XXX BUS-DMA workaround - FIXME later:
488 		 *
489 		 * We assume that that the aligment at this point of
490 		 * the code is greater than or equal to the size and
491 		 * less than two times the size, so that if we double
492 		 * the size, the size will be greater than the
493 		 * alignment.
494 		 *
495 		 * The bus-dma system has a check for "alignment"
496 		 * being less than "size". If that check fails we end
497 		 * up using contigmalloc which is page based even for
498 		 * small allocations. Try to avoid that to save
499 		 * memory, hence we sometimes to a large number of
500 		 * small allocations!
501 		 */
502 		if (size <= (USB_PAGE_SIZE / 2)) {
503 			size *= 2;
504 		}
505 #endif
506 	}
507 	/* get the correct DMA tag */
508 	utag = usb2_dma_tag_find(uptag, size, align);
509 	if (utag == NULL) {
510 		goto error;
511 	}
512 	/* allocate memory */
513 	if (bus_dmamem_alloc(
514 	    utag->tag, &ptr, (BUS_DMA_WAITOK | BUS_DMA_COHERENT), &map)) {
515 		goto error;
516 	}
517 	/* setup page cache */
518 	pc->buffer = ptr;
519 	pc->page_start = pg;
520 	pc->page_offset_buf = 0;
521 	pc->page_offset_end = size;
522 	pc->map = map;
523 	pc->tag = utag->tag;
524 	pc->ismultiseg = (align == 1);
525 
526 	mtx_lock(uptag->mtx);
527 
528 	/* load memory into DMA */
529 	err = bus_dmamap_load(
530 	    utag->tag, map, ptr, size, &usb2_pc_alloc_mem_cb,
531 	    pc, (BUS_DMA_WAITOK | BUS_DMA_COHERENT));
532 
533 	if (err == EINPROGRESS) {
534 		usb2_cv_wait(uptag->cv, uptag->mtx);
535 		err = 0;
536 	}
537 	mtx_unlock(uptag->mtx);
538 
539 	if (err || uptag->dma_error) {
540 		bus_dmamem_free(utag->tag, ptr, map);
541 		goto error;
542 	}
543 	bzero(ptr, size);
544 
545 	usb2_pc_cpu_flush(pc);
546 
547 	return (0);
548 
549 error:
550 	/* reset most of the page cache */
551 	pc->buffer = NULL;
552 	pc->page_start = NULL;
553 	pc->page_offset_buf = 0;
554 	pc->page_offset_end = 0;
555 	pc->map = NULL;
556 	pc->tag = NULL;
557 	return (1);
558 }
559 
560 /*------------------------------------------------------------------------*
561  *	usb2_pc_free_mem - free DMA memory
562  *
563  * This function is NULL safe.
564  *------------------------------------------------------------------------*/
565 void
566 usb2_pc_free_mem(struct usb_page_cache *pc)
567 {
568 	if (pc && pc->buffer) {
569 
570 		bus_dmamap_unload(pc->tag, pc->map);
571 
572 		bus_dmamem_free(pc->tag, pc->buffer, pc->map);
573 
574 		pc->buffer = NULL;
575 	}
576 }
577 
578 /*------------------------------------------------------------------------*
579  *	usb2_pc_load_mem - load virtual memory into DMA
580  *
581  * Return values:
582  * 0: Success
583  * Else: Error
584  *------------------------------------------------------------------------*/
585 uint8_t
586 usb2_pc_load_mem(struct usb_page_cache *pc, usb_size_t size, uint8_t sync)
587 {
588 	/* setup page cache */
589 	pc->page_offset_buf = 0;
590 	pc->page_offset_end = size;
591 	pc->ismultiseg = 1;
592 
593 	mtx_assert(pc->tag_parent->mtx, MA_OWNED);
594 
595 	if (size > 0) {
596 		if (sync) {
597 			struct usb_dma_parent_tag *uptag;
598 			int err;
599 
600 			uptag = pc->tag_parent;
601 
602 			/*
603 			 * We have to unload the previous loaded DMA
604 			 * pages before trying to load a new one!
605 			 */
606 			bus_dmamap_unload(pc->tag, pc->map);
607 
608 			/*
609 			 * Try to load memory into DMA.
610 			 */
611 			err = bus_dmamap_load(
612 			    pc->tag, pc->map, pc->buffer, size,
613 			    &usb2_pc_alloc_mem_cb, pc, BUS_DMA_WAITOK);
614 			if (err == EINPROGRESS) {
615 				usb2_cv_wait(uptag->cv, uptag->mtx);
616 				err = 0;
617 			}
618 			if (err || uptag->dma_error) {
619 				return (1);
620 			}
621 		} else {
622 
623 			/*
624 			 * We have to unload the previous loaded DMA
625 			 * pages before trying to load a new one!
626 			 */
627 			bus_dmamap_unload(pc->tag, pc->map);
628 
629 			/*
630 			 * Try to load memory into DMA. The callback
631 			 * will be called in all cases:
632 			 */
633 			if (bus_dmamap_load(
634 			    pc->tag, pc->map, pc->buffer, size,
635 			    &usb2_pc_load_mem_cb, pc, BUS_DMA_WAITOK)) {
636 			}
637 		}
638 	} else {
639 		if (!sync) {
640 			/*
641 			 * Call callback so that refcount is decremented
642 			 * properly:
643 			 */
644 			pc->tag_parent->dma_error = 0;
645 			(pc->tag_parent->func) (pc->tag_parent);
646 		}
647 	}
648 	return (0);
649 }
650 
651 /*------------------------------------------------------------------------*
652  *	usb2_pc_cpu_invalidate - invalidate CPU cache
653  *------------------------------------------------------------------------*/
654 void
655 usb2_pc_cpu_invalidate(struct usb_page_cache *pc)
656 {
657 	if (pc->page_offset_end == pc->page_offset_buf) {
658 		/* nothing has been loaded into this page cache! */
659 		return;
660 	}
661 	bus_dmamap_sync(pc->tag, pc->map,
662 	    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
663 }
664 
665 /*------------------------------------------------------------------------*
666  *	usb2_pc_cpu_flush - flush CPU cache
667  *------------------------------------------------------------------------*/
668 void
669 usb2_pc_cpu_flush(struct usb_page_cache *pc)
670 {
671 	if (pc->page_offset_end == pc->page_offset_buf) {
672 		/* nothing has been loaded into this page cache! */
673 		return;
674 	}
675 	bus_dmamap_sync(pc->tag, pc->map,
676 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
677 }
678 
679 /*------------------------------------------------------------------------*
680  *	usb2_pc_dmamap_create - create a DMA map
681  *
682  * Returns:
683  *    0: Success
684  * Else: Failure
685  *------------------------------------------------------------------------*/
686 uint8_t
687 usb2_pc_dmamap_create(struct usb_page_cache *pc, usb_size_t size)
688 {
689 	struct usb_xfer_root *info;
690 	struct usb_dma_tag *utag;
691 
692 	/* get info */
693 	info = USB_DMATAG_TO_XROOT(pc->tag_parent);
694 
695 	/* sanity check */
696 	if (info == NULL) {
697 		goto error;
698 	}
699 	utag = usb2_dma_tag_find(pc->tag_parent, size, 1);
700 	if (utag == NULL) {
701 		goto error;
702 	}
703 	/* create DMA map */
704 	if (bus_dmamap_create(utag->tag, 0, &pc->map)) {
705 		goto error;
706 	}
707 	pc->tag = utag->tag;
708 	return 0;			/* success */
709 
710 error:
711 	pc->map = NULL;
712 	pc->tag = NULL;
713 	return 1;			/* failure */
714 }
715 
716 /*------------------------------------------------------------------------*
717  *	usb2_pc_dmamap_destroy
718  *
719  * This function is NULL safe.
720  *------------------------------------------------------------------------*/
721 void
722 usb2_pc_dmamap_destroy(struct usb_page_cache *pc)
723 {
724 	if (pc && pc->tag) {
725 		bus_dmamap_destroy(pc->tag, pc->map);
726 		pc->tag = NULL;
727 		pc->map = NULL;
728 	}
729 }
730 
731 /*------------------------------------------------------------------------*
732  *	usb2_dma_tag_find - factored out code
733  *------------------------------------------------------------------------*/
734 struct usb_dma_tag *
735 usb2_dma_tag_find(struct usb_dma_parent_tag *udpt,
736     usb_size_t size, usb_size_t align)
737 {
738 	struct usb_dma_tag *udt;
739 	uint8_t nudt;
740 
741 	USB_ASSERT(align > 0, ("Invalid parameter align = 0!\n"));
742 	USB_ASSERT(size > 0, ("Invalid parameter size = 0!\n"));
743 
744 	udt = udpt->utag_first;
745 	nudt = udpt->utag_max;
746 
747 	while (nudt--) {
748 
749 		if (udt->align == 0) {
750 			usb2_dma_tag_create(udt, size, align);
751 			if (udt->tag == NULL) {
752 				return (NULL);
753 			}
754 			udt->align = align;
755 			udt->size = size;
756 			return (udt);
757 		}
758 		if ((udt->align == align) && (udt->size == size)) {
759 			return (udt);
760 		}
761 		udt++;
762 	}
763 	return (NULL);
764 }
765 
766 /*------------------------------------------------------------------------*
767  *	usb2_dma_tag_setup - initialise USB DMA tags
768  *------------------------------------------------------------------------*/
769 void
770 usb2_dma_tag_setup(struct usb_dma_parent_tag *udpt,
771     struct usb_dma_tag *udt, bus_dma_tag_t dmat,
772     struct mtx *mtx, usb_dma_callback_t *func,
773     uint8_t ndmabits, uint8_t nudt)
774 {
775 	bzero(udpt, sizeof(*udpt));
776 
777 	/* sanity checking */
778 	if ((nudt == 0) ||
779 	    (ndmabits == 0) ||
780 	    (mtx == NULL)) {
781 		/* something is corrupt */
782 		return;
783 	}
784 	/* initialise condition variable */
785 	usb2_cv_init(udpt->cv, "USB DMA CV");
786 
787 	/* store some information */
788 	udpt->mtx = mtx;
789 	udpt->func = func;
790 	udpt->tag = dmat;
791 	udpt->utag_first = udt;
792 	udpt->utag_max = nudt;
793 	udpt->dma_bits = ndmabits;
794 
795 	while (nudt--) {
796 		bzero(udt, sizeof(*udt));
797 		udt->tag_parent = udpt;
798 		udt++;
799 	}
800 }
801 
802 /*------------------------------------------------------------------------*
803  *	usb2_bus_tag_unsetup - factored out code
804  *------------------------------------------------------------------------*/
805 void
806 usb2_dma_tag_unsetup(struct usb_dma_parent_tag *udpt)
807 {
808 	struct usb_dma_tag *udt;
809 	uint8_t nudt;
810 
811 	udt = udpt->utag_first;
812 	nudt = udpt->utag_max;
813 
814 	while (nudt--) {
815 
816 		if (udt->align) {
817 			/* destroy the USB DMA tag */
818 			usb2_dma_tag_destroy(udt);
819 			udt->align = 0;
820 		}
821 		udt++;
822 	}
823 
824 	if (udpt->utag_max) {
825 		/* destroy the condition variable */
826 		usb2_cv_destroy(udpt->cv);
827 	}
828 }
829 
830 /*------------------------------------------------------------------------*
831  *	usb2_bdma_work_loop
832  *
833  * This function handles loading of virtual buffers into DMA and is
834  * only called when "dma_refcount" is zero.
835  *------------------------------------------------------------------------*/
836 void
837 usb2_bdma_work_loop(struct usb_xfer_queue *pq)
838 {
839 	struct usb_xfer_root *info;
840 	struct usb_xfer *xfer;
841 	usb_frcount_t nframes;
842 
843 	xfer = pq->curr;
844 	info = xfer->xroot;
845 
846 	mtx_assert(info->xfer_mtx, MA_OWNED);
847 
848 	if (xfer->error) {
849 		/* some error happened */
850 		USB_BUS_LOCK(info->bus);
851 		usb2_transfer_done(xfer, 0);
852 		USB_BUS_UNLOCK(info->bus);
853 		return;
854 	}
855 	if (!xfer->flags_int.bdma_setup) {
856 		struct usb_page *pg;
857 		usb_frlength_t frlength_0;
858 		uint8_t isread;
859 
860 		xfer->flags_int.bdma_setup = 1;
861 
862 		/* reset BUS-DMA load state */
863 
864 		info->dma_error = 0;
865 
866 		if (xfer->flags_int.isochronous_xfr) {
867 			/* only one frame buffer */
868 			nframes = 1;
869 			frlength_0 = xfer->sumlen;
870 		} else {
871 			/* can be multiple frame buffers */
872 			nframes = xfer->nframes;
873 			frlength_0 = xfer->frlengths[0];
874 		}
875 
876 		/*
877 		 * Set DMA direction first. This is needed to
878 		 * select the correct cache invalidate and cache
879 		 * flush operations.
880 		 */
881 		isread = USB_GET_DATA_ISREAD(xfer);
882 		pg = xfer->dma_page_ptr;
883 
884 		if (xfer->flags_int.control_xfr &&
885 		    xfer->flags_int.control_hdr) {
886 			/* special case */
887 			if (xfer->flags_int.usb_mode == USB_MODE_DEVICE) {
888 				/* The device controller writes to memory */
889 				xfer->frbuffers[0].isread = 1;
890 			} else {
891 				/* The host controller reads from memory */
892 				xfer->frbuffers[0].isread = 0;
893 			}
894 		} else {
895 			/* default case */
896 			xfer->frbuffers[0].isread = isread;
897 		}
898 
899 		/*
900 		 * Setup the "page_start" pointer which points to an array of
901 		 * USB pages where information about the physical address of a
902 		 * page will be stored. Also initialise the "isread" field of
903 		 * the USB page caches.
904 		 */
905 		xfer->frbuffers[0].page_start = pg;
906 
907 		info->dma_nframes = nframes;
908 		info->dma_currframe = 0;
909 		info->dma_frlength_0 = frlength_0;
910 
911 		pg += (frlength_0 / USB_PAGE_SIZE);
912 		pg += 2;
913 
914 		while (--nframes > 0) {
915 			xfer->frbuffers[nframes].isread = isread;
916 			xfer->frbuffers[nframes].page_start = pg;
917 
918 			pg += (xfer->frlengths[nframes] / USB_PAGE_SIZE);
919 			pg += 2;
920 		}
921 
922 	}
923 	if (info->dma_error) {
924 		USB_BUS_LOCK(info->bus);
925 		usb2_transfer_done(xfer, USB_ERR_DMA_LOAD_FAILED);
926 		USB_BUS_UNLOCK(info->bus);
927 		return;
928 	}
929 	if (info->dma_currframe != info->dma_nframes) {
930 
931 		if (info->dma_currframe == 0) {
932 			/* special case */
933 			usb2_pc_load_mem(xfer->frbuffers,
934 			    info->dma_frlength_0, 0);
935 		} else {
936 			/* default case */
937 			nframes = info->dma_currframe;
938 			usb2_pc_load_mem(xfer->frbuffers + nframes,
939 			    xfer->frlengths[nframes], 0);
940 		}
941 
942 		/* advance frame index */
943 		info->dma_currframe++;
944 
945 		return;
946 	}
947 	/* go ahead */
948 	usb2_bdma_pre_sync(xfer);
949 
950 	/* start loading next USB transfer, if any */
951 	usb2_command_wrapper(pq, NULL);
952 
953 	/* finally start the hardware */
954 	usb2_pipe_enter(xfer);
955 }
956 
957 /*------------------------------------------------------------------------*
958  *	usb2_bdma_done_event
959  *
960  * This function is called when the BUS-DMA has loaded virtual memory
961  * into DMA, if any.
962  *------------------------------------------------------------------------*/
963 void
964 usb2_bdma_done_event(struct usb_dma_parent_tag *udpt)
965 {
966 	struct usb_xfer_root *info;
967 
968 	info = USB_DMATAG_TO_XROOT(udpt);
969 
970 	mtx_assert(info->xfer_mtx, MA_OWNED);
971 
972 	/* copy error */
973 	info->dma_error = udpt->dma_error;
974 
975 	/* enter workloop again */
976 	usb2_command_wrapper(&info->dma_q,
977 	    info->dma_q.curr);
978 }
979 
980 /*------------------------------------------------------------------------*
981  *	usb2_bdma_pre_sync
982  *
983  * This function handles DMA synchronisation that must be done before
984  * an USB transfer is started.
985  *------------------------------------------------------------------------*/
986 void
987 usb2_bdma_pre_sync(struct usb_xfer *xfer)
988 {
989 	struct usb_page_cache *pc;
990 	usb_frcount_t nframes;
991 
992 	if (xfer->flags_int.isochronous_xfr) {
993 		/* only one frame buffer */
994 		nframes = 1;
995 	} else {
996 		/* can be multiple frame buffers */
997 		nframes = xfer->nframes;
998 	}
999 
1000 	pc = xfer->frbuffers;
1001 
1002 	while (nframes--) {
1003 
1004 		if (pc->isread) {
1005 			usb2_pc_cpu_invalidate(pc);
1006 		} else {
1007 			usb2_pc_cpu_flush(pc);
1008 		}
1009 		pc++;
1010 	}
1011 }
1012 
1013 /*------------------------------------------------------------------------*
1014  *	usb2_bdma_post_sync
1015  *
1016  * This function handles DMA synchronisation that must be done after
1017  * an USB transfer is complete.
1018  *------------------------------------------------------------------------*/
1019 void
1020 usb2_bdma_post_sync(struct usb_xfer *xfer)
1021 {
1022 	struct usb_page_cache *pc;
1023 	usb_frcount_t nframes;
1024 
1025 	if (xfer->flags_int.isochronous_xfr) {
1026 		/* only one frame buffer */
1027 		nframes = 1;
1028 	} else {
1029 		/* can be multiple frame buffers */
1030 		nframes = xfer->nframes;
1031 	}
1032 
1033 	pc = xfer->frbuffers;
1034 
1035 	while (nframes--) {
1036 		if (pc->isread) {
1037 			usb2_pc_cpu_invalidate(pc);
1038 		}
1039 		pc++;
1040 	}
1041 }
1042 
1043 #endif
1044