usb_transfer.c revision 191494
1184610Salfred/* $FreeBSD: head/sys/dev/usb/usb_transfer.c 191494 2009-04-25 21:10:06Z thompsa $ */
2184610Salfred/*-
3184610Salfred * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
4184610Salfred *
5184610Salfred * Redistribution and use in source and binary forms, with or without
6184610Salfred * modification, are permitted provided that the following conditions
7184610Salfred * are met:
8184610Salfred * 1. Redistributions of source code must retain the above copyright
9184610Salfred *    notice, this list of conditions and the following disclaimer.
10184610Salfred * 2. Redistributions in binary form must reproduce the above copyright
11184610Salfred *    notice, this list of conditions and the following disclaimer in the
12184610Salfred *    documentation and/or other materials provided with the distribution.
13184610Salfred *
14184610Salfred * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15184610Salfred * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16184610Salfred * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17184610Salfred * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18184610Salfred * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19184610Salfred * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20184610Salfred * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21184610Salfred * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22184610Salfred * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23184610Salfred * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24184610Salfred * SUCH DAMAGE.
25190754Sthompsa */
26184610Salfred
27188942Sthompsa#include <dev/usb/usb_mfunc.h>
28188942Sthompsa#include <dev/usb/usb_error.h>
29188942Sthompsa#include <dev/usb/usb.h>
30184610Salfred
31184610Salfred#define	USB_DEBUG_VAR usb2_debug
32184610Salfred
33188942Sthompsa#include <dev/usb/usb_core.h>
34188942Sthompsa#include <dev/usb/usb_busdma.h>
35188942Sthompsa#include <dev/usb/usb_process.h>
36188942Sthompsa#include <dev/usb/usb_transfer.h>
37188942Sthompsa#include <dev/usb/usb_device.h>
38188942Sthompsa#include <dev/usb/usb_debug.h>
39188942Sthompsa#include <dev/usb/usb_util.h>
40184610Salfred
41188942Sthompsa#include <dev/usb/usb_controller.h>
42188942Sthompsa#include <dev/usb/usb_bus.h>
43184610Salfred
44184610Salfredstruct usb2_std_packet_size {
45184610Salfred	struct {
46184610Salfred		uint16_t min;		/* inclusive */
47184610Salfred		uint16_t max;		/* inclusive */
48184610Salfred	}	range;
49184610Salfred
50184610Salfred	uint16_t fixed[4];
51184610Salfred};
52184610Salfred
53190734Sthompsastatic usb2_callback_t usb2_request_callback;
54184610Salfred
55184610Salfredstatic const struct usb2_config usb2_control_ep_cfg[USB_DEFAULT_XFER_MAX] = {
56184610Salfred
57184610Salfred	/* This transfer is used for generic control endpoint transfers */
58184610Salfred
59184610Salfred	[0] = {
60184610Salfred		.type = UE_CONTROL,
61184610Salfred		.endpoint = 0x00,	/* Control endpoint */
62184610Salfred		.direction = UE_DIR_ANY,
63190734Sthompsa		.bufsize = USB_EP0_BUFSIZE,	/* bytes */
64190734Sthompsa		.flags = {.proxy_buffer = 1,},
65190734Sthompsa		.callback = &usb2_request_callback,
66190734Sthompsa		.usb_mode = USB_MODE_MAX,	/* both modes */
67184610Salfred	},
68184610Salfred
69184610Salfred	/* This transfer is used for generic clear stall only */
70184610Salfred
71184610Salfred	[1] = {
72184610Salfred		.type = UE_CONTROL,
73184610Salfred		.endpoint = 0x00,	/* Control pipe */
74184610Salfred		.direction = UE_DIR_ANY,
75190734Sthompsa		.bufsize = sizeof(struct usb2_device_request),
76190734Sthompsa		.callback = &usb2_do_clear_stall_callback,
77190734Sthompsa		.timeout = 1000,	/* 1 second */
78190734Sthompsa		.interval = 50,	/* 50ms */
79190734Sthompsa		.usb_mode = USB_MODE_HOST,
80184610Salfred	},
81184610Salfred};
82184610Salfred
83184610Salfred/* function prototypes */
84184610Salfred
85185948Sthompsastatic void	usb2_update_max_frame_size(struct usb2_xfer *);
86185948Sthompsastatic void	usb2_transfer_unsetup_sub(struct usb2_xfer_root *, uint8_t);
87185948Sthompsastatic void	usb2_control_transfer_init(struct usb2_xfer *);
88185948Sthompsastatic uint8_t	usb2_start_hardware_sub(struct usb2_xfer *);
89185948Sthompsastatic void	usb2_callback_proc(struct usb2_proc_msg *);
90185948Sthompsastatic void	usb2_callback_ss_done_defer(struct usb2_xfer *);
91185948Sthompsastatic void	usb2_callback_wrapper(struct usb2_xfer_queue *);
92185948Sthompsastatic void	usb2_dma_delay_done_cb(void *);
93185948Sthompsastatic void	usb2_transfer_start_cb(void *);
94185948Sthompsastatic uint8_t	usb2_callback_wrapper_sub(struct usb2_xfer *);
95190734Sthompsastatic void	usb2_get_std_packet_size(struct usb2_std_packet_size *ptr,
96190734Sthompsa		    uint8_t type, uint8_t usb_speed);
97184610Salfred
98184610Salfred/*------------------------------------------------------------------------*
99190734Sthompsa *	usb2_request_callback
100190734Sthompsa *------------------------------------------------------------------------*/
101190734Sthompsastatic void
102190734Sthompsausb2_request_callback(struct usb2_xfer *xfer)
103190734Sthompsa{
104190734Sthompsa	if (xfer->flags_int.usb2_mode == USB_MODE_DEVICE)
105190734Sthompsa		usb2_handle_request_callback(xfer);
106190734Sthompsa	else
107190734Sthompsa		usb2_do_request_callback(xfer);
108190734Sthompsa}
109190734Sthompsa
110190734Sthompsa/*------------------------------------------------------------------------*
111184610Salfred *	usb2_update_max_frame_size
112184610Salfred *
113184610Salfred * This function updates the maximum frame size, hence high speed USB
114184610Salfred * can transfer multiple consecutive packets.
115184610Salfred *------------------------------------------------------------------------*/
116184610Salfredstatic void
117184610Salfredusb2_update_max_frame_size(struct usb2_xfer *xfer)
118184610Salfred{
119184610Salfred	/* compute maximum frame size */
120184610Salfred
121184610Salfred	if (xfer->max_packet_count == 2) {
122184610Salfred		xfer->max_frame_size = 2 * xfer->max_packet_size;
123184610Salfred	} else if (xfer->max_packet_count == 3) {
124184610Salfred		xfer->max_frame_size = 3 * xfer->max_packet_size;
125184610Salfred	} else {
126184610Salfred		xfer->max_frame_size = xfer->max_packet_size;
127184610Salfred	}
128184610Salfred}
129184610Salfred
130184610Salfred/*------------------------------------------------------------------------*
131184610Salfred *	usb2_get_dma_delay
132184610Salfred *
133184610Salfred * The following function is called when we need to
134184610Salfred * synchronize with DMA hardware.
135184610Salfred *
136184610Salfred * Returns:
137184610Salfred *    0: no DMA delay required
138184610Salfred * Else: milliseconds of DMA delay
139184610Salfred *------------------------------------------------------------------------*/
140190181Sthompsausb2_timeout_t
141184610Salfredusb2_get_dma_delay(struct usb2_bus *bus)
142184610Salfred{
143184610Salfred	uint32_t temp = 0;
144184610Salfred
145184610Salfred	if (bus->methods->get_dma_delay) {
146184610Salfred		(bus->methods->get_dma_delay) (bus, &temp);
147184610Salfred		/*
148184610Salfred		 * Round up and convert to milliseconds. Note that we use
149184610Salfred		 * 1024 milliseconds per second. to save a division.
150184610Salfred		 */
151184610Salfred		temp += 0x3FF;
152184610Salfred		temp /= 0x400;
153184610Salfred	}
154184610Salfred	return (temp);
155184610Salfred}
156184610Salfred
157184610Salfred/*------------------------------------------------------------------------*
158184610Salfred *	usb2_transfer_setup_sub_malloc
159184610Salfred *
160184610Salfred * This function will allocate one or more DMA'able memory chunks
161184610Salfred * according to "size", "align" and "count" arguments. "ppc" is
162184610Salfred * pointed to a linear array of USB page caches afterwards.
163184610Salfred *
164184610Salfred * Returns:
165184610Salfred *    0: Success
166184610Salfred * Else: Failure
167184610Salfred *------------------------------------------------------------------------*/
168190180Sthompsa#if USB_HAVE_BUSDMA
169184610Salfreduint8_t
170184610Salfredusb2_transfer_setup_sub_malloc(struct usb2_setup_params *parm,
171190181Sthompsa    struct usb2_page_cache **ppc, usb2_size_t size, usb2_size_t align,
172190181Sthompsa    usb2_size_t count)
173184610Salfred{
174184610Salfred	struct usb2_page_cache *pc;
175184610Salfred	struct usb2_page *pg;
176184610Salfred	void *buf;
177190181Sthompsa	usb2_size_t n_dma_pc;
178190181Sthompsa	usb2_size_t n_obj;
179190181Sthompsa	usb2_size_t x;
180190181Sthompsa	usb2_size_t y;
181190181Sthompsa	usb2_size_t r;
182190181Sthompsa	usb2_size_t z;
183184610Salfred
184184610Salfred	USB_ASSERT(align > 1, ("Invalid alignment, 0x%08x!\n",
185184610Salfred	    align));
186184610Salfred	USB_ASSERT(size > 0, ("Invalid size = 0!\n"));
187184610Salfred
188184610Salfred	if (count == 0) {
189184610Salfred		return (0);		/* nothing to allocate */
190184610Salfred	}
191184610Salfred	/*
192184610Salfred	 * Make sure that the size is aligned properly.
193184610Salfred	 */
194184610Salfred	size = -((-size) & (-align));
195184610Salfred
196184610Salfred	/*
197184610Salfred	 * Try multi-allocation chunks to reduce the number of DMA
198184610Salfred	 * allocations, hence DMA allocations are slow.
199184610Salfred	 */
200184610Salfred	if (size >= PAGE_SIZE) {
201184610Salfred		n_dma_pc = count;
202184610Salfred		n_obj = 1;
203184610Salfred	} else {
204184610Salfred		/* compute number of objects per page */
205184610Salfred		n_obj = (PAGE_SIZE / size);
206184610Salfred		/*
207184610Salfred		 * Compute number of DMA chunks, rounded up
208184610Salfred		 * to nearest one:
209184610Salfred		 */
210184610Salfred		n_dma_pc = ((count + n_obj - 1) / n_obj);
211184610Salfred	}
212184610Salfred
213184610Salfred	if (parm->buf == NULL) {
214184610Salfred		/* for the future */
215184610Salfred		parm->dma_page_ptr += n_dma_pc;
216184610Salfred		parm->dma_page_cache_ptr += n_dma_pc;
217184610Salfred		parm->dma_page_ptr += count;
218184610Salfred		parm->xfer_page_cache_ptr += count;
219184610Salfred		return (0);
220184610Salfred	}
221184610Salfred	for (x = 0; x != n_dma_pc; x++) {
222184610Salfred		/* need to initialize the page cache */
223184610Salfred		parm->dma_page_cache_ptr[x].tag_parent =
224187173Sthompsa		    &parm->curr_xfer->xroot->dma_parent_tag;
225184610Salfred	}
226184610Salfred	for (x = 0; x != count; x++) {
227184610Salfred		/* need to initialize the page cache */
228184610Salfred		parm->xfer_page_cache_ptr[x].tag_parent =
229187173Sthompsa		    &parm->curr_xfer->xroot->dma_parent_tag;
230184610Salfred	}
231184610Salfred
232184610Salfred	if (ppc) {
233184610Salfred		*ppc = parm->xfer_page_cache_ptr;
234184610Salfred	}
235184610Salfred	r = count;			/* set remainder count */
236184610Salfred	z = n_obj * size;		/* set allocation size */
237184610Salfred	pc = parm->xfer_page_cache_ptr;
238184610Salfred	pg = parm->dma_page_ptr;
239184610Salfred
240184610Salfred	for (x = 0; x != n_dma_pc; x++) {
241184610Salfred
242184610Salfred		if (r < n_obj) {
243184610Salfred			/* compute last remainder */
244184610Salfred			z = r * size;
245184610Salfred			n_obj = r;
246184610Salfred		}
247184610Salfred		if (usb2_pc_alloc_mem(parm->dma_page_cache_ptr,
248184610Salfred		    pg, z, align)) {
249184610Salfred			return (1);	/* failure */
250184610Salfred		}
251184610Salfred		/* Set beginning of current buffer */
252184610Salfred		buf = parm->dma_page_cache_ptr->buffer;
253184610Salfred		/* Make room for one DMA page cache and one page */
254184610Salfred		parm->dma_page_cache_ptr++;
255184610Salfred		pg++;
256184610Salfred
257184610Salfred		for (y = 0; (y != n_obj); y++, r--, pc++, pg++) {
258184610Salfred
259184610Salfred			/* Load sub-chunk into DMA */
260184610Salfred			if (usb2_pc_dmamap_create(pc, size)) {
261184610Salfred				return (1);	/* failure */
262184610Salfred			}
263184610Salfred			pc->buffer = USB_ADD_BYTES(buf, y * size);
264184610Salfred			pc->page_start = pg;
265184610Salfred
266184610Salfred			mtx_lock(pc->tag_parent->mtx);
267184610Salfred			if (usb2_pc_load_mem(pc, size, 1 /* synchronous */ )) {
268184610Salfred				mtx_unlock(pc->tag_parent->mtx);
269184610Salfred				return (1);	/* failure */
270184610Salfred			}
271184610Salfred			mtx_unlock(pc->tag_parent->mtx);
272184610Salfred		}
273184610Salfred	}
274184610Salfred
275184610Salfred	parm->xfer_page_cache_ptr = pc;
276184610Salfred	parm->dma_page_ptr = pg;
277184610Salfred	return (0);
278184610Salfred}
279190180Sthompsa#endif
280184610Salfred
281184610Salfred/*------------------------------------------------------------------------*
282184610Salfred *	usb2_transfer_setup_sub - transfer setup subroutine
283184610Salfred *
284184610Salfred * This function must be called from the "xfer_setup" callback of the
285184610Salfred * USB Host or Device controller driver when setting up an USB
286184610Salfred * transfer. This function will setup correct packet sizes, buffer
287184610Salfred * sizes, flags and more, that are stored in the "usb2_xfer"
288184610Salfred * structure.
289184610Salfred *------------------------------------------------------------------------*/
290184610Salfredvoid
291184610Salfredusb2_transfer_setup_sub(struct usb2_setup_params *parm)
292184610Salfred{
293184610Salfred	enum {
294184610Salfred		REQ_SIZE = 8,
295184610Salfred		MIN_PKT = 8,
296184610Salfred	};
297184610Salfred	struct usb2_xfer *xfer = parm->curr_xfer;
298190734Sthompsa	const struct usb2_config *setup = parm->curr_setup;
299184610Salfred	struct usb2_endpoint_descriptor *edesc;
300184610Salfred	struct usb2_std_packet_size std_size;
301190181Sthompsa	usb2_frcount_t n_frlengths;
302190181Sthompsa	usb2_frcount_t n_frbuffers;
303190181Sthompsa	usb2_frcount_t x;
304184610Salfred	uint8_t type;
305184610Salfred	uint8_t zmps;
306184610Salfred
307184610Salfred	/*
308184610Salfred	 * Sanity check. The following parameters must be initialized before
309184610Salfred	 * calling this function.
310184610Salfred	 */
311184610Salfred	if ((parm->hc_max_packet_size == 0) ||
312184610Salfred	    (parm->hc_max_packet_count == 0) ||
313184610Salfred	    (parm->hc_max_frame_size == 0)) {
314184610Salfred		parm->err = USB_ERR_INVAL;
315184610Salfred		goto done;
316184610Salfred	}
317184610Salfred	edesc = xfer->pipe->edesc;
318184610Salfred
319184610Salfred	type = (edesc->bmAttributes & UE_XFERTYPE);
320184610Salfred
321190734Sthompsa	xfer->flags = setup->flags;
322190734Sthompsa	xfer->nframes = setup->frames;
323190734Sthompsa	xfer->timeout = setup->timeout;
324190734Sthompsa	xfer->callback = setup->callback;
325190734Sthompsa	xfer->interval = setup->interval;
326184610Salfred	xfer->endpoint = edesc->bEndpointAddress;
327184610Salfred	xfer->max_packet_size = UGETW(edesc->wMaxPacketSize);
328184610Salfred	xfer->max_packet_count = 1;
329184610Salfred	/* make a shadow copy: */
330184610Salfred	xfer->flags_int.usb2_mode = parm->udev->flags.usb2_mode;
331184610Salfred
332190734Sthompsa	parm->bufsize = setup->bufsize;
333184610Salfred
334184610Salfred	if (parm->speed == USB_SPEED_HIGH) {
335184610Salfred		xfer->max_packet_count += (xfer->max_packet_size >> 11) & 3;
336184610Salfred		xfer->max_packet_size &= 0x7FF;
337184610Salfred	}
338184610Salfred	/* range check "max_packet_count" */
339184610Salfred
340184610Salfred	if (xfer->max_packet_count > parm->hc_max_packet_count) {
341184610Salfred		xfer->max_packet_count = parm->hc_max_packet_count;
342184610Salfred	}
343184610Salfred	/* filter "wMaxPacketSize" according to HC capabilities */
344184610Salfred
345184610Salfred	if ((xfer->max_packet_size > parm->hc_max_packet_size) ||
346184610Salfred	    (xfer->max_packet_size == 0)) {
347184610Salfred		xfer->max_packet_size = parm->hc_max_packet_size;
348184610Salfred	}
349184610Salfred	/* filter "wMaxPacketSize" according to standard sizes */
350184610Salfred
351190734Sthompsa	usb2_get_std_packet_size(&std_size, type, parm->speed);
352184610Salfred
353184610Salfred	if (std_size.range.min || std_size.range.max) {
354184610Salfred
355184610Salfred		if (xfer->max_packet_size < std_size.range.min) {
356184610Salfred			xfer->max_packet_size = std_size.range.min;
357184610Salfred		}
358184610Salfred		if (xfer->max_packet_size > std_size.range.max) {
359184610Salfred			xfer->max_packet_size = std_size.range.max;
360184610Salfred		}
361184610Salfred	} else {
362184610Salfred
363184610Salfred		if (xfer->max_packet_size >= std_size.fixed[3]) {
364184610Salfred			xfer->max_packet_size = std_size.fixed[3];
365184610Salfred		} else if (xfer->max_packet_size >= std_size.fixed[2]) {
366184610Salfred			xfer->max_packet_size = std_size.fixed[2];
367184610Salfred		} else if (xfer->max_packet_size >= std_size.fixed[1]) {
368184610Salfred			xfer->max_packet_size = std_size.fixed[1];
369184610Salfred		} else {
370184610Salfred			/* only one possibility left */
371184610Salfred			xfer->max_packet_size = std_size.fixed[0];
372184610Salfred		}
373184610Salfred	}
374184610Salfred
375184610Salfred	/* compute "max_frame_size" */
376184610Salfred
377184610Salfred	usb2_update_max_frame_size(xfer);
378184610Salfred
379184610Salfred	/* check interrupt interval and transfer pre-delay */
380184610Salfred
381184610Salfred	if (type == UE_ISOCHRONOUS) {
382184610Salfred
383190181Sthompsa		uint16_t frame_limit;
384184610Salfred
385184610Salfred		xfer->interval = 0;	/* not used, must be zero */
386184610Salfred		xfer->flags_int.isochronous_xfr = 1;	/* set flag */
387184610Salfred
388184610Salfred		if (xfer->timeout == 0) {
389184610Salfred			/*
390184610Salfred			 * set a default timeout in
391184610Salfred			 * case something goes wrong!
392184610Salfred			 */
393184610Salfred			xfer->timeout = 1000 / 4;
394184610Salfred		}
395187180Sthompsa		switch (parm->speed) {
396187180Sthompsa		case USB_SPEED_LOW:
397187180Sthompsa		case USB_SPEED_FULL:
398187180Sthompsa			frame_limit = USB_MAX_FS_ISOC_FRAMES_PER_XFER;
399187180Sthompsa			break;
400187180Sthompsa		default:
401184610Salfred			frame_limit = USB_MAX_HS_ISOC_FRAMES_PER_XFER;
402187180Sthompsa			break;
403184610Salfred		}
404184610Salfred
405184610Salfred		if (xfer->nframes > frame_limit) {
406184610Salfred			/*
407184610Salfred			 * this is not going to work
408184610Salfred			 * cross hardware
409184610Salfred			 */
410184610Salfred			parm->err = USB_ERR_INVAL;
411184610Salfred			goto done;
412184610Salfred		}
413184610Salfred		if (xfer->nframes == 0) {
414184610Salfred			/*
415184610Salfred			 * this is not a valid value
416184610Salfred			 */
417184610Salfred			parm->err = USB_ERR_ZERO_NFRAMES;
418184610Salfred			goto done;
419184610Salfred		}
420184610Salfred	} else {
421184610Salfred
422184610Salfred		/*
423184610Salfred		 * if a value is specified use that else check the endpoint
424184610Salfred		 * descriptor
425184610Salfred		 */
426184610Salfred		if (xfer->interval == 0) {
427184610Salfred
428184610Salfred			if (type == UE_INTERRUPT) {
429184610Salfred
430184610Salfred				xfer->interval = edesc->bInterval;
431184610Salfred
432187180Sthompsa				switch (parm->speed) {
433187180Sthompsa				case USB_SPEED_SUPER:
434187180Sthompsa				case USB_SPEED_VARIABLE:
435187180Sthompsa					/* 125us -> 1ms */
436187180Sthompsa					if (xfer->interval < 4)
437187180Sthompsa						xfer->interval = 1;
438187180Sthompsa					else if (xfer->interval > 16)
439187180Sthompsa						xfer->interval = (1<<(16-4));
440187180Sthompsa					else
441187180Sthompsa						xfer->interval =
442187180Sthompsa						    (1 << (xfer->interval-4));
443187180Sthompsa					break;
444187180Sthompsa				case USB_SPEED_HIGH:
445187180Sthompsa					/* 125us -> 1ms */
446187180Sthompsa					xfer->interval /= 8;
447187180Sthompsa					break;
448187180Sthompsa				default:
449187180Sthompsa					break;
450184610Salfred				}
451184610Salfred				if (xfer->interval == 0) {
452184610Salfred					/*
453187180Sthompsa					 * One millisecond is the smallest
454187180Sthompsa					 * interval we support:
455184610Salfred					 */
456184610Salfred					xfer->interval = 1;
457184610Salfred				}
458184610Salfred			}
459184610Salfred		}
460184610Salfred	}
461184610Salfred
462184610Salfred	/*
463184610Salfred	 * NOTE: we do not allow "max_packet_size" or "max_frame_size"
464184610Salfred	 * to be equal to zero when setting up USB transfers, hence
465184610Salfred	 * this leads to alot of extra code in the USB kernel.
466184610Salfred	 */
467184610Salfred
468184610Salfred	if ((xfer->max_frame_size == 0) ||
469184610Salfred	    (xfer->max_packet_size == 0)) {
470184610Salfred
471184610Salfred		zmps = 1;
472184610Salfred
473184610Salfred		if ((parm->bufsize <= MIN_PKT) &&
474184610Salfred		    (type != UE_CONTROL) &&
475184610Salfred		    (type != UE_BULK)) {
476184610Salfred
477184610Salfred			/* workaround */
478184610Salfred			xfer->max_packet_size = MIN_PKT;
479184610Salfred			xfer->max_packet_count = 1;
480184610Salfred			parm->bufsize = 0;	/* automatic setup length */
481184610Salfred			usb2_update_max_frame_size(xfer);
482184610Salfred
483184610Salfred		} else {
484184610Salfred			parm->err = USB_ERR_ZERO_MAXP;
485184610Salfred			goto done;
486184610Salfred		}
487184610Salfred
488184610Salfred	} else {
489184610Salfred		zmps = 0;
490184610Salfred	}
491184610Salfred
492184610Salfred	/*
493184610Salfred	 * check if we should setup a default
494184610Salfred	 * length:
495184610Salfred	 */
496184610Salfred
497184610Salfred	if (parm->bufsize == 0) {
498184610Salfred
499184610Salfred		parm->bufsize = xfer->max_frame_size;
500184610Salfred
501184610Salfred		if (type == UE_ISOCHRONOUS) {
502184610Salfred			parm->bufsize *= xfer->nframes;
503184610Salfred		}
504184610Salfred	}
505184610Salfred	/*
506184610Salfred	 * check if we are about to setup a proxy
507184610Salfred	 * type of buffer:
508184610Salfred	 */
509184610Salfred
510184610Salfred	if (xfer->flags.proxy_buffer) {
511184610Salfred
512184610Salfred		/* round bufsize up */
513184610Salfred
514184610Salfred		parm->bufsize += (xfer->max_frame_size - 1);
515184610Salfred
516184610Salfred		if (parm->bufsize < xfer->max_frame_size) {
517184610Salfred			/* length wrapped around */
518184610Salfred			parm->err = USB_ERR_INVAL;
519184610Salfred			goto done;
520184610Salfred		}
521184610Salfred		/* subtract remainder */
522184610Salfred
523184610Salfred		parm->bufsize -= (parm->bufsize % xfer->max_frame_size);
524184610Salfred
525184610Salfred		/* add length of USB device request structure, if any */
526184610Salfred
527184610Salfred		if (type == UE_CONTROL) {
528184610Salfred			parm->bufsize += REQ_SIZE;	/* SETUP message */
529184610Salfred		}
530184610Salfred	}
531184610Salfred	xfer->max_data_length = parm->bufsize;
532184610Salfred
533184610Salfred	/* Setup "n_frlengths" and "n_frbuffers" */
534184610Salfred
535184610Salfred	if (type == UE_ISOCHRONOUS) {
536184610Salfred		n_frlengths = xfer->nframes;
537184610Salfred		n_frbuffers = 1;
538184610Salfred	} else {
539184610Salfred
540184610Salfred		if (type == UE_CONTROL) {
541184610Salfred			xfer->flags_int.control_xfr = 1;
542184610Salfred			if (xfer->nframes == 0) {
543184610Salfred				if (parm->bufsize <= REQ_SIZE) {
544184610Salfred					/*
545184610Salfred					 * there will never be any data
546184610Salfred					 * stage
547184610Salfred					 */
548184610Salfred					xfer->nframes = 1;
549184610Salfred				} else {
550184610Salfred					xfer->nframes = 2;
551184610Salfred				}
552184610Salfred			}
553184610Salfred		} else {
554184610Salfred			if (xfer->nframes == 0) {
555184610Salfred				xfer->nframes = 1;
556184610Salfred			}
557184610Salfred		}
558184610Salfred
559184610Salfred		n_frlengths = xfer->nframes;
560184610Salfred		n_frbuffers = xfer->nframes;
561184610Salfred	}
562184610Salfred
563184610Salfred	/*
564184610Salfred	 * check if we have room for the
565184610Salfred	 * USB device request structure:
566184610Salfred	 */
567184610Salfred
568184610Salfred	if (type == UE_CONTROL) {
569184610Salfred
570184610Salfred		if (xfer->max_data_length < REQ_SIZE) {
571184610Salfred			/* length wrapped around or too small bufsize */
572184610Salfred			parm->err = USB_ERR_INVAL;
573184610Salfred			goto done;
574184610Salfred		}
575184610Salfred		xfer->max_data_length -= REQ_SIZE;
576184610Salfred	}
577184610Salfred	/* setup "frlengths" */
578184610Salfred
579184610Salfred	xfer->frlengths = parm->xfer_length_ptr;
580184610Salfred
581184610Salfred	parm->xfer_length_ptr += n_frlengths;
582184610Salfred
583184610Salfred	/* setup "frbuffers" */
584184610Salfred
585184610Salfred	xfer->frbuffers = parm->xfer_page_cache_ptr;
586184610Salfred
587184610Salfred	parm->xfer_page_cache_ptr += n_frbuffers;
588184610Salfred
589184610Salfred	/*
590184610Salfred	 * check if we need to setup
591184610Salfred	 * a local buffer:
592184610Salfred	 */
593184610Salfred
594184610Salfred	if (!xfer->flags.ext_buffer) {
595184610Salfred
596184610Salfred		/* align data */
597184610Salfred		parm->size[0] += ((-parm->size[0]) & (USB_HOST_ALIGN - 1));
598184610Salfred
599184610Salfred		if (parm->buf) {
600184610Salfred
601184610Salfred			xfer->local_buffer =
602184610Salfred			    USB_ADD_BYTES(parm->buf, parm->size[0]);
603184610Salfred
604184610Salfred			usb2_set_frame_offset(xfer, 0, 0);
605184610Salfred
606184610Salfred			if ((type == UE_CONTROL) && (n_frbuffers > 1)) {
607184610Salfred				usb2_set_frame_offset(xfer, REQ_SIZE, 1);
608184610Salfred			}
609184610Salfred		}
610184610Salfred		parm->size[0] += parm->bufsize;
611184610Salfred
612184610Salfred		/* align data again */
613184610Salfred		parm->size[0] += ((-parm->size[0]) & (USB_HOST_ALIGN - 1));
614184610Salfred	}
615184610Salfred	/*
616184610Salfred	 * Compute maximum buffer size
617184610Salfred	 */
618184610Salfred
619184610Salfred	if (parm->bufsize_max < parm->bufsize) {
620184610Salfred		parm->bufsize_max = parm->bufsize;
621184610Salfred	}
622190180Sthompsa#if USB_HAVE_BUSDMA
623184610Salfred	if (xfer->flags_int.bdma_enable) {
624184610Salfred		/*
625184610Salfred		 * Setup "dma_page_ptr".
626184610Salfred		 *
627184610Salfred		 * Proof for formula below:
628184610Salfred		 *
629184610Salfred		 * Assume there are three USB frames having length "a", "b" and
630184610Salfred		 * "c". These USB frames will at maximum need "z"
631184610Salfred		 * "usb2_page" structures. "z" is given by:
632184610Salfred		 *
633184610Salfred		 * z = ((a / USB_PAGE_SIZE) + 2) + ((b / USB_PAGE_SIZE) + 2) +
634184610Salfred		 * ((c / USB_PAGE_SIZE) + 2);
635184610Salfred		 *
636184610Salfred		 * Constraining "a", "b" and "c" like this:
637184610Salfred		 *
638184610Salfred		 * (a + b + c) <= parm->bufsize
639184610Salfred		 *
640184610Salfred		 * We know that:
641184610Salfred		 *
642184610Salfred		 * z <= ((parm->bufsize / USB_PAGE_SIZE) + (3*2));
643184610Salfred		 *
644184610Salfred		 * Here is the general formula:
645184610Salfred		 */
646184610Salfred		xfer->dma_page_ptr = parm->dma_page_ptr;
647184610Salfred		parm->dma_page_ptr += (2 * n_frbuffers);
648184610Salfred		parm->dma_page_ptr += (parm->bufsize / USB_PAGE_SIZE);
649184610Salfred	}
650190180Sthompsa#endif
651184610Salfred	if (zmps) {
652184610Salfred		/* correct maximum data length */
653184610Salfred		xfer->max_data_length = 0;
654184610Salfred	}
655184610Salfred	/* subtract USB frame remainder from "hc_max_frame_size" */
656184610Salfred
657190181Sthompsa	xfer->max_hc_frame_size =
658184610Salfred	    (parm->hc_max_frame_size -
659184610Salfred	    (parm->hc_max_frame_size % xfer->max_frame_size));
660184610Salfred
661190181Sthompsa	if (xfer->max_hc_frame_size == 0) {
662184610Salfred		parm->err = USB_ERR_INVAL;
663184610Salfred		goto done;
664184610Salfred	}
665184610Salfred	/* initialize max frame count */
666184610Salfred
667184610Salfred	xfer->max_frame_count = xfer->nframes;
668184610Salfred
669184610Salfred	/* initialize frame buffers */
670184610Salfred
671184610Salfred	if (parm->buf) {
672184610Salfred		for (x = 0; x != n_frbuffers; x++) {
673184610Salfred			xfer->frbuffers[x].tag_parent =
674187173Sthompsa			    &xfer->xroot->dma_parent_tag;
675190180Sthompsa#if USB_HAVE_BUSDMA
676184610Salfred			if (xfer->flags_int.bdma_enable &&
677184610Salfred			    (parm->bufsize_max > 0)) {
678184610Salfred
679184610Salfred				if (usb2_pc_dmamap_create(
680184610Salfred				    xfer->frbuffers + x,
681184610Salfred				    parm->bufsize_max)) {
682184610Salfred					parm->err = USB_ERR_NOMEM;
683184610Salfred					goto done;
684184610Salfred				}
685184610Salfred			}
686190180Sthompsa#endif
687184610Salfred		}
688184610Salfred	}
689184610Salfreddone:
690184610Salfred	if (parm->err) {
691184610Salfred		/*
692184610Salfred		 * Set some dummy values so that we avoid division by zero:
693184610Salfred		 */
694190181Sthompsa		xfer->max_hc_frame_size = 1;
695184610Salfred		xfer->max_frame_size = 1;
696184610Salfred		xfer->max_packet_size = 1;
697184610Salfred		xfer->max_data_length = 0;
698184610Salfred		xfer->nframes = 0;
699184610Salfred		xfer->max_frame_count = 0;
700184610Salfred	}
701184610Salfred}
702184610Salfred
703184610Salfred/*------------------------------------------------------------------------*
704184610Salfred *	usb2_transfer_setup - setup an array of USB transfers
705184610Salfred *
706184610Salfred * NOTE: You must always call "usb2_transfer_unsetup" after calling
707184610Salfred * "usb2_transfer_setup" if success was returned.
708184610Salfred *
709184610Salfred * The idea is that the USB device driver should pre-allocate all its
710184610Salfred * transfers by one call to this function.
711184610Salfred *
712184610Salfred * Return values:
713184610Salfred *    0: Success
714184610Salfred * Else: Failure
715184610Salfred *------------------------------------------------------------------------*/
716184610Salfredusb2_error_t
717184610Salfredusb2_transfer_setup(struct usb2_device *udev,
718184610Salfred    const uint8_t *ifaces, struct usb2_xfer **ppxfer,
719184610Salfred    const struct usb2_config *setup_start, uint16_t n_setup,
720187173Sthompsa    void *priv_sc, struct mtx *xfer_mtx)
721184610Salfred{
722184610Salfred	struct usb2_xfer dummy;
723184610Salfred	struct usb2_setup_params parm;
724184610Salfred	const struct usb2_config *setup_end = setup_start + n_setup;
725184610Salfred	const struct usb2_config *setup;
726184610Salfred	struct usb2_pipe *pipe;
727184610Salfred	struct usb2_xfer_root *info;
728184610Salfred	struct usb2_xfer *xfer;
729184610Salfred	void *buf = NULL;
730184610Salfred	uint16_t n;
731184610Salfred	uint16_t refcount;
732184610Salfred
733184610Salfred	parm.err = 0;
734184610Salfred	refcount = 0;
735184610Salfred	info = NULL;
736184610Salfred
737184610Salfred	WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
738184610Salfred	    "usb2_transfer_setup can sleep!");
739184610Salfred
740184610Salfred	/* do some checking first */
741184610Salfred
742184610Salfred	if (n_setup == 0) {
743184610Salfred		DPRINTFN(6, "setup array has zero length!\n");
744184610Salfred		return (USB_ERR_INVAL);
745184610Salfred	}
746184610Salfred	if (ifaces == 0) {
747184610Salfred		DPRINTFN(6, "ifaces array is NULL!\n");
748184610Salfred		return (USB_ERR_INVAL);
749184610Salfred	}
750187173Sthompsa	if (xfer_mtx == NULL) {
751184610Salfred		DPRINTFN(6, "using global lock\n");
752187173Sthompsa		xfer_mtx = &Giant;
753184610Salfred	}
754184610Salfred	/* sanity checks */
755184610Salfred	for (setup = setup_start, n = 0;
756184610Salfred	    setup != setup_end; setup++, n++) {
757190734Sthompsa		if (setup->bufsize == (usb2_frlength_t)-1) {
758184610Salfred			parm.err = USB_ERR_BAD_BUFSIZE;
759184610Salfred			DPRINTF("invalid bufsize\n");
760184610Salfred		}
761190734Sthompsa		if (setup->callback == NULL) {
762184610Salfred			parm.err = USB_ERR_NO_CALLBACK;
763184610Salfred			DPRINTF("no callback\n");
764184610Salfred		}
765184610Salfred		ppxfer[n] = NULL;
766184610Salfred	}
767184610Salfred
768184610Salfred	if (parm.err) {
769184610Salfred		goto done;
770184610Salfred	}
771184610Salfred	bzero(&parm, sizeof(parm));
772184610Salfred
773184610Salfred	parm.udev = udev;
774184610Salfred	parm.speed = usb2_get_speed(udev);
775184610Salfred	parm.hc_max_packet_count = 1;
776184610Salfred
777184610Salfred	if (parm.speed >= USB_SPEED_MAX) {
778184610Salfred		parm.err = USB_ERR_INVAL;
779184610Salfred		goto done;
780184610Salfred	}
781184610Salfred	/* setup all transfers */
782184610Salfred
783184610Salfred	while (1) {
784184610Salfred
785184610Salfred		if (buf) {
786184610Salfred			/*
787184610Salfred			 * Initialize the "usb2_xfer_root" structure,
788184610Salfred			 * which is common for all our USB transfers.
789184610Salfred			 */
790184610Salfred			info = USB_ADD_BYTES(buf, 0);
791184610Salfred
792184610Salfred			info->memory_base = buf;
793184610Salfred			info->memory_size = parm.size[0];
794184610Salfred
795190180Sthompsa#if USB_HAVE_BUSDMA
796184610Salfred			info->dma_page_cache_start = USB_ADD_BYTES(buf, parm.size[4]);
797184610Salfred			info->dma_page_cache_end = USB_ADD_BYTES(buf, parm.size[5]);
798190180Sthompsa#endif
799184610Salfred			info->xfer_page_cache_start = USB_ADD_BYTES(buf, parm.size[5]);
800184610Salfred			info->xfer_page_cache_end = USB_ADD_BYTES(buf, parm.size[2]);
801184610Salfred
802184610Salfred			usb2_cv_init(&info->cv_drain, "WDRAIN");
803184610Salfred
804187173Sthompsa			info->xfer_mtx = xfer_mtx;
805190180Sthompsa#if USB_HAVE_BUSDMA
806184610Salfred			usb2_dma_tag_setup(&info->dma_parent_tag,
807184610Salfred			    parm.dma_tag_p, udev->bus->dma_parent_tag[0].tag,
808190180Sthompsa			    xfer_mtx, &usb2_bdma_done_event, 32, parm.dma_tag_max);
809190180Sthompsa#endif
810184610Salfred
811184610Salfred			info->bus = udev->bus;
812187173Sthompsa			info->udev = udev;
813184610Salfred
814184610Salfred			TAILQ_INIT(&info->done_q.head);
815184610Salfred			info->done_q.command = &usb2_callback_wrapper;
816190180Sthompsa#if USB_HAVE_BUSDMA
817184610Salfred			TAILQ_INIT(&info->dma_q.head);
818184610Salfred			info->dma_q.command = &usb2_bdma_work_loop;
819190180Sthompsa#endif
820184610Salfred			info->done_m[0].hdr.pm_callback = &usb2_callback_proc;
821187173Sthompsa			info->done_m[0].xroot = info;
822184610Salfred			info->done_m[1].hdr.pm_callback = &usb2_callback_proc;
823187173Sthompsa			info->done_m[1].xroot = info;
824184610Salfred
825191400Sthompsa			/*
826191400Sthompsa			 * In device side mode control endpoint
827191400Sthompsa			 * requests need to run from a separate
828191400Sthompsa			 * context, else there is a chance of
829191400Sthompsa			 * deadlock!
830191400Sthompsa			 */
831191400Sthompsa			if (setup_start == usb2_control_ep_cfg)
832187174Sthompsa				info->done_p =
833191400Sthompsa				    &udev->bus->control_xfer_proc;
834191400Sthompsa			else if (xfer_mtx == &Giant)
835191400Sthompsa				info->done_p =
836187174Sthompsa				    &udev->bus->giant_callback_proc;
837187174Sthompsa			else
838187174Sthompsa				info->done_p =
839187174Sthompsa				    &udev->bus->non_giant_callback_proc;
840184610Salfred		}
841184610Salfred		/* reset sizes */
842184610Salfred
843184610Salfred		parm.size[0] = 0;
844184610Salfred		parm.buf = buf;
845184610Salfred		parm.size[0] += sizeof(info[0]);
846184610Salfred
847184610Salfred		for (setup = setup_start, n = 0;
848184610Salfred		    setup != setup_end; setup++, n++) {
849184610Salfred
850184610Salfred			/* skip USB transfers without callbacks: */
851190734Sthompsa			if (setup->callback == NULL) {
852184610Salfred				continue;
853184610Salfred			}
854184610Salfred			/* see if there is a matching endpoint */
855184610Salfred			pipe = usb2_get_pipe(udev,
856184610Salfred			    ifaces[setup->if_index], setup);
857184610Salfred
858190735Sthompsa			if ((pipe == NULL) || (pipe->methods == NULL)) {
859190734Sthompsa				if (setup->flags.no_pipe_ok)
860184610Salfred					continue;
861190734Sthompsa				if ((setup->usb_mode != USB_MODE_MAX) &&
862190734Sthompsa				    (setup->usb_mode != udev->flags.usb2_mode))
863190734Sthompsa					continue;
864184610Salfred				parm.err = USB_ERR_NO_PIPE;
865184610Salfred				goto done;
866184610Salfred			}
867184610Salfred
868184610Salfred			/* align data properly */
869184610Salfred			parm.size[0] += ((-parm.size[0]) & (USB_HOST_ALIGN - 1));
870184610Salfred
871190734Sthompsa			/* store current setup pointer */
872190734Sthompsa			parm.curr_setup = setup;
873190734Sthompsa
874184610Salfred			if (buf) {
875184610Salfred				/*
876184610Salfred				 * Common initialization of the
877184610Salfred				 * "usb2_xfer" structure.
878184610Salfred				 */
879184610Salfred				xfer = USB_ADD_BYTES(buf, parm.size[0]);
880184610Salfred				xfer->address = udev->address;
881184610Salfred				xfer->priv_sc = priv_sc;
882187173Sthompsa				xfer->xroot = info;
883184610Salfred
884184824Sthompsa				usb2_callout_init_mtx(&xfer->timeout_handle,
885186454Sthompsa				    &udev->bus->bus_mtx, 0);
886184610Salfred			} else {
887184610Salfred				/*
888184610Salfred				 * Setup a dummy xfer, hence we are
889184610Salfred				 * writing to the "usb2_xfer"
890184610Salfred				 * structure pointed to by "xfer"
891184610Salfred				 * before we have allocated any
892184610Salfred				 * memory:
893184610Salfred				 */
894184610Salfred				xfer = &dummy;
895184610Salfred				bzero(&dummy, sizeof(dummy));
896184610Salfred				refcount++;
897184610Salfred			}
898184610Salfred
899188982Sthompsa			/* set transfer pipe pointer */
900188982Sthompsa			xfer->pipe = pipe;
901188982Sthompsa
902184610Salfred			parm.size[0] += sizeof(xfer[0]);
903188982Sthompsa			parm.methods = xfer->pipe->methods;
904188982Sthompsa			parm.curr_xfer = xfer;
905184610Salfred
906188982Sthompsa			/*
907188982Sthompsa			 * Call the Host or Device controller transfer
908188982Sthompsa			 * setup routine:
909188982Sthompsa			 */
910188982Sthompsa			(udev->bus->methods->xfer_setup) (&parm);
911184610Salfred
912188982Sthompsa			/* check for error */
913188982Sthompsa			if (parm.err)
914188982Sthompsa				goto done;
915188982Sthompsa
916184610Salfred			if (buf) {
917184610Salfred				/*
918184610Salfred				 * Increment the pipe refcount. This
919184610Salfred				 * basically prevents setting a new
920184610Salfred				 * configuration and alternate setting
921184610Salfred				 * when USB transfers are in use on
922184610Salfred				 * the given interface. Search the USB
923184610Salfred				 * code for "pipe->refcount" if you
924184610Salfred				 * want more information.
925184610Salfred				 */
926184610Salfred				xfer->pipe->refcount++;
927184610Salfred
928188982Sthompsa				/*
929188982Sthompsa				 * Whenever we set ppxfer[] then we
930188982Sthompsa				 * also need to increment the
931188982Sthompsa				 * "setup_refcount":
932188982Sthompsa				 */
933188982Sthompsa				info->setup_refcount++;
934184610Salfred
935188982Sthompsa				/*
936188982Sthompsa				 * Transfer is successfully setup and
937188982Sthompsa				 * can be used:
938188982Sthompsa				 */
939188982Sthompsa				ppxfer[n] = xfer;
940184610Salfred			}
941184610Salfred		}
942184610Salfred
943184610Salfred		if (buf || parm.err) {
944184610Salfred			goto done;
945184610Salfred		}
946184610Salfred		if (refcount == 0) {
947184610Salfred			/* no transfers - nothing to do ! */
948184610Salfred			goto done;
949184610Salfred		}
950184610Salfred		/* align data properly */
951184610Salfred		parm.size[0] += ((-parm.size[0]) & (USB_HOST_ALIGN - 1));
952184610Salfred
953184610Salfred		/* store offset temporarily */
954184610Salfred		parm.size[1] = parm.size[0];
955184610Salfred
956184610Salfred		/*
957184610Salfred		 * The number of DMA tags required depends on
958184610Salfred		 * the number of endpoints. The current estimate
959184610Salfred		 * for maximum number of DMA tags per endpoint
960184610Salfred		 * is two.
961184610Salfred		 */
962184610Salfred		parm.dma_tag_max += 2 * MIN(n_setup, USB_EP_MAX);
963184610Salfred
964184610Salfred		/*
965184610Salfred		 * DMA tags for QH, TD, Data and more.
966184610Salfred		 */
967184610Salfred		parm.dma_tag_max += 8;
968184610Salfred
969184610Salfred		parm.dma_tag_p += parm.dma_tag_max;
970184610Salfred
971184610Salfred		parm.size[0] += ((uint8_t *)parm.dma_tag_p) -
972184610Salfred		    ((uint8_t *)0);
973184610Salfred
974184610Salfred		/* align data properly */
975184610Salfred		parm.size[0] += ((-parm.size[0]) & (USB_HOST_ALIGN - 1));
976184610Salfred
977184610Salfred		/* store offset temporarily */
978184610Salfred		parm.size[3] = parm.size[0];
979184610Salfred
980184610Salfred		parm.size[0] += ((uint8_t *)parm.dma_page_ptr) -
981184610Salfred		    ((uint8_t *)0);
982184610Salfred
983184610Salfred		/* align data properly */
984184610Salfred		parm.size[0] += ((-parm.size[0]) & (USB_HOST_ALIGN - 1));
985184610Salfred
986184610Salfred		/* store offset temporarily */
987184610Salfred		parm.size[4] = parm.size[0];
988184610Salfred
989184610Salfred		parm.size[0] += ((uint8_t *)parm.dma_page_cache_ptr) -
990184610Salfred		    ((uint8_t *)0);
991184610Salfred
992184610Salfred		/* store end offset temporarily */
993184610Salfred		parm.size[5] = parm.size[0];
994184610Salfred
995184610Salfred		parm.size[0] += ((uint8_t *)parm.xfer_page_cache_ptr) -
996184610Salfred		    ((uint8_t *)0);
997184610Salfred
998184610Salfred		/* store end offset temporarily */
999184610Salfred
1000184610Salfred		parm.size[2] = parm.size[0];
1001184610Salfred
1002184610Salfred		/* align data properly */
1003184610Salfred		parm.size[0] += ((-parm.size[0]) & (USB_HOST_ALIGN - 1));
1004184610Salfred
1005184610Salfred		parm.size[6] = parm.size[0];
1006184610Salfred
1007184610Salfred		parm.size[0] += ((uint8_t *)parm.xfer_length_ptr) -
1008184610Salfred		    ((uint8_t *)0);
1009184610Salfred
1010184610Salfred		/* align data properly */
1011184610Salfred		parm.size[0] += ((-parm.size[0]) & (USB_HOST_ALIGN - 1));
1012184610Salfred
1013184610Salfred		/* allocate zeroed memory */
1014184610Salfred		buf = malloc(parm.size[0], M_USB, M_WAITOK | M_ZERO);
1015184610Salfred
1016184610Salfred		if (buf == NULL) {
1017184610Salfred			parm.err = USB_ERR_NOMEM;
1018184610Salfred			DPRINTFN(0, "cannot allocate memory block for "
1019184610Salfred			    "configuration (%d bytes)\n",
1020184610Salfred			    parm.size[0]);
1021184610Salfred			goto done;
1022184610Salfred		}
1023184610Salfred		parm.dma_tag_p = USB_ADD_BYTES(buf, parm.size[1]);
1024184610Salfred		parm.dma_page_ptr = USB_ADD_BYTES(buf, parm.size[3]);
1025184610Salfred		parm.dma_page_cache_ptr = USB_ADD_BYTES(buf, parm.size[4]);
1026184610Salfred		parm.xfer_page_cache_ptr = USB_ADD_BYTES(buf, parm.size[5]);
1027184610Salfred		parm.xfer_length_ptr = USB_ADD_BYTES(buf, parm.size[6]);
1028184610Salfred	}
1029184610Salfred
1030184610Salfreddone:
1031184610Salfred	if (buf) {
1032184610Salfred		if (info->setup_refcount == 0) {
1033184610Salfred			/*
1034184610Salfred			 * "usb2_transfer_unsetup_sub" will unlock
1035184824Sthompsa			 * the bus mutex before returning !
1036184610Salfred			 */
1037184824Sthompsa			USB_BUS_LOCK(info->bus);
1038184610Salfred
1039184610Salfred			/* something went wrong */
1040184610Salfred			usb2_transfer_unsetup_sub(info, 0);
1041184610Salfred		}
1042184610Salfred	}
1043184610Salfred	if (parm.err) {
1044184610Salfred		usb2_transfer_unsetup(ppxfer, n_setup);
1045184610Salfred	}
1046184610Salfred	return (parm.err);
1047184610Salfred}
1048184610Salfred
1049184610Salfred/*------------------------------------------------------------------------*
1050184610Salfred *	usb2_transfer_unsetup_sub - factored out code
1051184610Salfred *------------------------------------------------------------------------*/
1052184610Salfredstatic void
1053184610Salfredusb2_transfer_unsetup_sub(struct usb2_xfer_root *info, uint8_t needs_delay)
1054184610Salfred{
1055184610Salfred	struct usb2_page_cache *pc;
1056184610Salfred
1057184824Sthompsa	USB_BUS_LOCK_ASSERT(info->bus, MA_OWNED);
1058184610Salfred
1059184610Salfred	/* wait for any outstanding DMA operations */
1060184610Salfred
1061184610Salfred	if (needs_delay) {
1062190181Sthompsa		usb2_timeout_t temp;
1063184610Salfred		temp = usb2_get_dma_delay(info->bus);
1064188411Sthompsa		usb2_pause_mtx(&info->bus->bus_mtx,
1065188411Sthompsa		    USB_MS_TO_TICKS(temp));
1066184610Salfred	}
1067187174Sthompsa
1068187174Sthompsa	/* make sure that our done messages are not queued anywhere */
1069187174Sthompsa	usb2_proc_mwait(info->done_p, &info->done_m[0], &info->done_m[1]);
1070187174Sthompsa
1071184824Sthompsa	USB_BUS_UNLOCK(info->bus);
1072184610Salfred
1073190180Sthompsa#if USB_HAVE_BUSDMA
1074184610Salfred	/* free DMA'able memory, if any */
1075184610Salfred	pc = info->dma_page_cache_start;
1076184610Salfred	while (pc != info->dma_page_cache_end) {
1077184610Salfred		usb2_pc_free_mem(pc);
1078184610Salfred		pc++;
1079184610Salfred	}
1080184610Salfred
1081184610Salfred	/* free DMA maps in all "xfer->frbuffers" */
1082184610Salfred	pc = info->xfer_page_cache_start;
1083184610Salfred	while (pc != info->xfer_page_cache_end) {
1084184610Salfred		usb2_pc_dmamap_destroy(pc);
1085184610Salfred		pc++;
1086184610Salfred	}
1087184610Salfred
1088184610Salfred	/* free all DMA tags */
1089184610Salfred	usb2_dma_tag_unsetup(&info->dma_parent_tag);
1090190180Sthompsa#endif
1091184610Salfred
1092184610Salfred	usb2_cv_destroy(&info->cv_drain);
1093184610Salfred
1094184610Salfred	/*
1095184610Salfred	 * free the "memory_base" last, hence the "info" structure is
1096184610Salfred	 * contained within the "memory_base"!
1097184610Salfred	 */
1098184610Salfred	free(info->memory_base, M_USB);
1099184610Salfred}
1100184610Salfred
1101184610Salfred/*------------------------------------------------------------------------*
1102184610Salfred *	usb2_transfer_unsetup - unsetup/free an array of USB transfers
1103184610Salfred *
1104184610Salfred * NOTE: All USB transfers in progress will get called back passing
1105184610Salfred * the error code "USB_ERR_CANCELLED" before this function
1106184610Salfred * returns.
1107184610Salfred *------------------------------------------------------------------------*/
1108184610Salfredvoid
1109184610Salfredusb2_transfer_unsetup(struct usb2_xfer **pxfer, uint16_t n_setup)
1110184610Salfred{
1111184610Salfred	struct usb2_xfer *xfer;
1112184610Salfred	struct usb2_xfer_root *info;
1113184610Salfred	uint8_t needs_delay = 0;
1114184610Salfred
1115184610Salfred	WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
1116184610Salfred	    "usb2_transfer_unsetup can sleep!");
1117184610Salfred
1118184610Salfred	while (n_setup--) {
1119184610Salfred		xfer = pxfer[n_setup];
1120184610Salfred
1121188982Sthompsa		if (xfer == NULL)
1122188982Sthompsa			continue;
1123184610Salfred
1124188982Sthompsa		info = xfer->xroot;
1125184610Salfred
1126188982Sthompsa		USB_XFER_LOCK(xfer);
1127188982Sthompsa		USB_BUS_LOCK(info->bus);
1128184610Salfred
1129188982Sthompsa		/*
1130188982Sthompsa		 * HINT: when you start/stop a transfer, it might be a
1131188982Sthompsa		 * good idea to directly use the "pxfer[]" structure:
1132188982Sthompsa		 *
1133188982Sthompsa		 * usb2_transfer_start(sc->pxfer[0]);
1134188982Sthompsa		 * usb2_transfer_stop(sc->pxfer[0]);
1135188982Sthompsa		 *
1136188982Sthompsa		 * That way, if your code has many parts that will not
1137188982Sthompsa		 * stop running under the same lock, in other words
1138188982Sthompsa		 * "xfer_mtx", the usb2_transfer_start and
1139188982Sthompsa		 * usb2_transfer_stop functions will simply return
1140188982Sthompsa		 * when they detect a NULL pointer argument.
1141188982Sthompsa		 *
1142188982Sthompsa		 * To avoid any races we clear the "pxfer[]" pointer
1143188982Sthompsa		 * while holding the private mutex of the driver:
1144188982Sthompsa		 */
1145188982Sthompsa		pxfer[n_setup] = NULL;
1146184610Salfred
1147188982Sthompsa		USB_BUS_UNLOCK(info->bus);
1148188982Sthompsa		USB_XFER_UNLOCK(xfer);
1149184610Salfred
1150188982Sthompsa		usb2_transfer_drain(xfer);
1151184610Salfred
1152190180Sthompsa#if USB_HAVE_BUSDMA
1153188982Sthompsa		if (xfer->flags_int.bdma_enable)
1154188982Sthompsa			needs_delay = 1;
1155190180Sthompsa#endif
1156188982Sthompsa		/*
1157188982Sthompsa		 * NOTE: default pipe does not have an
1158188982Sthompsa		 * interface, even if pipe->iface_index == 0
1159188982Sthompsa		 */
1160188982Sthompsa		xfer->pipe->refcount--;
1161184610Salfred
1162188982Sthompsa		usb2_callout_drain(&xfer->timeout_handle);
1163184610Salfred
1164188982Sthompsa		USB_BUS_LOCK(info->bus);
1165184610Salfred
1166188982Sthompsa		USB_ASSERT(info->setup_refcount != 0, ("Invalid setup "
1167188982Sthompsa		    "reference count!\n"));
1168184610Salfred
1169188982Sthompsa		info->setup_refcount--;
1170188982Sthompsa
1171188982Sthompsa		if (info->setup_refcount == 0) {
1172188982Sthompsa			usb2_transfer_unsetup_sub(info,
1173188982Sthompsa			    needs_delay);
1174188982Sthompsa		} else {
1175188982Sthompsa			USB_BUS_UNLOCK(info->bus);
1176184610Salfred		}
1177184610Salfred	}
1178184610Salfred}
1179184610Salfred
1180184610Salfred/*------------------------------------------------------------------------*
1181184610Salfred *	usb2_control_transfer_init - factored out code
1182184610Salfred *
1183184610Salfred * In USB Device Mode we have to wait for the SETUP packet which
1184184610Salfred * containst the "struct usb2_device_request" structure, before we can
1185184610Salfred * transfer any data. In USB Host Mode we already have the SETUP
1186184610Salfred * packet at the moment the USB transfer is started. This leads us to
1187184610Salfred * having to setup the USB transfer at two different places in
1188184610Salfred * time. This function just contains factored out control transfer
1189184610Salfred * initialisation code, so that we don't duplicate the code.
1190184610Salfred *------------------------------------------------------------------------*/
1191184610Salfredstatic void
1192184610Salfredusb2_control_transfer_init(struct usb2_xfer *xfer)
1193184610Salfred{
1194184610Salfred	struct usb2_device_request req;
1195184610Salfred
1196184610Salfred	/* copy out the USB request header */
1197184610Salfred
1198184610Salfred	usb2_copy_out(xfer->frbuffers, 0, &req, sizeof(req));
1199184610Salfred
1200184610Salfred	/* setup remainder */
1201184610Salfred
1202184610Salfred	xfer->flags_int.control_rem = UGETW(req.wLength);
1203184610Salfred
1204184610Salfred	/* copy direction to endpoint variable */
1205184610Salfred
1206184610Salfred	xfer->endpoint &= ~(UE_DIR_IN | UE_DIR_OUT);
1207184610Salfred	xfer->endpoint |=
1208184610Salfred	    (req.bmRequestType & UT_READ) ? UE_DIR_IN : UE_DIR_OUT;
1209184610Salfred}
1210184610Salfred
1211184610Salfred/*------------------------------------------------------------------------*
1212184610Salfred *	usb2_start_hardware_sub
1213184610Salfred *
1214184610Salfred * This function handles initialisation of control transfers. Control
1215184610Salfred * transfers are special in that regard that they can both transmit
1216184610Salfred * and receive data.
1217184610Salfred *
1218184610Salfred * Return values:
1219184610Salfred *    0: Success
1220184610Salfred * Else: Failure
1221184610Salfred *------------------------------------------------------------------------*/
1222184610Salfredstatic uint8_t
1223184610Salfredusb2_start_hardware_sub(struct usb2_xfer *xfer)
1224184610Salfred{
1225190181Sthompsa	usb2_frlength_t len;
1226184610Salfred
1227184610Salfred	/* Check for control endpoint stall */
1228184610Salfred	if (xfer->flags.stall_pipe) {
1229184610Salfred		/* no longer active */
1230184610Salfred		xfer->flags_int.control_act = 0;
1231184610Salfred	}
1232190184Sthompsa
1233190184Sthompsa	/* Check for invalid number of frames */
1234190184Sthompsa	if (xfer->nframes > 2) {
1235190184Sthompsa		/*
1236190184Sthompsa		 * If you need to split a control transfer, you
1237190184Sthompsa		 * have to do one part at a time. Only with
1238190184Sthompsa		 * non-control transfers you can do multiple
1239190184Sthompsa		 * parts a time.
1240190184Sthompsa		 */
1241190184Sthompsa		DPRINTFN(0, "Too many frames: %u\n",
1242190184Sthompsa		    (unsigned int)xfer->nframes);
1243190184Sthompsa		goto error;
1244190184Sthompsa	}
1245190184Sthompsa
1246184610Salfred	/*
1247184610Salfred         * Check if there is a control
1248184610Salfred         * transfer in progress:
1249184610Salfred         */
1250184610Salfred	if (xfer->flags_int.control_act) {
1251184610Salfred
1252184610Salfred		if (xfer->flags_int.control_hdr) {
1253184610Salfred
1254184610Salfred			/* clear send header flag */
1255184610Salfred
1256184610Salfred			xfer->flags_int.control_hdr = 0;
1257184610Salfred
1258184610Salfred			/* setup control transfer */
1259184610Salfred			if (xfer->flags_int.usb2_mode == USB_MODE_DEVICE) {
1260184610Salfred				usb2_control_transfer_init(xfer);
1261184610Salfred			}
1262184610Salfred		}
1263184610Salfred		/* get data length */
1264184610Salfred
1265184610Salfred		len = xfer->sumlen;
1266184610Salfred
1267184610Salfred	} else {
1268184610Salfred
1269184610Salfred		/* the size of the SETUP structure is hardcoded ! */
1270184610Salfred
1271184610Salfred		if (xfer->frlengths[0] != sizeof(struct usb2_device_request)) {
1272184610Salfred			DPRINTFN(0, "Wrong framelength %u != %zu\n",
1273184610Salfred			    xfer->frlengths[0], sizeof(struct
1274184610Salfred			    usb2_device_request));
1275184610Salfred			goto error;
1276184610Salfred		}
1277184610Salfred		/* check USB mode */
1278184610Salfred		if (xfer->flags_int.usb2_mode == USB_MODE_DEVICE) {
1279184610Salfred
1280184610Salfred			/* check number of frames */
1281184610Salfred			if (xfer->nframes != 1) {
1282184610Salfred				/*
1283184610Salfred			         * We need to receive the setup
1284184610Salfred			         * message first so that we know the
1285184610Salfred			         * data direction!
1286184610Salfred			         */
1287184610Salfred				DPRINTF("Misconfigured transfer\n");
1288184610Salfred				goto error;
1289184610Salfred			}
1290184610Salfred			/*
1291184610Salfred			 * Set a dummy "control_rem" value.  This
1292184610Salfred			 * variable will be overwritten later by a
1293184610Salfred			 * call to "usb2_control_transfer_init()" !
1294184610Salfred			 */
1295184610Salfred			xfer->flags_int.control_rem = 0xFFFF;
1296184610Salfred		} else {
1297184610Salfred
1298184610Salfred			/* setup "endpoint" and "control_rem" */
1299184610Salfred
1300184610Salfred			usb2_control_transfer_init(xfer);
1301184610Salfred		}
1302184610Salfred
1303184610Salfred		/* set transfer-header flag */
1304184610Salfred
1305184610Salfred		xfer->flags_int.control_hdr = 1;
1306184610Salfred
1307184610Salfred		/* get data length */
1308184610Salfred
1309184610Salfred		len = (xfer->sumlen - sizeof(struct usb2_device_request));
1310184610Salfred	}
1311184610Salfred
1312184610Salfred	/* check if there is a length mismatch */
1313184610Salfred
1314184610Salfred	if (len > xfer->flags_int.control_rem) {
1315184610Salfred		DPRINTFN(0, "Length greater than remaining length!\n");
1316184610Salfred		goto error;
1317184610Salfred	}
1318184610Salfred	/* check if we are doing a short transfer */
1319184610Salfred
1320184610Salfred	if (xfer->flags.force_short_xfer) {
1321184610Salfred		xfer->flags_int.control_rem = 0;
1322184610Salfred	} else {
1323184610Salfred		if ((len != xfer->max_data_length) &&
1324184610Salfred		    (len != xfer->flags_int.control_rem) &&
1325184610Salfred		    (xfer->nframes != 1)) {
1326184610Salfred			DPRINTFN(0, "Short control transfer without "
1327184610Salfred			    "force_short_xfer set!\n");
1328184610Salfred			goto error;
1329184610Salfred		}
1330184610Salfred		xfer->flags_int.control_rem -= len;
1331184610Salfred	}
1332184610Salfred
1333184610Salfred	/* the status part is executed when "control_act" is 0 */
1334184610Salfred
1335184610Salfred	if ((xfer->flags_int.control_rem > 0) ||
1336184610Salfred	    (xfer->flags.manual_status)) {
1337184610Salfred		/* don't execute the STATUS stage yet */
1338184610Salfred		xfer->flags_int.control_act = 1;
1339184610Salfred
1340184610Salfred		/* sanity check */
1341184610Salfred		if ((!xfer->flags_int.control_hdr) &&
1342184610Salfred		    (xfer->nframes == 1)) {
1343184610Salfred			/*
1344184610Salfred		         * This is not a valid operation!
1345184610Salfred		         */
1346184610Salfred			DPRINTFN(0, "Invalid parameter "
1347184610Salfred			    "combination\n");
1348184610Salfred			goto error;
1349184610Salfred		}
1350184610Salfred	} else {
1351184610Salfred		/* time to execute the STATUS stage */
1352184610Salfred		xfer->flags_int.control_act = 0;
1353184610Salfred	}
1354184610Salfred	return (0);			/* success */
1355184610Salfred
1356184610Salfrederror:
1357184610Salfred	return (1);			/* failure */
1358184610Salfred}
1359184610Salfred
1360184610Salfred/*------------------------------------------------------------------------*
1361184610Salfred *	usb2_start_hardware - start USB hardware for the given transfer
1362184610Salfred *
1363184610Salfred * This function should only be called from the USB callback.
1364184610Salfred *------------------------------------------------------------------------*/
1365184610Salfredvoid
1366184610Salfredusb2_start_hardware(struct usb2_xfer *xfer)
1367184610Salfred{
1368191494Sthompsa	struct usb2_xfer_root *info;
1369191494Sthompsa	struct usb2_bus *bus;
1370190181Sthompsa	usb2_frcount_t x;
1371184610Salfred
1372191494Sthompsa	info = xfer->xroot;
1373191494Sthompsa	bus = info->bus;
1374191494Sthompsa
1375184610Salfred	DPRINTF("xfer=%p, pipe=%p, nframes=%d, dir=%s\n",
1376184610Salfred	    xfer, xfer->pipe, xfer->nframes, USB_GET_DATA_ISREAD(xfer) ?
1377184610Salfred	    "read" : "write");
1378184610Salfred
1379191494Sthompsa	/* Check if the device is still alive */
1380191494Sthompsa	if (info->udev->state < USB_STATE_POWERED) {
1381191494Sthompsa		USB_BUS_LOCK(bus);
1382191494Sthompsa		usb2_transfer_done(xfer, USB_ERR_NOT_CONFIGURED);
1383191494Sthompsa		USB_BUS_UNLOCK(bus);
1384191494Sthompsa		return;
1385191494Sthompsa	}
1386191494Sthompsa
1387184610Salfred#if USB_DEBUG
1388184610Salfred	if (USB_DEBUG_VAR > 0) {
1389191494Sthompsa		USB_BUS_LOCK(bus);
1390184610Salfred
1391184610Salfred		usb2_dump_pipe(xfer->pipe);
1392184610Salfred
1393191494Sthompsa		USB_BUS_UNLOCK(bus);
1394184610Salfred	}
1395184610Salfred#endif
1396184610Salfred
1397184824Sthompsa	USB_XFER_LOCK_ASSERT(xfer, MA_OWNED);
1398191494Sthompsa	USB_BUS_LOCK_ASSERT(bus, MA_NOTOWNED);
1399184610Salfred
1400184610Salfred	/* Only open the USB transfer once! */
1401184610Salfred	if (!xfer->flags_int.open) {
1402184610Salfred		xfer->flags_int.open = 1;
1403184610Salfred
1404184610Salfred		DPRINTF("open\n");
1405184610Salfred
1406191494Sthompsa		USB_BUS_LOCK(bus);
1407184610Salfred		(xfer->pipe->methods->open) (xfer);
1408191494Sthompsa		USB_BUS_UNLOCK(bus);
1409184610Salfred	}
1410184610Salfred	/* set "transferring" flag */
1411184610Salfred	xfer->flags_int.transferring = 1;
1412184610Salfred
1413190734Sthompsa#if USB_HAVE_POWERD
1414186730Salfred	/* increment power reference */
1415186730Salfred	usb2_transfer_power_ref(xfer, 1);
1416190734Sthompsa#endif
1417184610Salfred	/*
1418184610Salfred	 * Check if the transfer is waiting on a queue, most
1419184610Salfred	 * frequently the "done_q":
1420184610Salfred	 */
1421184610Salfred	if (xfer->wait_queue) {
1422191494Sthompsa		USB_BUS_LOCK(bus);
1423184610Salfred		usb2_transfer_dequeue(xfer);
1424191494Sthompsa		USB_BUS_UNLOCK(bus);
1425184610Salfred	}
1426184610Salfred	/* clear "did_dma_delay" flag */
1427184610Salfred	xfer->flags_int.did_dma_delay = 0;
1428184610Salfred
1429184610Salfred	/* clear "did_close" flag */
1430184610Salfred	xfer->flags_int.did_close = 0;
1431184610Salfred
1432190180Sthompsa#if USB_HAVE_BUSDMA
1433184610Salfred	/* clear "bdma_setup" flag */
1434184610Salfred	xfer->flags_int.bdma_setup = 0;
1435190180Sthompsa#endif
1436184610Salfred	/* by default we cannot cancel any USB transfer immediately */
1437184610Salfred	xfer->flags_int.can_cancel_immed = 0;
1438184610Salfred
1439184610Salfred	/* clear lengths and frame counts by default */
1440184610Salfred	xfer->sumlen = 0;
1441184610Salfred	xfer->actlen = 0;
1442184610Salfred	xfer->aframes = 0;
1443184610Salfred
1444184610Salfred	/* clear any previous errors */
1445184610Salfred	xfer->error = 0;
1446184610Salfred
1447184610Salfred	/* sanity check */
1448184610Salfred
1449184610Salfred	if (xfer->nframes == 0) {
1450184610Salfred		if (xfer->flags.stall_pipe) {
1451184610Salfred			/*
1452184610Salfred			 * Special case - want to stall without transferring
1453184610Salfred			 * any data:
1454184610Salfred			 */
1455184610Salfred			DPRINTF("xfer=%p nframes=0: stall "
1456184610Salfred			    "or clear stall!\n", xfer);
1457191494Sthompsa			USB_BUS_LOCK(bus);
1458184610Salfred			xfer->flags_int.can_cancel_immed = 1;
1459184610Salfred			/* start the transfer */
1460184610Salfred			usb2_command_wrapper(&xfer->pipe->pipe_q, xfer);
1461191494Sthompsa			USB_BUS_UNLOCK(bus);
1462184610Salfred			return;
1463184610Salfred		}
1464191494Sthompsa		USB_BUS_LOCK(bus);
1465184610Salfred		usb2_transfer_done(xfer, USB_ERR_INVAL);
1466191494Sthompsa		USB_BUS_UNLOCK(bus);
1467184610Salfred		return;
1468184610Salfred	}
1469184610Salfred	/* compute total transfer length */
1470184610Salfred
1471184610Salfred	for (x = 0; x != xfer->nframes; x++) {
1472184610Salfred		xfer->sumlen += xfer->frlengths[x];
1473184610Salfred		if (xfer->sumlen < xfer->frlengths[x]) {
1474184610Salfred			/* length wrapped around */
1475191494Sthompsa			USB_BUS_LOCK(bus);
1476184610Salfred			usb2_transfer_done(xfer, USB_ERR_INVAL);
1477191494Sthompsa			USB_BUS_UNLOCK(bus);
1478184610Salfred			return;
1479184610Salfred		}
1480184610Salfred	}
1481184610Salfred
1482184610Salfred	/* clear some internal flags */
1483184610Salfred
1484184610Salfred	xfer->flags_int.short_xfer_ok = 0;
1485184610Salfred	xfer->flags_int.short_frames_ok = 0;
1486184610Salfred
1487184610Salfred	/* check if this is a control transfer */
1488184610Salfred
1489184610Salfred	if (xfer->flags_int.control_xfr) {
1490184610Salfred
1491184610Salfred		if (usb2_start_hardware_sub(xfer)) {
1492191494Sthompsa			USB_BUS_LOCK(bus);
1493184610Salfred			usb2_transfer_done(xfer, USB_ERR_STALLED);
1494191494Sthompsa			USB_BUS_UNLOCK(bus);
1495184610Salfred			return;
1496184610Salfred		}
1497184610Salfred	}
1498184610Salfred	/*
1499184610Salfred	 * Setup filtered version of some transfer flags,
1500184610Salfred	 * in case of data read direction
1501184610Salfred	 */
1502184610Salfred	if (USB_GET_DATA_ISREAD(xfer)) {
1503184610Salfred
1504190184Sthompsa		if (xfer->flags.short_frames_ok) {
1505190184Sthompsa			xfer->flags_int.short_xfer_ok = 1;
1506190184Sthompsa			xfer->flags_int.short_frames_ok = 1;
1507190184Sthompsa		} else if (xfer->flags.short_xfer_ok) {
1508190184Sthompsa			xfer->flags_int.short_xfer_ok = 1;
1509184610Salfred
1510190184Sthompsa			/* check for control transfer */
1511190184Sthompsa			if (xfer->flags_int.control_xfr) {
1512190184Sthompsa				/*
1513190184Sthompsa				 * 1) Control transfers do not support
1514190184Sthompsa				 * reception of multiple short USB
1515190184Sthompsa				 * frames in host mode and device side
1516190184Sthompsa				 * mode, with exception of:
1517190184Sthompsa				 *
1518190184Sthompsa				 * 2) Due to sometimes buggy device
1519190184Sthompsa				 * side firmware we need to do a
1520190184Sthompsa				 * STATUS stage in case of short
1521190184Sthompsa				 * control transfers in USB host mode.
1522190184Sthompsa				 * The STATUS stage then becomes the
1523190184Sthompsa				 * "alt_next" to the DATA stage.
1524190184Sthompsa				 */
1525184610Salfred				xfer->flags_int.short_frames_ok = 1;
1526184610Salfred			}
1527184610Salfred		}
1528184610Salfred	}
1529184610Salfred	/*
1530184610Salfred	 * Check if BUS-DMA support is enabled and try to load virtual
1531184610Salfred	 * buffers into DMA, if any:
1532184610Salfred	 */
1533190180Sthompsa#if USB_HAVE_BUSDMA
1534184610Salfred	if (xfer->flags_int.bdma_enable) {
1535184610Salfred		/* insert the USB transfer last in the BUS-DMA queue */
1536187173Sthompsa		usb2_command_wrapper(&xfer->xroot->dma_q, xfer);
1537184610Salfred		return;
1538184610Salfred	}
1539190180Sthompsa#endif
1540184610Salfred	/*
1541184610Salfred	 * Enter the USB transfer into the Host Controller or
1542184610Salfred	 * Device Controller schedule:
1543184610Salfred	 */
1544184610Salfred	usb2_pipe_enter(xfer);
1545184610Salfred}
1546184610Salfred
1547184610Salfred/*------------------------------------------------------------------------*
1548184610Salfred *	usb2_pipe_enter - factored out code
1549184610Salfred *------------------------------------------------------------------------*/
1550184610Salfredvoid
1551184610Salfredusb2_pipe_enter(struct usb2_xfer *xfer)
1552184610Salfred{
1553184610Salfred	struct usb2_pipe *pipe;
1554184610Salfred
1555184824Sthompsa	USB_XFER_LOCK_ASSERT(xfer, MA_OWNED);
1556184610Salfred
1557187173Sthompsa	USB_BUS_LOCK(xfer->xroot->bus);
1558184610Salfred
1559184610Salfred	pipe = xfer->pipe;
1560184610Salfred
1561184610Salfred	DPRINTF("enter\n");
1562184610Salfred
1563184610Salfred	/* enter the transfer */
1564184610Salfred	(pipe->methods->enter) (xfer);
1565184610Salfred
1566190738Sthompsa	xfer->flags_int.can_cancel_immed = 1;
1567190738Sthompsa
1568190738Sthompsa	/* check for transfer error */
1569190738Sthompsa	if (xfer->error) {
1570190738Sthompsa		/* some error has happened */
1571190738Sthompsa		usb2_transfer_done(xfer, 0);
1572190738Sthompsa		USB_BUS_UNLOCK(xfer->xroot->bus);
1573190738Sthompsa		return;
1574184610Salfred	}
1575184610Salfred
1576184610Salfred	/* start the transfer */
1577184610Salfred	usb2_command_wrapper(&pipe->pipe_q, xfer);
1578187173Sthompsa	USB_BUS_UNLOCK(xfer->xroot->bus);
1579184610Salfred}
1580184610Salfred
1581184610Salfred/*------------------------------------------------------------------------*
1582184610Salfred *	usb2_transfer_start - start an USB transfer
1583184610Salfred *
1584184610Salfred * NOTE: Calling this function more than one time will only
1585184610Salfred *       result in a single transfer start, until the USB transfer
1586184610Salfred *       completes.
1587184610Salfred *------------------------------------------------------------------------*/
1588184610Salfredvoid
1589184610Salfredusb2_transfer_start(struct usb2_xfer *xfer)
1590184610Salfred{
1591184610Salfred	if (xfer == NULL) {
1592184610Salfred		/* transfer is gone */
1593184610Salfred		return;
1594184610Salfred	}
1595184824Sthompsa	USB_XFER_LOCK_ASSERT(xfer, MA_OWNED);
1596184610Salfred
1597184610Salfred	/* mark the USB transfer started */
1598184610Salfred
1599184610Salfred	if (!xfer->flags_int.started) {
1600184610Salfred		xfer->flags_int.started = 1;
1601184610Salfred	}
1602184610Salfred	/* check if the USB transfer callback is already transferring */
1603184610Salfred
1604184610Salfred	if (xfer->flags_int.transferring) {
1605184610Salfred		return;
1606184610Salfred	}
1607187173Sthompsa	USB_BUS_LOCK(xfer->xroot->bus);
1608184610Salfred	/* call the USB transfer callback */
1609184610Salfred	usb2_callback_ss_done_defer(xfer);
1610187173Sthompsa	USB_BUS_UNLOCK(xfer->xroot->bus);
1611184610Salfred}
1612184610Salfred
1613184610Salfred/*------------------------------------------------------------------------*
1614184610Salfred *	usb2_transfer_stop - stop an USB transfer
1615184610Salfred *
1616184610Salfred * NOTE: Calling this function more than one time will only
1617184610Salfred *       result in a single transfer stop.
1618184610Salfred * NOTE: When this function returns it is not safe to free nor
1619184610Salfred *       reuse any DMA buffers. See "usb2_transfer_drain()".
1620184610Salfred *------------------------------------------------------------------------*/
1621184610Salfredvoid
1622184610Salfredusb2_transfer_stop(struct usb2_xfer *xfer)
1623184610Salfred{
1624184610Salfred	struct usb2_pipe *pipe;
1625184610Salfred
1626184610Salfred	if (xfer == NULL) {
1627184610Salfred		/* transfer is gone */
1628184610Salfred		return;
1629184610Salfred	}
1630184824Sthompsa	USB_XFER_LOCK_ASSERT(xfer, MA_OWNED);
1631184610Salfred
1632184610Salfred	/* check if the USB transfer was ever opened */
1633184610Salfred
1634184610Salfred	if (!xfer->flags_int.open) {
1635184610Salfred		/* nothing to do except clearing the "started" flag */
1636184610Salfred		xfer->flags_int.started = 0;
1637184610Salfred		return;
1638184610Salfred	}
1639184610Salfred	/* try to stop the current USB transfer */
1640184610Salfred
1641187173Sthompsa	USB_BUS_LOCK(xfer->xroot->bus);
1642184610Salfred	xfer->error = USB_ERR_CANCELLED;/* override any previous error */
1643184610Salfred	/*
1644184610Salfred	 * Clear "open" and "started" when both private and USB lock
1645184610Salfred	 * is locked so that we don't get a race updating "flags_int"
1646184610Salfred	 */
1647184610Salfred	xfer->flags_int.open = 0;
1648184610Salfred	xfer->flags_int.started = 0;
1649184610Salfred
1650184610Salfred	/*
1651184610Salfred	 * Check if we can cancel the USB transfer immediately.
1652184610Salfred	 */
1653184610Salfred	if (xfer->flags_int.transferring) {
1654184610Salfred		if (xfer->flags_int.can_cancel_immed &&
1655184610Salfred		    (!xfer->flags_int.did_close)) {
1656184610Salfred			DPRINTF("close\n");
1657184610Salfred			/*
1658184610Salfred			 * The following will lead to an USB_ERR_CANCELLED
1659184610Salfred			 * error code being passed to the USB callback.
1660184610Salfred			 */
1661184610Salfred			(xfer->pipe->methods->close) (xfer);
1662184610Salfred			/* only close once */
1663184610Salfred			xfer->flags_int.did_close = 1;
1664184610Salfred		} else {
1665184610Salfred			/* need to wait for the next done callback */
1666184610Salfred		}
1667184610Salfred	} else {
1668184610Salfred		DPRINTF("close\n");
1669184610Salfred
1670184610Salfred		/* close here and now */
1671184610Salfred		(xfer->pipe->methods->close) (xfer);
1672184610Salfred
1673184610Salfred		/*
1674184610Salfred		 * Any additional DMA delay is done by
1675184610Salfred		 * "usb2_transfer_unsetup()".
1676184610Salfred		 */
1677184610Salfred
1678184610Salfred		/*
1679184610Salfred		 * Special case. Check if we need to restart a blocked
1680184610Salfred		 * pipe.
1681184610Salfred		 */
1682184610Salfred		pipe = xfer->pipe;
1683184610Salfred
1684184610Salfred		/*
1685184610Salfred		 * If the current USB transfer is completing we need
1686184610Salfred		 * to start the next one:
1687184610Salfred		 */
1688184610Salfred		if (pipe->pipe_q.curr == xfer) {
1689184610Salfred			usb2_command_wrapper(&pipe->pipe_q, NULL);
1690184610Salfred		}
1691184610Salfred	}
1692184610Salfred
1693187173Sthompsa	USB_BUS_UNLOCK(xfer->xroot->bus);
1694184610Salfred}
1695184610Salfred
1696184610Salfred/*------------------------------------------------------------------------*
1697184610Salfred *	usb2_transfer_pending
1698184610Salfred *
1699184610Salfred * This function will check if an USB transfer is pending which is a
1700184610Salfred * little bit complicated!
1701184610Salfred * Return values:
1702184610Salfred * 0: Not pending
1703184610Salfred * 1: Pending: The USB transfer will receive a callback in the future.
1704184610Salfred *------------------------------------------------------------------------*/
1705184610Salfreduint8_t
1706184610Salfredusb2_transfer_pending(struct usb2_xfer *xfer)
1707184610Salfred{
1708184610Salfred	struct usb2_xfer_root *info;
1709184610Salfred	struct usb2_xfer_queue *pq;
1710184610Salfred
1711188600Sthompsa	if (xfer == NULL) {
1712188600Sthompsa		/* transfer is gone */
1713188600Sthompsa		return (0);
1714188600Sthompsa	}
1715184824Sthompsa	USB_XFER_LOCK_ASSERT(xfer, MA_OWNED);
1716184610Salfred
1717184610Salfred	if (xfer->flags_int.transferring) {
1718184610Salfred		/* trivial case */
1719184610Salfred		return (1);
1720184610Salfred	}
1721187173Sthompsa	USB_BUS_LOCK(xfer->xroot->bus);
1722184610Salfred	if (xfer->wait_queue) {
1723184610Salfred		/* we are waiting on a queue somewhere */
1724187173Sthompsa		USB_BUS_UNLOCK(xfer->xroot->bus);
1725184610Salfred		return (1);
1726184610Salfred	}
1727187173Sthompsa	info = xfer->xroot;
1728184610Salfred	pq = &info->done_q;
1729184610Salfred
1730184610Salfred	if (pq->curr == xfer) {
1731184610Salfred		/* we are currently scheduled for callback */
1732187173Sthompsa		USB_BUS_UNLOCK(xfer->xroot->bus);
1733184610Salfred		return (1);
1734184610Salfred	}
1735184610Salfred	/* we are not pending */
1736187173Sthompsa	USB_BUS_UNLOCK(xfer->xroot->bus);
1737184610Salfred	return (0);
1738184610Salfred}
1739184610Salfred
1740184610Salfred/*------------------------------------------------------------------------*
1741184610Salfred *	usb2_transfer_drain
1742184610Salfred *
1743184610Salfred * This function will stop the USB transfer and wait for any
1744184610Salfred * additional BUS-DMA and HW-DMA operations to complete. Buffers that
1745184610Salfred * are loaded into DMA can safely be freed or reused after that this
1746184610Salfred * function has returned.
1747184610Salfred *------------------------------------------------------------------------*/
1748184610Salfredvoid
1749184610Salfredusb2_transfer_drain(struct usb2_xfer *xfer)
1750184610Salfred{
1751184610Salfred	WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
1752184610Salfred	    "usb2_transfer_drain can sleep!");
1753184610Salfred
1754184610Salfred	if (xfer == NULL) {
1755184610Salfred		/* transfer is gone */
1756184610Salfred		return;
1757184610Salfred	}
1758187173Sthompsa	if (xfer->xroot->xfer_mtx != &Giant) {
1759184824Sthompsa		USB_XFER_LOCK_ASSERT(xfer, MA_NOTOWNED);
1760184610Salfred	}
1761184824Sthompsa	USB_XFER_LOCK(xfer);
1762184610Salfred
1763184610Salfred	usb2_transfer_stop(xfer);
1764184610Salfred
1765184610Salfred	while (usb2_transfer_pending(xfer)) {
1766184610Salfred		xfer->flags_int.draining = 1;
1767184610Salfred		/*
1768184610Salfred		 * Wait until the current outstanding USB
1769184610Salfred		 * transfer is complete !
1770184610Salfred		 */
1771187173Sthompsa		usb2_cv_wait(&xfer->xroot->cv_drain, xfer->xroot->xfer_mtx);
1772184610Salfred	}
1773184824Sthompsa	USB_XFER_UNLOCK(xfer);
1774184610Salfred}
1775184610Salfred
1776184610Salfred/*------------------------------------------------------------------------*
1777184610Salfred *	usb2_set_frame_data
1778184610Salfred *
1779184610Salfred * This function sets the pointer of the buffer that should
1780184610Salfred * loaded directly into DMA for the given USB frame. Passing "ptr"
1781184610Salfred * equal to NULL while the corresponding "frlength" is greater
1782184610Salfred * than zero gives undefined results!
1783184610Salfred *------------------------------------------------------------------------*/
1784184610Salfredvoid
1785190181Sthompsausb2_set_frame_data(struct usb2_xfer *xfer, void *ptr, usb2_frcount_t frindex)
1786184610Salfred{
1787184610Salfred	/* set virtual address to load and length */
1788184610Salfred	xfer->frbuffers[frindex].buffer = ptr;
1789184610Salfred}
1790184610Salfred
1791184610Salfred/*------------------------------------------------------------------------*
1792184610Salfred *	usb2_set_frame_offset
1793184610Salfred *
1794184610Salfred * This function sets the frame data buffer offset relative to the beginning
1795184610Salfred * of the USB DMA buffer allocated for this USB transfer.
1796184610Salfred *------------------------------------------------------------------------*/
1797184610Salfredvoid
1798190181Sthompsausb2_set_frame_offset(struct usb2_xfer *xfer, usb2_frlength_t offset,
1799190181Sthompsa    usb2_frcount_t frindex)
1800184610Salfred{
1801184610Salfred	USB_ASSERT(!xfer->flags.ext_buffer, ("Cannot offset data frame "
1802184610Salfred	    "when the USB buffer is external!\n"));
1803184610Salfred
1804184610Salfred	/* set virtual address to load */
1805184610Salfred	xfer->frbuffers[frindex].buffer =
1806184610Salfred	    USB_ADD_BYTES(xfer->local_buffer, offset);
1807184610Salfred}
1808184610Salfred
1809184610Salfred/*------------------------------------------------------------------------*
1810184610Salfred *	usb2_callback_proc - factored out code
1811184610Salfred *
1812184610Salfred * This function performs USB callbacks.
1813184610Salfred *------------------------------------------------------------------------*/
1814184610Salfredstatic void
1815184610Salfredusb2_callback_proc(struct usb2_proc_msg *_pm)
1816184610Salfred{
1817184610Salfred	struct usb2_done_msg *pm = (void *)_pm;
1818187173Sthompsa	struct usb2_xfer_root *info = pm->xroot;
1819184610Salfred
1820184610Salfred	/* Change locking order */
1821184824Sthompsa	USB_BUS_UNLOCK(info->bus);
1822184610Salfred
1823184610Salfred	/*
1824184610Salfred	 * We exploit the fact that the mutex is the same for all
1825184610Salfred	 * callbacks that will be called from this thread:
1826184610Salfred	 */
1827187173Sthompsa	mtx_lock(info->xfer_mtx);
1828184824Sthompsa	USB_BUS_LOCK(info->bus);
1829184610Salfred
1830184610Salfred	/* Continue where we lost track */
1831184610Salfred	usb2_command_wrapper(&info->done_q,
1832184610Salfred	    info->done_q.curr);
1833184610Salfred
1834187173Sthompsa	mtx_unlock(info->xfer_mtx);
1835184610Salfred}
1836184610Salfred
1837184610Salfred/*------------------------------------------------------------------------*
1838184610Salfred *	usb2_callback_ss_done_defer
1839184610Salfred *
1840184610Salfred * This function will defer the start, stop and done callback to the
1841184610Salfred * correct thread.
1842184610Salfred *------------------------------------------------------------------------*/
1843184610Salfredstatic void
1844184610Salfredusb2_callback_ss_done_defer(struct usb2_xfer *xfer)
1845184610Salfred{
1846187173Sthompsa	struct usb2_xfer_root *info = xfer->xroot;
1847184610Salfred	struct usb2_xfer_queue *pq = &info->done_q;
1848184610Salfred
1849187173Sthompsa	USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
1850184824Sthompsa
1851184610Salfred	if (pq->curr != xfer) {
1852184610Salfred		usb2_transfer_enqueue(pq, xfer);
1853184610Salfred	}
1854184610Salfred	if (!pq->recurse_1) {
1855184610Salfred
1856184610Salfred		/*
1857184610Salfred	         * We have to postpone the callback due to the fact we
1858184610Salfred	         * will have a Lock Order Reversal, LOR, if we try to
1859184610Salfred	         * proceed !
1860184610Salfred	         */
1861187174Sthompsa		if (usb2_proc_msignal(info->done_p,
1862184610Salfred		    &info->done_m[0], &info->done_m[1])) {
1863184610Salfred			/* ignore */
1864184610Salfred		}
1865184610Salfred	} else {
1866184610Salfred		/* clear second recurse flag */
1867184610Salfred		pq->recurse_2 = 0;
1868184610Salfred	}
1869184610Salfred	return;
1870184610Salfred
1871184610Salfred}
1872184610Salfred
1873184610Salfred/*------------------------------------------------------------------------*
1874184610Salfred *	usb2_callback_wrapper
1875184610Salfred *
1876184610Salfred * This is a wrapper for USB callbacks. This wrapper does some
1877184610Salfred * auto-magic things like figuring out if we can call the callback
1878184610Salfred * directly from the current context or if we need to wakeup the
1879184610Salfred * interrupt process.
1880184610Salfred *------------------------------------------------------------------------*/
1881184610Salfredstatic void
1882184610Salfredusb2_callback_wrapper(struct usb2_xfer_queue *pq)
1883184610Salfred{
1884184610Salfred	struct usb2_xfer *xfer = pq->curr;
1885187173Sthompsa	struct usb2_xfer_root *info = xfer->xroot;
1886184610Salfred
1887190738Sthompsa	USB_BUS_LOCK_ASSERT(info->bus, MA_OWNED);
1888190738Sthompsa	if (!mtx_owned(info->xfer_mtx)) {
1889184610Salfred		/*
1890184610Salfred	       	 * Cases that end up here:
1891184610Salfred		 *
1892184610Salfred		 * 5) HW interrupt done callback or other source.
1893184610Salfred		 */
1894184610Salfred		DPRINTFN(3, "case 5\n");
1895184610Salfred
1896184610Salfred		/*
1897184610Salfred	         * We have to postpone the callback due to the fact we
1898184610Salfred	         * will have a Lock Order Reversal, LOR, if we try to
1899184610Salfred	         * proceed !
1900184610Salfred	         */
1901187174Sthompsa		if (usb2_proc_msignal(info->done_p,
1902184610Salfred		    &info->done_m[0], &info->done_m[1])) {
1903184610Salfred			/* ignore */
1904184610Salfred		}
1905184610Salfred		return;
1906184610Salfred	}
1907184610Salfred	/*
1908184610Salfred	 * Cases that end up here:
1909184610Salfred	 *
1910184610Salfred	 * 1) We are starting a transfer
1911184610Salfred	 * 2) We are prematurely calling back a transfer
1912184610Salfred	 * 3) We are stopping a transfer
1913184610Salfred	 * 4) We are doing an ordinary callback
1914184610Salfred	 */
1915184610Salfred	DPRINTFN(3, "case 1-4\n");
1916184610Salfred	/* get next USB transfer in the queue */
1917184610Salfred	info->done_q.curr = NULL;
1918184610Salfred
1919190738Sthompsa	USB_BUS_UNLOCK(info->bus);
1920190738Sthompsa	USB_BUS_LOCK_ASSERT(info->bus, MA_NOTOWNED);
1921184610Salfred
1922184610Salfred	/* set correct USB state for callback */
1923184610Salfred	if (!xfer->flags_int.transferring) {
1924184610Salfred		xfer->usb2_state = USB_ST_SETUP;
1925184610Salfred		if (!xfer->flags_int.started) {
1926184610Salfred			/* we got stopped before we even got started */
1927190738Sthompsa			USB_BUS_LOCK(info->bus);
1928184610Salfred			goto done;
1929184610Salfred		}
1930184610Salfred	} else {
1931184610Salfred
1932184610Salfred		if (usb2_callback_wrapper_sub(xfer)) {
1933184610Salfred			/* the callback has been deferred */
1934190738Sthompsa			USB_BUS_LOCK(info->bus);
1935184610Salfred			goto done;
1936184610Salfred		}
1937190734Sthompsa#if USB_HAVE_POWERD
1938186730Salfred		/* decrement power reference */
1939186730Salfred		usb2_transfer_power_ref(xfer, -1);
1940190734Sthompsa#endif
1941184610Salfred		xfer->flags_int.transferring = 0;
1942184610Salfred
1943184610Salfred		if (xfer->error) {
1944184610Salfred			xfer->usb2_state = USB_ST_ERROR;
1945184610Salfred		} else {
1946184610Salfred			/* set transferred state */
1947184610Salfred			xfer->usb2_state = USB_ST_TRANSFERRED;
1948190180Sthompsa#if USB_HAVE_BUSDMA
1949184610Salfred			/* sync DMA memory, if any */
1950184610Salfred			if (xfer->flags_int.bdma_enable &&
1951184610Salfred			    (!xfer->flags_int.bdma_no_post_sync)) {
1952184610Salfred				usb2_bdma_post_sync(xfer);
1953184610Salfred			}
1954190180Sthompsa#endif
1955184610Salfred		}
1956184610Salfred	}
1957184610Salfred
1958184610Salfred	/* call processing routine */
1959184610Salfred	(xfer->callback) (xfer);
1960184610Salfred
1961184610Salfred	/* pickup the USB mutex again */
1962190738Sthompsa	USB_BUS_LOCK(info->bus);
1963184610Salfred
1964184610Salfred	/*
1965184610Salfred	 * Check if we got started after that we got cancelled, but
1966187166Sthompsa	 * before we managed to do the callback.
1967184610Salfred	 */
1968184610Salfred	if ((!xfer->flags_int.open) &&
1969184610Salfred	    (xfer->flags_int.started) &&
1970184610Salfred	    (xfer->usb2_state == USB_ST_ERROR)) {
1971184610Salfred		/* try to loop, but not recursivly */
1972184610Salfred		usb2_command_wrapper(&info->done_q, xfer);
1973184610Salfred		return;
1974187166Sthompsa	}
1975187166Sthompsa
1976187166Sthompsadone:
1977187166Sthompsa	/*
1978187166Sthompsa	 * Check if we are draining.
1979187166Sthompsa	 */
1980187166Sthompsa	if (xfer->flags_int.draining &&
1981184610Salfred	    (!xfer->flags_int.transferring)) {
1982184610Salfred		/* "usb2_transfer_drain()" is waiting for end of transfer */
1983184610Salfred		xfer->flags_int.draining = 0;
1984190738Sthompsa		usb2_cv_broadcast(&info->cv_drain);
1985184610Salfred	}
1986187166Sthompsa
1987184610Salfred	/* do the next callback, if any */
1988184610Salfred	usb2_command_wrapper(&info->done_q,
1989184610Salfred	    info->done_q.curr);
1990184610Salfred}
1991184610Salfred
1992184610Salfred/*------------------------------------------------------------------------*
1993184610Salfred *	usb2_dma_delay_done_cb
1994184610Salfred *
1995184610Salfred * This function is called when the DMA delay has been exectuded, and
1996184610Salfred * will make sure that the callback is called to complete the USB
1997184610Salfred * transfer. This code path is ususally only used when there is an USB
1998184610Salfred * error like USB_ERR_CANCELLED.
1999184610Salfred *------------------------------------------------------------------------*/
2000184610Salfredstatic void
2001184610Salfredusb2_dma_delay_done_cb(void *arg)
2002184610Salfred{
2003184610Salfred	struct usb2_xfer *xfer = arg;
2004184610Salfred
2005187173Sthompsa	USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
2006184610Salfred
2007184610Salfred	DPRINTFN(3, "Completed %p\n", xfer);
2008184610Salfred
2009184610Salfred	/* queue callback for execution, again */
2010184610Salfred	usb2_transfer_done(xfer, 0);
2011184610Salfred}
2012184610Salfred
2013184610Salfred/*------------------------------------------------------------------------*
2014184610Salfred *	usb2_transfer_dequeue
2015184610Salfred *
2016184610Salfred *  - This function is used to remove an USB transfer from a USB
2017184610Salfred *  transfer queue.
2018184610Salfred *
2019184610Salfred *  - This function can be called multiple times in a row.
2020184610Salfred *------------------------------------------------------------------------*/
2021184610Salfredvoid
2022184610Salfredusb2_transfer_dequeue(struct usb2_xfer *xfer)
2023184610Salfred{
2024184610Salfred	struct usb2_xfer_queue *pq;
2025184610Salfred
2026184610Salfred	pq = xfer->wait_queue;
2027184610Salfred	if (pq) {
2028184610Salfred		TAILQ_REMOVE(&pq->head, xfer, wait_entry);
2029184610Salfred		xfer->wait_queue = NULL;
2030184610Salfred	}
2031184610Salfred}
2032184610Salfred
2033184610Salfred/*------------------------------------------------------------------------*
2034184610Salfred *	usb2_transfer_enqueue
2035184610Salfred *
2036184610Salfred *  - This function is used to insert an USB transfer into a USB *
2037184610Salfred *  transfer queue.
2038184610Salfred *
2039184610Salfred *  - This function can be called multiple times in a row.
2040184610Salfred *------------------------------------------------------------------------*/
2041184610Salfredvoid
2042184610Salfredusb2_transfer_enqueue(struct usb2_xfer_queue *pq, struct usb2_xfer *xfer)
2043184610Salfred{
2044184610Salfred	/*
2045184610Salfred	 * Insert the USB transfer into the queue, if it is not
2046184610Salfred	 * already on a USB transfer queue:
2047184610Salfred	 */
2048184610Salfred	if (xfer->wait_queue == NULL) {
2049184610Salfred		xfer->wait_queue = pq;
2050184610Salfred		TAILQ_INSERT_TAIL(&pq->head, xfer, wait_entry);
2051184610Salfred	}
2052184610Salfred}
2053184610Salfred
2054184610Salfred/*------------------------------------------------------------------------*
2055184610Salfred *	usb2_transfer_done
2056184610Salfred *
2057184610Salfred *  - This function is used to remove an USB transfer from the busdma,
2058184610Salfred *  pipe or interrupt queue.
2059184610Salfred *
2060184610Salfred *  - This function is used to queue the USB transfer on the done
2061184610Salfred *  queue.
2062184610Salfred *
2063184610Salfred *  - This function is used to stop any USB transfer timeouts.
2064184610Salfred *------------------------------------------------------------------------*/
2065184610Salfredvoid
2066184610Salfredusb2_transfer_done(struct usb2_xfer *xfer, usb2_error_t error)
2067184610Salfred{
2068187173Sthompsa	USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
2069184610Salfred
2070184610Salfred	DPRINTF("err=%s\n", usb2_errstr(error));
2071184610Salfred
2072184610Salfred	/*
2073184610Salfred	 * If we are not transferring then just return.
2074184610Salfred	 * This can happen during transfer cancel.
2075184610Salfred	 */
2076184610Salfred	if (!xfer->flags_int.transferring) {
2077184610Salfred		DPRINTF("not transferring\n");
2078184610Salfred		return;
2079184610Salfred	}
2080184610Salfred	/* only set transfer error if not already set */
2081184610Salfred	if (!xfer->error) {
2082184610Salfred		xfer->error = error;
2083184610Salfred	}
2084184610Salfred	/* stop any callouts */
2085184610Salfred	usb2_callout_stop(&xfer->timeout_handle);
2086184610Salfred
2087184610Salfred	/*
2088184610Salfred	 * If we are waiting on a queue, just remove the USB transfer
2089184610Salfred	 * from the queue, if any. We should have the required locks
2090184610Salfred	 * locked to do the remove when this function is called.
2091184610Salfred	 */
2092184610Salfred	usb2_transfer_dequeue(xfer);
2093184610Salfred
2094190180Sthompsa#if USB_HAVE_BUSDMA
2095187173Sthompsa	if (mtx_owned(xfer->xroot->xfer_mtx)) {
2096190180Sthompsa		struct usb2_xfer_queue *pq;
2097190180Sthompsa
2098184610Salfred		/*
2099184610Salfred		 * If the private USB lock is not locked, then we assume
2100184610Salfred		 * that the BUS-DMA load stage has been passed:
2101184610Salfred		 */
2102187173Sthompsa		pq = &xfer->xroot->dma_q;
2103184610Salfred
2104184610Salfred		if (pq->curr == xfer) {
2105184610Salfred			/* start the next BUS-DMA load, if any */
2106184610Salfred			usb2_command_wrapper(pq, NULL);
2107184610Salfred		}
2108184610Salfred	}
2109190180Sthompsa#endif
2110184610Salfred	/* keep some statistics */
2111184610Salfred	if (xfer->error) {
2112187173Sthompsa		xfer->xroot->bus->stats_err.uds_requests
2113184610Salfred		    [xfer->pipe->edesc->bmAttributes & UE_XFERTYPE]++;
2114184610Salfred	} else {
2115187173Sthompsa		xfer->xroot->bus->stats_ok.uds_requests
2116184610Salfred		    [xfer->pipe->edesc->bmAttributes & UE_XFERTYPE]++;
2117184610Salfred	}
2118184610Salfred
2119184610Salfred	/* call the USB transfer callback */
2120184610Salfred	usb2_callback_ss_done_defer(xfer);
2121184610Salfred}
2122184610Salfred
2123184610Salfred/*------------------------------------------------------------------------*
2124184610Salfred *	usb2_transfer_start_cb
2125184610Salfred *
2126184610Salfred * This function is called to start the USB transfer when
2127184610Salfred * "xfer->interval" is greater than zero, and and the endpoint type is
2128184610Salfred * BULK or CONTROL.
2129184610Salfred *------------------------------------------------------------------------*/
2130184610Salfredstatic void
2131184610Salfredusb2_transfer_start_cb(void *arg)
2132184610Salfred{
2133184610Salfred	struct usb2_xfer *xfer = arg;
2134184610Salfred	struct usb2_pipe *pipe = xfer->pipe;
2135184610Salfred
2136187173Sthompsa	USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
2137184610Salfred
2138184610Salfred	DPRINTF("start\n");
2139184610Salfred
2140184610Salfred	/* start the transfer */
2141184610Salfred	(pipe->methods->start) (xfer);
2142184610Salfred
2143190738Sthompsa	xfer->flags_int.can_cancel_immed = 1;
2144190738Sthompsa
2145190738Sthompsa	/* check for error */
2146190738Sthompsa	if (xfer->error) {
2147190738Sthompsa		/* some error has happened */
2148190738Sthompsa		usb2_transfer_done(xfer, 0);
2149184610Salfred	}
2150184610Salfred}
2151184610Salfred
2152184610Salfred/*------------------------------------------------------------------------*
2153184610Salfred *	usb2_transfer_set_stall
2154184610Salfred *
2155184610Salfred * This function is used to set the stall flag outside the
2156184610Salfred * callback. This function is NULL safe.
2157184610Salfred *------------------------------------------------------------------------*/
2158184610Salfredvoid
2159184610Salfredusb2_transfer_set_stall(struct usb2_xfer *xfer)
2160184610Salfred{
2161184610Salfred	if (xfer == NULL) {
2162184610Salfred		/* tearing down */
2163184610Salfred		return;
2164184610Salfred	}
2165184824Sthompsa	USB_XFER_LOCK_ASSERT(xfer, MA_OWNED);
2166184610Salfred
2167184610Salfred	/* avoid any races by locking the USB mutex */
2168187173Sthompsa	USB_BUS_LOCK(xfer->xroot->bus);
2169184610Salfred
2170184610Salfred	xfer->flags.stall_pipe = 1;
2171184610Salfred
2172187173Sthompsa	USB_BUS_UNLOCK(xfer->xroot->bus);
2173184610Salfred}
2174184610Salfred
2175184610Salfred/*------------------------------------------------------------------------*
2176184610Salfred *	usb2_transfer_clear_stall
2177184610Salfred *
2178184610Salfred * This function is used to clear the stall flag outside the
2179184610Salfred * callback. This function is NULL safe.
2180184610Salfred *------------------------------------------------------------------------*/
2181184610Salfredvoid
2182184610Salfredusb2_transfer_clear_stall(struct usb2_xfer *xfer)
2183184610Salfred{
2184184610Salfred	if (xfer == NULL) {
2185184610Salfred		/* tearing down */
2186184610Salfred		return;
2187184610Salfred	}
2188184824Sthompsa	USB_XFER_LOCK_ASSERT(xfer, MA_OWNED);
2189184610Salfred
2190184610Salfred	/* avoid any races by locking the USB mutex */
2191187173Sthompsa	USB_BUS_LOCK(xfer->xroot->bus);
2192184610Salfred
2193184610Salfred	xfer->flags.stall_pipe = 0;
2194184610Salfred
2195187173Sthompsa	USB_BUS_UNLOCK(xfer->xroot->bus);
2196184610Salfred}
2197184610Salfred
2198184610Salfred/*------------------------------------------------------------------------*
2199184610Salfred *	usb2_pipe_start
2200184610Salfred *
2201184610Salfred * This function is used to add an USB transfer to the pipe transfer list.
2202184610Salfred *------------------------------------------------------------------------*/
2203184610Salfredvoid
2204184610Salfredusb2_pipe_start(struct usb2_xfer_queue *pq)
2205184610Salfred{
2206184610Salfred	struct usb2_pipe *pipe;
2207184610Salfred	struct usb2_xfer *xfer;
2208184610Salfred	uint8_t type;
2209184610Salfred
2210184610Salfred	xfer = pq->curr;
2211184610Salfred	pipe = xfer->pipe;
2212184610Salfred
2213187173Sthompsa	USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
2214184610Salfred
2215184610Salfred	/*
2216184610Salfred	 * If the pipe is already stalled we do nothing !
2217184610Salfred	 */
2218184610Salfred	if (pipe->is_stalled) {
2219184610Salfred		return;
2220184610Salfred	}
2221184610Salfred	/*
2222184610Salfred	 * Check if we are supposed to stall the pipe:
2223184610Salfred	 */
2224184610Salfred	if (xfer->flags.stall_pipe) {
2225184610Salfred		/* clear stall command */
2226184610Salfred		xfer->flags.stall_pipe = 0;
2227184610Salfred
2228184610Salfred		/*
2229184610Salfred		 * Only stall BULK and INTERRUPT endpoints.
2230184610Salfred		 */
2231184610Salfred		type = (pipe->edesc->bmAttributes & UE_XFERTYPE);
2232184610Salfred		if ((type == UE_BULK) ||
2233184610Salfred		    (type == UE_INTERRUPT)) {
2234184610Salfred			struct usb2_device *udev;
2235184610Salfred			struct usb2_xfer_root *info;
2236184610Salfred
2237187173Sthompsa			info = xfer->xroot;
2238187173Sthompsa			udev = info->udev;
2239184610Salfred			pipe->is_stalled = 1;
2240184610Salfred
2241184610Salfred			if (udev->flags.usb2_mode == USB_MODE_DEVICE) {
2242184610Salfred				(udev->bus->methods->set_stall) (
2243184610Salfred				    udev, NULL, pipe);
2244184610Salfred			} else if (udev->default_xfer[1]) {
2245187173Sthompsa				info = udev->default_xfer[1]->xroot;
2246187174Sthompsa				if (usb2_proc_msignal(
2247187174Sthompsa				    &info->bus->non_giant_callback_proc,
2248184610Salfred				    &udev->cs_msg[0], &udev->cs_msg[1])) {
2249184610Salfred					/* ignore */
2250184610Salfred				}
2251184610Salfred			} else {
2252184610Salfred				/* should not happen */
2253184610Salfred				DPRINTFN(0, "No stall handler!\n");
2254184610Salfred			}
2255184610Salfred			/*
2256184610Salfred			 * We get started again when the stall is cleared!
2257184610Salfred			 */
2258184610Salfred			return;
2259184610Salfred		}
2260184610Salfred	}
2261184610Salfred	/* Set or clear stall complete - special case */
2262184610Salfred	if (xfer->nframes == 0) {
2263184610Salfred		/* we are complete */
2264184610Salfred		xfer->aframes = 0;
2265184610Salfred		usb2_transfer_done(xfer, 0);
2266184610Salfred		return;
2267184610Salfred	}
2268184610Salfred	/*
2269184610Salfred	 * Handled cases:
2270184610Salfred	 *
2271184610Salfred	 * 1) Start the first transfer queued.
2272184610Salfred	 *
2273184610Salfred	 * 2) Re-start the current USB transfer.
2274184610Salfred	 */
2275184610Salfred	/*
2276184610Salfred	 * Check if there should be any
2277184610Salfred	 * pre transfer start delay:
2278184610Salfred	 */
2279184610Salfred	if (xfer->interval > 0) {
2280184610Salfred		type = (pipe->edesc->bmAttributes & UE_XFERTYPE);
2281184610Salfred		if ((type == UE_BULK) ||
2282184610Salfred		    (type == UE_CONTROL)) {
2283184610Salfred			usb2_transfer_timeout_ms(xfer,
2284184610Salfred			    &usb2_transfer_start_cb,
2285184610Salfred			    xfer->interval);
2286184610Salfred			return;
2287184610Salfred		}
2288184610Salfred	}
2289184610Salfred	DPRINTF("start\n");
2290184610Salfred
2291184610Salfred	/* start USB transfer */
2292184610Salfred	(pipe->methods->start) (xfer);
2293184610Salfred
2294190738Sthompsa	xfer->flags_int.can_cancel_immed = 1;
2295190738Sthompsa
2296190738Sthompsa	/* check for error */
2297190738Sthompsa	if (xfer->error) {
2298190738Sthompsa		/* some error has happened */
2299190738Sthompsa		usb2_transfer_done(xfer, 0);
2300184610Salfred	}
2301184610Salfred}
2302184610Salfred
2303184610Salfred/*------------------------------------------------------------------------*
2304184610Salfred *	usb2_transfer_timeout_ms
2305184610Salfred *
2306184610Salfred * This function is used to setup a timeout on the given USB
2307184610Salfred * transfer. If the timeout has been deferred the callback given by
2308184610Salfred * "cb" will get called after "ms" milliseconds.
2309184610Salfred *------------------------------------------------------------------------*/
2310184610Salfredvoid
2311184610Salfredusb2_transfer_timeout_ms(struct usb2_xfer *xfer,
2312190181Sthompsa    void (*cb) (void *arg), usb2_timeout_t ms)
2313184610Salfred{
2314187173Sthompsa	USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
2315184610Salfred
2316184610Salfred	/* defer delay */
2317184610Salfred	usb2_callout_reset(&xfer->timeout_handle,
2318184610Salfred	    USB_MS_TO_TICKS(ms), cb, xfer);
2319184610Salfred}
2320184610Salfred
2321184610Salfred/*------------------------------------------------------------------------*
2322184610Salfred *	usb2_callback_wrapper_sub
2323184610Salfred *
2324184610Salfred *  - This function will update variables in an USB transfer after
2325184610Salfred *  that the USB transfer is complete.
2326184610Salfred *
2327184610Salfred *  - This function is used to start the next USB transfer on the
2328184610Salfred *  pipe transfer queue, if any.
2329184610Salfred *
2330184610Salfred * NOTE: In some special cases the USB transfer will not be removed from
2331184610Salfred * the pipe queue, but remain first. To enforce USB transfer removal call
2332184610Salfred * this function passing the error code "USB_ERR_CANCELLED".
2333184610Salfred *
2334184610Salfred * Return values:
2335184610Salfred * 0: Success.
2336184610Salfred * Else: The callback has been deferred.
2337184610Salfred *------------------------------------------------------------------------*/
2338184610Salfredstatic uint8_t
2339184610Salfredusb2_callback_wrapper_sub(struct usb2_xfer *xfer)
2340184610Salfred{
2341184610Salfred	struct usb2_pipe *pipe;
2342190181Sthompsa	usb2_frcount_t x;
2343184610Salfred
2344184610Salfred	if ((!xfer->flags_int.open) &&
2345184610Salfred	    (!xfer->flags_int.did_close)) {
2346184610Salfred		DPRINTF("close\n");
2347187173Sthompsa		USB_BUS_LOCK(xfer->xroot->bus);
2348184610Salfred		(xfer->pipe->methods->close) (xfer);
2349187173Sthompsa		USB_BUS_UNLOCK(xfer->xroot->bus);
2350184610Salfred		/* only close once */
2351184610Salfred		xfer->flags_int.did_close = 1;
2352184610Salfred		return (1);		/* wait for new callback */
2353184610Salfred	}
2354184610Salfred	/*
2355184610Salfred	 * If we have a non-hardware induced error we
2356184610Salfred	 * need to do the DMA delay!
2357184610Salfred	 */
2358184610Salfred	if (((xfer->error == USB_ERR_CANCELLED) ||
2359184610Salfred	    (xfer->error == USB_ERR_TIMEOUT)) &&
2360184610Salfred	    (!xfer->flags_int.did_dma_delay)) {
2361184610Salfred
2362190181Sthompsa		usb2_timeout_t temp;
2363184610Salfred
2364184610Salfred		/* only delay once */
2365184610Salfred		xfer->flags_int.did_dma_delay = 1;
2366184610Salfred
2367184610Salfred		/* we can not cancel this delay */
2368184610Salfred		xfer->flags_int.can_cancel_immed = 0;
2369184610Salfred
2370187173Sthompsa		temp = usb2_get_dma_delay(xfer->xroot->bus);
2371184610Salfred
2372184610Salfred		DPRINTFN(3, "DMA delay, %u ms, "
2373184610Salfred		    "on %p\n", temp, xfer);
2374184610Salfred
2375184610Salfred		if (temp != 0) {
2376187173Sthompsa			USB_BUS_LOCK(xfer->xroot->bus);
2377184610Salfred			usb2_transfer_timeout_ms(xfer,
2378184610Salfred			    &usb2_dma_delay_done_cb, temp);
2379187173Sthompsa			USB_BUS_UNLOCK(xfer->xroot->bus);
2380184610Salfred			return (1);	/* wait for new callback */
2381184610Salfred		}
2382184610Salfred	}
2383184610Salfred	/* check actual number of frames */
2384184610Salfred	if (xfer->aframes > xfer->nframes) {
2385184610Salfred		if (xfer->error == 0) {
2386184610Salfred			panic("%s: actual number of frames, %d, is "
2387184610Salfred			    "greater than initial number of frames, %d!\n",
2388184610Salfred			    __FUNCTION__, xfer->aframes, xfer->nframes);
2389184610Salfred		} else {
2390184610Salfred			/* just set some valid value */
2391184610Salfred			xfer->aframes = xfer->nframes;
2392184610Salfred		}
2393184610Salfred	}
2394184610Salfred	/* compute actual length */
2395184610Salfred	xfer->actlen = 0;
2396184610Salfred
2397184610Salfred	for (x = 0; x != xfer->aframes; x++) {
2398184610Salfred		xfer->actlen += xfer->frlengths[x];
2399184610Salfred	}
2400184610Salfred
2401184610Salfred	/*
2402184610Salfred	 * Frames that were not transferred get zero actual length in
2403184610Salfred	 * case the USB device driver does not check the actual number
2404184610Salfred	 * of frames transferred, "xfer->aframes":
2405184610Salfred	 */
2406184610Salfred	for (; x < xfer->nframes; x++) {
2407184610Salfred		xfer->frlengths[x] = 0;
2408184610Salfred	}
2409184610Salfred
2410184610Salfred	/* check actual length */
2411184610Salfred	if (xfer->actlen > xfer->sumlen) {
2412184610Salfred		if (xfer->error == 0) {
2413184610Salfred			panic("%s: actual length, %d, is greater than "
2414184610Salfred			    "initial length, %d!\n",
2415184610Salfred			    __FUNCTION__, xfer->actlen, xfer->sumlen);
2416184610Salfred		} else {
2417184610Salfred			/* just set some valid value */
2418184610Salfred			xfer->actlen = xfer->sumlen;
2419184610Salfred		}
2420184610Salfred	}
2421184610Salfred	DPRINTFN(6, "xfer=%p pipe=%p sts=%d alen=%d, slen=%d, afrm=%d, nfrm=%d\n",
2422184610Salfred	    xfer, xfer->pipe, xfer->error, xfer->actlen, xfer->sumlen,
2423184610Salfred	    xfer->aframes, xfer->nframes);
2424184610Salfred
2425184610Salfred	if (xfer->error) {
2426184610Salfred		/* end of control transfer, if any */
2427184610Salfred		xfer->flags_int.control_act = 0;
2428184610Salfred
2429184610Salfred		/* check if we should block the execution queue */
2430184610Salfred		if ((xfer->error != USB_ERR_CANCELLED) &&
2431184610Salfred		    (xfer->flags.pipe_bof)) {
2432184610Salfred			DPRINTFN(2, "xfer=%p: Block On Failure "
2433184610Salfred			    "on pipe=%p\n", xfer, xfer->pipe);
2434184610Salfred			goto done;
2435184610Salfred		}
2436184610Salfred	} else {
2437184610Salfred		/* check for short transfers */
2438184610Salfred		if (xfer->actlen < xfer->sumlen) {
2439184610Salfred
2440184610Salfred			/* end of control transfer, if any */
2441184610Salfred			xfer->flags_int.control_act = 0;
2442184610Salfred
2443184610Salfred			if (!xfer->flags_int.short_xfer_ok) {
2444184610Salfred				xfer->error = USB_ERR_SHORT_XFER;
2445184610Salfred				if (xfer->flags.pipe_bof) {
2446184610Salfred					DPRINTFN(2, "xfer=%p: Block On Failure on "
2447184610Salfred					    "Short Transfer on pipe %p.\n",
2448184610Salfred					    xfer, xfer->pipe);
2449184610Salfred					goto done;
2450184610Salfred				}
2451184610Salfred			}
2452184610Salfred		} else {
2453184610Salfred			/*
2454184610Salfred			 * Check if we are in the middle of a
2455184610Salfred			 * control transfer:
2456184610Salfred			 */
2457184610Salfred			if (xfer->flags_int.control_act) {
2458184610Salfred				DPRINTFN(5, "xfer=%p: Control transfer "
2459184610Salfred				    "active on pipe=%p\n", xfer, xfer->pipe);
2460184610Salfred				goto done;
2461184610Salfred			}
2462184610Salfred		}
2463184610Salfred	}
2464184610Salfred
2465184610Salfred	pipe = xfer->pipe;
2466184610Salfred
2467184610Salfred	/*
2468184610Salfred	 * If the current USB transfer is completing we need to start the
2469184610Salfred	 * next one:
2470184610Salfred	 */
2471187173Sthompsa	USB_BUS_LOCK(xfer->xroot->bus);
2472184610Salfred	if (pipe->pipe_q.curr == xfer) {
2473184610Salfred		usb2_command_wrapper(&pipe->pipe_q, NULL);
2474184610Salfred
2475184610Salfred		if (pipe->pipe_q.curr || TAILQ_FIRST(&pipe->pipe_q.head)) {
2476184610Salfred			/* there is another USB transfer waiting */
2477184610Salfred		} else {
2478184610Salfred			/* this is the last USB transfer */
2479184610Salfred			/* clear isochronous sync flag */
2480184610Salfred			xfer->pipe->is_synced = 0;
2481184610Salfred		}
2482184610Salfred	}
2483187173Sthompsa	USB_BUS_UNLOCK(xfer->xroot->bus);
2484184610Salfreddone:
2485184610Salfred	return (0);
2486184610Salfred}
2487184610Salfred
2488184610Salfred/*------------------------------------------------------------------------*
2489184610Salfred *	usb2_command_wrapper
2490184610Salfred *
2491184610Salfred * This function is used to execute commands non-recursivly on an USB
2492184610Salfred * transfer.
2493184610Salfred *------------------------------------------------------------------------*/
2494184610Salfredvoid
2495184610Salfredusb2_command_wrapper(struct usb2_xfer_queue *pq, struct usb2_xfer *xfer)
2496184610Salfred{
2497184610Salfred	if (xfer) {
2498184610Salfred		/*
2499184610Salfred		 * If the transfer is not already processing,
2500184610Salfred		 * queue it!
2501184610Salfred		 */
2502184610Salfred		if (pq->curr != xfer) {
2503184610Salfred			usb2_transfer_enqueue(pq, xfer);
2504184610Salfred			if (pq->curr != NULL) {
2505184610Salfred				/* something is already processing */
2506184610Salfred				DPRINTFN(6, "busy %p\n", pq->curr);
2507184610Salfred				return;
2508184610Salfred			}
2509184610Salfred		}
2510184610Salfred	} else {
2511184610Salfred		/* Get next element in queue */
2512184610Salfred		pq->curr = NULL;
2513184610Salfred	}
2514184610Salfred
2515184610Salfred	if (!pq->recurse_1) {
2516184610Salfred
2517184610Salfred		do {
2518184610Salfred
2519184610Salfred			/* set both recurse flags */
2520184610Salfred			pq->recurse_1 = 1;
2521184610Salfred			pq->recurse_2 = 1;
2522184610Salfred
2523184610Salfred			if (pq->curr == NULL) {
2524184610Salfred				xfer = TAILQ_FIRST(&pq->head);
2525184610Salfred				if (xfer) {
2526184610Salfred					TAILQ_REMOVE(&pq->head, xfer,
2527184610Salfred					    wait_entry);
2528184610Salfred					xfer->wait_queue = NULL;
2529184610Salfred					pq->curr = xfer;
2530184610Salfred				} else {
2531184610Salfred					break;
2532184610Salfred				}
2533184610Salfred			}
2534184610Salfred			DPRINTFN(6, "cb %p (enter)\n", pq->curr);
2535184610Salfred			(pq->command) (pq);
2536184610Salfred			DPRINTFN(6, "cb %p (leave)\n", pq->curr);
2537184610Salfred
2538184610Salfred		} while (!pq->recurse_2);
2539184610Salfred
2540184610Salfred		/* clear first recurse flag */
2541184610Salfred		pq->recurse_1 = 0;
2542184610Salfred
2543184610Salfred	} else {
2544184610Salfred		/* clear second recurse flag */
2545184610Salfred		pq->recurse_2 = 0;
2546184610Salfred	}
2547184610Salfred}
2548184610Salfred
2549184610Salfred/*------------------------------------------------------------------------*
2550184610Salfred *	usb2_default_transfer_setup
2551184610Salfred *
2552184610Salfred * This function is used to setup the default USB control endpoint
2553184610Salfred * transfer.
2554184610Salfred *------------------------------------------------------------------------*/
2555184610Salfredvoid
2556184610Salfredusb2_default_transfer_setup(struct usb2_device *udev)
2557184610Salfred{
2558184610Salfred	struct usb2_xfer *xfer;
2559184610Salfred	uint8_t no_resetup;
2560184610Salfred	uint8_t iface_index;
2561184610Salfred
2562190735Sthompsa	/* check for root HUB */
2563190735Sthompsa	if (udev->parent_hub == NULL)
2564190735Sthompsa		return;
2565184610Salfredrepeat:
2566184610Salfred
2567184610Salfred	xfer = udev->default_xfer[0];
2568184610Salfred	if (xfer) {
2569184824Sthompsa		USB_XFER_LOCK(xfer);
2570184610Salfred		no_resetup =
2571184610Salfred		    ((xfer->address == udev->address) &&
2572184610Salfred		    (udev->default_ep_desc.wMaxPacketSize[0] ==
2573184610Salfred		    udev->ddesc.bMaxPacketSize));
2574184610Salfred		if (udev->flags.usb2_mode == USB_MODE_DEVICE) {
2575184610Salfred			if (no_resetup) {
2576184610Salfred				/*
2577184610Salfred				 * NOTE: checking "xfer->address" and
2578184610Salfred				 * starting the USB transfer must be
2579184610Salfred				 * atomic!
2580184610Salfred				 */
2581184610Salfred				usb2_transfer_start(xfer);
2582184610Salfred			}
2583184610Salfred		}
2584184824Sthompsa		USB_XFER_UNLOCK(xfer);
2585184610Salfred	} else {
2586184610Salfred		no_resetup = 0;
2587184610Salfred	}
2588184610Salfred
2589184610Salfred	if (no_resetup) {
2590184610Salfred		/*
2591184610Salfred	         * All parameters are exactly the same like before.
2592184610Salfred	         * Just return.
2593184610Salfred	         */
2594184610Salfred		return;
2595184610Salfred	}
2596184610Salfred	/*
2597184610Salfred	 * Update wMaxPacketSize for the default control endpoint:
2598184610Salfred	 */
2599184610Salfred	udev->default_ep_desc.wMaxPacketSize[0] =
2600184610Salfred	    udev->ddesc.bMaxPacketSize;
2601184610Salfred
2602184610Salfred	/*
2603184610Salfred	 * Unsetup any existing USB transfer:
2604184610Salfred	 */
2605184610Salfred	usb2_transfer_unsetup(udev->default_xfer, USB_DEFAULT_XFER_MAX);
2606184610Salfred
2607184610Salfred	/*
2608184610Salfred	 * Try to setup a new USB transfer for the
2609184610Salfred	 * default control endpoint:
2610184610Salfred	 */
2611184610Salfred	iface_index = 0;
2612184610Salfred	if (usb2_transfer_setup(udev, &iface_index,
2613184610Salfred	    udev->default_xfer, usb2_control_ep_cfg, USB_DEFAULT_XFER_MAX, NULL,
2614184610Salfred	    udev->default_mtx)) {
2615184610Salfred		DPRINTFN(0, "could not setup default "
2616184610Salfred		    "USB transfer!\n");
2617184610Salfred	} else {
2618184610Salfred		goto repeat;
2619184610Salfred	}
2620184610Salfred}
2621184610Salfred
2622184610Salfred/*------------------------------------------------------------------------*
2623184610Salfred *	usb2_clear_data_toggle - factored out code
2624184610Salfred *
2625184610Salfred * NOTE: the intention of this function is not to reset the hardware
2626184610Salfred * data toggle.
2627184610Salfred *------------------------------------------------------------------------*/
2628184610Salfredvoid
2629184610Salfredusb2_clear_data_toggle(struct usb2_device *udev, struct usb2_pipe *pipe)
2630184610Salfred{
2631184610Salfred	DPRINTFN(5, "udev=%p pipe=%p\n", udev, pipe);
2632184610Salfred
2633184824Sthompsa	USB_BUS_LOCK(udev->bus);
2634184610Salfred	pipe->toggle_next = 0;
2635184824Sthompsa	USB_BUS_UNLOCK(udev->bus);
2636184610Salfred}
2637184610Salfred
2638184610Salfred/*------------------------------------------------------------------------*
2639184610Salfred *	usb2_clear_stall_callback - factored out clear stall callback
2640184610Salfred *
2641184610Salfred * Input parameters:
2642184610Salfred *  xfer1: Clear Stall Control Transfer
2643184610Salfred *  xfer2: Stalled USB Transfer
2644184610Salfred *
2645184610Salfred * This function is NULL safe.
2646184610Salfred *
2647184610Salfred * Return values:
2648184610Salfred *   0: In progress
2649184610Salfred *   Else: Finished
2650184610Salfred *
2651184610Salfred * Clear stall config example:
2652184610Salfred *
2653184610Salfred * static const struct usb2_config my_clearstall =  {
2654184610Salfred *	.type = UE_CONTROL,
2655184610Salfred *	.endpoint = 0,
2656184610Salfred *	.direction = UE_DIR_ANY,
2657184610Salfred *	.interval = 50, //50 milliseconds
2658184610Salfred *	.bufsize = sizeof(struct usb2_device_request),
2659190734Sthompsa *	.timeout = 1000, //1.000 seconds
2660190734Sthompsa *	.callback = &my_clear_stall_callback, // **
2661190734Sthompsa *	.usb_mode = USB_MODE_HOST,
2662184610Salfred * };
2663184610Salfred *
2664184610Salfred * ** "my_clear_stall_callback" calls "usb2_clear_stall_callback"
2665184610Salfred * passing the correct parameters.
2666184610Salfred *------------------------------------------------------------------------*/
2667184610Salfreduint8_t
2668184610Salfredusb2_clear_stall_callback(struct usb2_xfer *xfer1,
2669184610Salfred    struct usb2_xfer *xfer2)
2670184610Salfred{
2671184610Salfred	struct usb2_device_request req;
2672184610Salfred
2673184610Salfred	if (xfer2 == NULL) {
2674184610Salfred		/* looks like we are tearing down */
2675184610Salfred		DPRINTF("NULL input parameter\n");
2676184610Salfred		return (0);
2677184610Salfred	}
2678184824Sthompsa	USB_XFER_LOCK_ASSERT(xfer1, MA_OWNED);
2679184824Sthompsa	USB_XFER_LOCK_ASSERT(xfer2, MA_OWNED);
2680184610Salfred
2681184610Salfred	switch (USB_GET_STATE(xfer1)) {
2682184610Salfred	case USB_ST_SETUP:
2683184610Salfred
2684184610Salfred		/*
2685184610Salfred		 * pre-clear the data toggle to DATA0 ("umass.c" and
2686184610Salfred		 * "ata-usb.c" depends on this)
2687184610Salfred		 */
2688184610Salfred
2689187173Sthompsa		usb2_clear_data_toggle(xfer2->xroot->udev, xfer2->pipe);
2690184610Salfred
2691184610Salfred		/* setup a clear-stall packet */
2692184610Salfred
2693184610Salfred		req.bmRequestType = UT_WRITE_ENDPOINT;
2694184610Salfred		req.bRequest = UR_CLEAR_FEATURE;
2695184610Salfred		USETW(req.wValue, UF_ENDPOINT_HALT);
2696184610Salfred		req.wIndex[0] = xfer2->pipe->edesc->bEndpointAddress;
2697184610Salfred		req.wIndex[1] = 0;
2698184610Salfred		USETW(req.wLength, 0);
2699184610Salfred
2700184610Salfred		/*
2701184610Salfred		 * "usb2_transfer_setup_sub()" will ensure that
2702184610Salfred		 * we have sufficient room in the buffer for
2703184610Salfred		 * the request structure!
2704184610Salfred		 */
2705184610Salfred
2706184610Salfred		/* copy in the transfer */
2707184610Salfred
2708184610Salfred		usb2_copy_in(xfer1->frbuffers, 0, &req, sizeof(req));
2709184610Salfred
2710184610Salfred		/* set length */
2711184610Salfred		xfer1->frlengths[0] = sizeof(req);
2712184610Salfred		xfer1->nframes = 1;
2713184610Salfred
2714184610Salfred		usb2_start_hardware(xfer1);
2715184610Salfred		return (0);
2716184610Salfred
2717184610Salfred	case USB_ST_TRANSFERRED:
2718184610Salfred		break;
2719184610Salfred
2720184610Salfred	default:			/* Error */
2721184610Salfred		if (xfer1->error == USB_ERR_CANCELLED) {
2722184610Salfred			return (0);
2723184610Salfred		}
2724184610Salfred		break;
2725184610Salfred	}
2726184610Salfred	return (1);			/* Clear Stall Finished */
2727184610Salfred}
2728184610Salfred
2729184610Salfredvoid
2730184610Salfredusb2_do_poll(struct usb2_xfer **ppxfer, uint16_t max)
2731184610Salfred{
2732188983Sthompsa	static uint8_t once = 0;
2733188983Sthompsa	/* polling is currently not supported */
2734188983Sthompsa	if (!once) {
2735188983Sthompsa		once = 1;
2736188983Sthompsa		printf("usb2_do_poll: USB polling is "
2737188983Sthompsa		    "not supported!\n");
2738184610Salfred	}
2739184610Salfred}
2740190734Sthompsa
2741190734Sthompsastatic void
2742190734Sthompsausb2_get_std_packet_size(struct usb2_std_packet_size *ptr,
2743190734Sthompsa    uint8_t type, uint8_t usb_speed)
2744190734Sthompsa{
2745190734Sthompsa	static const uint16_t intr_range_max[USB_SPEED_MAX] = {
2746190734Sthompsa		[USB_SPEED_LOW] = 8,
2747190734Sthompsa		[USB_SPEED_FULL] = 64,
2748190734Sthompsa		[USB_SPEED_HIGH] = 1024,
2749190734Sthompsa		[USB_SPEED_VARIABLE] = 1024,
2750190734Sthompsa		[USB_SPEED_SUPER] = 1024,
2751190734Sthompsa	};
2752190734Sthompsa
2753190734Sthompsa	static const uint16_t isoc_range_max[USB_SPEED_MAX] = {
2754190734Sthompsa		[USB_SPEED_LOW] = 0,	/* invalid */
2755190734Sthompsa		[USB_SPEED_FULL] = 1023,
2756190734Sthompsa		[USB_SPEED_HIGH] = 1024,
2757190734Sthompsa		[USB_SPEED_VARIABLE] = 3584,
2758190734Sthompsa		[USB_SPEED_SUPER] = 1024,
2759190734Sthompsa	};
2760190734Sthompsa
2761190734Sthompsa	static const uint16_t control_min[USB_SPEED_MAX] = {
2762190734Sthompsa		[USB_SPEED_LOW] = 8,
2763190734Sthompsa		[USB_SPEED_FULL] = 8,
2764190734Sthompsa		[USB_SPEED_HIGH] = 64,
2765190734Sthompsa		[USB_SPEED_VARIABLE] = 512,
2766190734Sthompsa		[USB_SPEED_SUPER] = 512,
2767190734Sthompsa	};
2768190734Sthompsa
2769190734Sthompsa	static const uint16_t bulk_min[USB_SPEED_MAX] = {
2770190734Sthompsa		[USB_SPEED_LOW] = 0,	/* not supported */
2771190734Sthompsa		[USB_SPEED_FULL] = 8,
2772190734Sthompsa		[USB_SPEED_HIGH] = 512,
2773190734Sthompsa		[USB_SPEED_VARIABLE] = 512,
2774190734Sthompsa		[USB_SPEED_SUPER] = 1024,
2775190734Sthompsa	};
2776190734Sthompsa
2777190734Sthompsa	uint16_t temp;
2778190734Sthompsa
2779190734Sthompsa	memset(ptr, 0, sizeof(*ptr));
2780190734Sthompsa
2781190734Sthompsa	switch (type) {
2782190734Sthompsa	case UE_INTERRUPT:
2783190734Sthompsa		ptr->range.max = intr_range_max[usb_speed];
2784190734Sthompsa		break;
2785190734Sthompsa	case UE_ISOCHRONOUS:
2786190734Sthompsa		ptr->range.max = isoc_range_max[usb_speed];
2787190734Sthompsa		break;
2788190734Sthompsa	default:
2789190734Sthompsa		if (type == UE_BULK)
2790190734Sthompsa			temp = bulk_min[usb_speed];
2791190734Sthompsa		else /* UE_CONTROL */
2792190734Sthompsa			temp = control_min[usb_speed];
2793190734Sthompsa
2794190734Sthompsa		/* default is fixed */
2795190734Sthompsa		ptr->fixed[0] = temp;
2796190734Sthompsa		ptr->fixed[1] = temp;
2797190734Sthompsa		ptr->fixed[2] = temp;
2798190734Sthompsa		ptr->fixed[3] = temp;
2799190734Sthompsa
2800190734Sthompsa		if (usb_speed == USB_SPEED_FULL) {
2801190734Sthompsa			/* multiple sizes */
2802190734Sthompsa			ptr->fixed[1] = 16;
2803190734Sthompsa			ptr->fixed[2] = 32;
2804190734Sthompsa			ptr->fixed[3] = 64;
2805190734Sthompsa		}
2806190734Sthompsa		if ((usb_speed == USB_SPEED_VARIABLE) &&
2807190734Sthompsa		    (type == UE_BULK)) {
2808190734Sthompsa			/* multiple sizes */
2809190734Sthompsa			ptr->fixed[2] = 1024;
2810190734Sthompsa			ptr->fixed[3] = 1536;
2811190734Sthompsa		}
2812190734Sthompsa		break;
2813190734Sthompsa	}
2814190734Sthompsa}
2815