1/*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include "implementation/global_implementation.h"
29
30/* function prototypes */
31
32static uint8_t usb_handle_get_stall(struct usb_device *, uint8_t);
33static usb_error_t	 usb_handle_remote_wakeup(struct usb_xfer *, uint8_t);
34static usb_error_t	 usb_handle_request(struct usb_xfer *);
35static usb_error_t	 usb_handle_set_config(struct usb_xfer *, uint8_t);
36static usb_error_t	 usb_handle_set_stall(struct usb_xfer *, uint8_t,
37			    uint8_t);
38static usb_error_t	 usb_handle_iface_request(struct usb_xfer *, void **,
39			    uint16_t *, struct usb_device_request, uint16_t,
40			    uint8_t);
41
42/*------------------------------------------------------------------------*
43 *	usb_handle_request_callback
44 *
45 * This function is the USB callback for generic USB Device control
46 * transfers.
47 *------------------------------------------------------------------------*/
48void
49usb_handle_request_callback(struct usb_xfer *xfer, usb_error_t error)
50{
51	usb_error_t err;
52
53	/* check the current transfer state */
54
55	switch (USB_GET_STATE(xfer)) {
56	case USB_ST_SETUP:
57	case USB_ST_TRANSFERRED:
58
59		/* handle the request */
60		err = usb_handle_request(xfer);
61
62		if (err) {
63			if (err == USB_ERR_BAD_CONTEXT) {
64				/* we need to re-setup the control transfer */
65				usb_needs_explore(xfer->xroot->bus, 0);
66				break;
67			}
68			goto tr_restart;
69		}
70		usbd_transfer_submit(xfer);
71		break;
72
73	default:
74		/* check if a control transfer is active */
75		if (xfer->flags_int.control_rem != 0xFFFF) {
76			/* handle the request */
77			(void)usb_handle_request(xfer);
78		}
79		if (xfer->error != USB_ERR_CANCELLED) {
80			/* should not happen - try stalling */
81			goto tr_restart;
82		}
83		break;
84	}
85	return;
86
87tr_restart:
88	/*
89	 * If a control transfer is active, stall it, and wait for the
90	 * next control transfer.
91	 */
92	usbd_xfer_set_frame_len(xfer, 0, sizeof(struct usb_device_request));
93	xfer->nframes = 1;
94	xfer->flags.manual_status = 1;
95	xfer->flags.force_short_xfer = 0;
96	usbd_xfer_set_stall(xfer);	/* cancel previous transfer, if any */
97	usbd_transfer_submit(xfer);
98}
99
100/*------------------------------------------------------------------------*
101 *	usb_handle_set_config
102 *
103 * Returns:
104 *    0: Success
105 * Else: Failure
106 *------------------------------------------------------------------------*/
107static usb_error_t
108usb_handle_set_config(struct usb_xfer *xfer, uint8_t conf_no)
109{
110	struct usb_device *udev = xfer->xroot->udev;
111	usb_error_t err = USB_ERR_NORMAL_COMPLETION;
112	uint8_t do_unlock;
113
114	/*
115	 * We need to protect against other threads doing probe and
116	 * attach:
117	 */
118	USB_XFER_UNLOCK(xfer);
119
120	/* Prevent re-enumeration */
121	do_unlock = usbd_enum_lock(udev);
122
123	if (conf_no == USB_UNCONFIG_NO) {
124		conf_no = USB_UNCONFIG_INDEX;
125	} else {
126		/*
127		 * The relationship between config number and config index
128		 * is very simple in our case:
129		 */
130		conf_no--;
131	}
132
133	if (usbd_set_config_index(udev, conf_no)) {
134		DPRINTF("set config %d failed\n", conf_no);
135		err = USB_ERR_STALLED;
136		goto done;
137	}
138	if (usb_probe_and_attach(udev, USB_IFACE_INDEX_ANY)) {
139		DPRINTF("probe and attach failed\n");
140		err = USB_ERR_STALLED;
141		goto done;
142	}
143done:
144	if (do_unlock)
145		usbd_enum_unlock(udev);
146	USB_XFER_LOCK(xfer);
147	return (err);
148}
149
150static usb_error_t
151usb_check_alt_setting(struct usb_device *udev,
152    struct usb_interface *iface, uint8_t alt_index)
153{
154	uint8_t do_unlock;
155	usb_error_t err = USB_ERR_NORMAL_COMPLETION;
156
157	/* Prevent re-enumeration */
158	do_unlock = usbd_enum_lock(udev);
159
160	if (alt_index >= usbd_get_no_alts(udev->cdesc, iface->idesc))
161		err = USB_ERR_INVAL;
162
163	if (do_unlock)
164		usbd_enum_unlock(udev);
165
166	return (err);
167}
168
169/*------------------------------------------------------------------------*
170 *	usb_handle_iface_request
171 *
172 * Returns:
173 *    0: Success
174 * Else: Failure
175 *------------------------------------------------------------------------*/
176static usb_error_t
177usb_handle_iface_request(struct usb_xfer *xfer,
178    void **ppdata, uint16_t *plen,
179    struct usb_device_request req, uint16_t off, uint8_t state)
180{
181	struct usb_interface *iface;
182	struct usb_interface *iface_parent;	/* parent interface */
183	struct usb_device *udev = xfer->xroot->udev;
184	int error;
185	uint8_t iface_index;
186	uint8_t temp_state;
187	uint8_t do_unlock;
188
189	if ((req.bmRequestType & 0x1F) == UT_INTERFACE) {
190		iface_index = req.wIndex[0];	/* unicast */
191	} else {
192		iface_index = 0;	/* broadcast */
193	}
194
195	/*
196	 * We need to protect against other threads doing probe and
197	 * attach:
198	 */
199	USB_XFER_UNLOCK(xfer);
200
201	/* Prevent re-enumeration */
202	do_unlock = usbd_enum_lock(udev);
203
204	error = ENXIO;
205
206tr_repeat:
207	iface = usbd_get_iface(udev, iface_index);
208	if ((iface == NULL) ||
209	    (iface->idesc == NULL)) {
210		/* end of interfaces non-existing interface */
211		goto tr_stalled;
212	}
213	/* set initial state */
214
215	temp_state = state;
216
217	/* forward request to interface, if any */
218
219	if ((error != 0) &&
220	    (error != ENOTTY) &&
221	    (iface->subdev != NULL) &&
222	    device_is_attached(iface->subdev)) {
223		error = USB_HANDLE_REQUEST(iface->subdev,
224		    &req, ppdata, plen,
225		    off, &temp_state);
226	}
227	iface_parent = usbd_get_iface(udev, iface->parent_iface_index);
228
229	if ((iface_parent == NULL) ||
230	    (iface_parent->idesc == NULL)) {
231		/* non-existing interface */
232		iface_parent = NULL;
233	}
234	/* forward request to parent interface, if any */
235
236	if ((error != 0) &&
237	    (error != ENOTTY) &&
238	    (iface_parent != NULL) &&
239	    (iface_parent->subdev != NULL) &&
240	    ((req.bmRequestType & 0x1F) == UT_INTERFACE) &&
241	    (iface_parent->subdev != iface->subdev) &&
242	    device_is_attached(iface_parent->subdev)) {
243		error = USB_HANDLE_REQUEST(iface_parent->subdev,
244		    &req, ppdata, plen, off, &temp_state);
245	}
246	if (error == 0) {
247		/* negativly adjust pointer and length */
248		*ppdata = ((uint8_t *)(*ppdata)) - off;
249		*plen += off;
250
251		if ((state == USB_HR_NOT_COMPLETE) &&
252		    (temp_state == USB_HR_COMPLETE_OK))
253			goto tr_short;
254		else
255			goto tr_valid;
256	} else if (error == ENOTTY) {
257		goto tr_stalled;
258	}
259	if ((req.bmRequestType & 0x1F) != UT_INTERFACE) {
260		iface_index++;		/* iterate */
261		goto tr_repeat;
262	}
263	if (state != USB_HR_NOT_COMPLETE) {
264		/* we are complete */
265		goto tr_valid;
266	}
267	switch (req.bmRequestType) {
268	case UT_WRITE_INTERFACE:
269		switch (req.bRequest) {
270		case UR_SET_INTERFACE:
271			/*
272			 * We assume that the endpoints are the same
273			 * across the alternate settings.
274			 *
275			 * Reset the endpoints, because re-attaching
276			 * only a part of the device is not possible.
277			 */
278			error = usb_check_alt_setting(udev,
279			    iface, req.wValue[0]);
280			if (error) {
281				DPRINTF("alt setting does not exist %s\n",
282				    usbd_errstr(error));
283				goto tr_stalled;
284			}
285			error = usb_reset_iface_endpoints(udev, iface_index);
286			if (error) {
287				DPRINTF("alt setting failed %s\n",
288				    usbd_errstr(error));
289				goto tr_stalled;
290			}
291			/* update the current alternate setting */
292			iface->alt_index = req.wValue[0];
293			break;
294
295		default:
296			goto tr_stalled;
297		}
298		break;
299
300	case UT_READ_INTERFACE:
301		switch (req.bRequest) {
302		case UR_GET_INTERFACE:
303			*ppdata = &iface->alt_index;
304			*plen = 1;
305			break;
306
307		default:
308			goto tr_stalled;
309		}
310		break;
311	default:
312		goto tr_stalled;
313	}
314tr_valid:
315	if (do_unlock)
316		usbd_enum_unlock(udev);
317	USB_XFER_LOCK(xfer);
318	return (USB_ERR_NORMAL_COMPLETION);
319
320tr_short:
321	if (do_unlock)
322		usbd_enum_unlock(udev);
323	USB_XFER_LOCK(xfer);
324	return (USB_ERR_SHORT_XFER);
325
326tr_stalled:
327	if (do_unlock)
328		usbd_enum_unlock(udev);
329	USB_XFER_LOCK(xfer);
330	return (USB_ERR_STALLED);
331}
332
333/*------------------------------------------------------------------------*
334 *	usb_handle_stall
335 *
336 * Returns:
337 *    0: Success
338 * Else: Failure
339 *------------------------------------------------------------------------*/
340static usb_error_t
341usb_handle_set_stall(struct usb_xfer *xfer, uint8_t ep, uint8_t do_stall)
342{
343	struct usb_device *udev = xfer->xroot->udev;
344	usb_error_t err;
345
346	USB_XFER_UNLOCK(xfer);
347	err = usbd_set_endpoint_stall(udev,
348	    usbd_get_ep_by_addr(udev, ep), do_stall);
349	USB_XFER_LOCK(xfer);
350	return (err);
351}
352
353/*------------------------------------------------------------------------*
354 *	usb_handle_get_stall
355 *
356 * Returns:
357 *    0: Success
358 * Else: Failure
359 *------------------------------------------------------------------------*/
360static uint8_t
361usb_handle_get_stall(struct usb_device *udev, uint8_t ea_val)
362{
363	struct usb_endpoint *ep;
364	uint8_t halted;
365
366	ep = usbd_get_ep_by_addr(udev, ea_val);
367	if (ep == NULL) {
368		/* nothing to do */
369		return (0);
370	}
371	USB_BUS_LOCK(udev->bus);
372	halted = ep->is_stalled;
373	USB_BUS_UNLOCK(udev->bus);
374
375	return (halted);
376}
377
378/*------------------------------------------------------------------------*
379 *	usb_handle_remote_wakeup
380 *
381 * Returns:
382 *    0: Success
383 * Else: Failure
384 *------------------------------------------------------------------------*/
385static usb_error_t
386usb_handle_remote_wakeup(struct usb_xfer *xfer, uint8_t is_on)
387{
388	struct usb_device *udev;
389	struct usb_bus *bus;
390
391	udev = xfer->xroot->udev;
392	bus = udev->bus;
393
394	USB_BUS_LOCK(bus);
395
396	if (is_on) {
397		udev->flags.remote_wakeup = 1;
398	} else {
399		udev->flags.remote_wakeup = 0;
400	}
401
402	USB_BUS_UNLOCK(bus);
403
404#if USB_HAVE_POWERD
405	/* In case we are out of sync, update the power state. */
406	usb_bus_power_update(udev->bus);
407#endif
408	return (USB_ERR_NORMAL_COMPLETION);			/* success */
409}
410
411/*------------------------------------------------------------------------*
412 *	usb_handle_request
413 *
414 * Internal state sequence:
415 *
416 * USB_HR_NOT_COMPLETE -> USB_HR_COMPLETE_OK v USB_HR_COMPLETE_ERR
417 *
418 * Returns:
419 * 0: Ready to start hardware
420 * Else: Stall current transfer, if any
421 *------------------------------------------------------------------------*/
422static usb_error_t
423usb_handle_request(struct usb_xfer *xfer)
424{
425	struct usb_device_request req;
426	struct usb_device *udev;
427	const void *src_zcopy;		/* zero-copy source pointer */
428	const void *src_mcopy;		/* non zero-copy source pointer */
429	uint16_t off;			/* data offset */
430	uint16_t rem;			/* data remainder */
431	uint16_t max_len;		/* max fragment length */
432	uint16_t wValue;
433	uint8_t state;
434	uint8_t is_complete = 1;
435	usb_error_t err;
436	union {
437		uWord	wStatus;
438		uint8_t	buf[2];
439	} temp;
440
441	/*
442	 * Filter the USB transfer state into
443	 * something which we understand:
444	 */
445
446	switch (USB_GET_STATE(xfer)) {
447	case USB_ST_SETUP:
448		state = USB_HR_NOT_COMPLETE;
449
450		if (!xfer->flags_int.control_act) {
451			/* nothing to do */
452			goto tr_stalled;
453		}
454		break;
455	case USB_ST_TRANSFERRED:
456		if (!xfer->flags_int.control_act) {
457			state = USB_HR_COMPLETE_OK;
458		} else {
459			state = USB_HR_NOT_COMPLETE;
460		}
461		break;
462	default:
463		state = USB_HR_COMPLETE_ERR;
464		break;
465	}
466
467	/* reset frame stuff */
468
469	usbd_xfer_set_frame_len(xfer, 0, 0);
470
471	usbd_xfer_set_frame_offset(xfer, 0, 0);
472	usbd_xfer_set_frame_offset(xfer, sizeof(req), 1);
473
474	/* get the current request, if any */
475
476	usbd_copy_out(xfer->frbuffers, 0, &req, sizeof(req));
477
478	if (xfer->flags_int.control_rem == 0xFFFF) {
479		/* first time - not initialised */
480		rem = UGETW(req.wLength);
481		off = 0;
482	} else {
483		/* not first time - initialised */
484		rem = xfer->flags_int.control_rem;
485		off = UGETW(req.wLength) - rem;
486	}
487
488	/* set some defaults */
489
490	max_len = 0;
491	src_zcopy = NULL;
492	src_mcopy = NULL;
493	udev = xfer->xroot->udev;
494
495	/* get some request fields decoded */
496
497	wValue = UGETW(req.wValue);
498
499	DPRINTF("req 0x%02x 0x%02x 0x%04x 0x%04x "
500	    "off=0x%x rem=0x%x, state=%d\n", req.bmRequestType,
501	    req.bRequest, wValue, UGETW(req.wIndex), off, rem, state);
502
503	/* demultiplex the control request */
504
505	switch (req.bmRequestType) {
506	case UT_READ_DEVICE:
507		if (state != USB_HR_NOT_COMPLETE) {
508			break;
509		}
510		switch (req.bRequest) {
511		case UR_GET_DESCRIPTOR:
512			goto tr_handle_get_descriptor;
513		case UR_GET_CONFIG:
514			goto tr_handle_get_config;
515		case UR_GET_STATUS:
516			goto tr_handle_get_status;
517		default:
518			goto tr_stalled;
519		}
520		break;
521
522	case UT_WRITE_DEVICE:
523		switch (req.bRequest) {
524		case UR_SET_ADDRESS:
525			goto tr_handle_set_address;
526		case UR_SET_CONFIG:
527			goto tr_handle_set_config;
528		case UR_CLEAR_FEATURE:
529			switch (wValue) {
530			case UF_DEVICE_REMOTE_WAKEUP:
531				goto tr_handle_clear_wakeup;
532			default:
533				goto tr_stalled;
534			}
535			break;
536		case UR_SET_FEATURE:
537			switch (wValue) {
538			case UF_DEVICE_REMOTE_WAKEUP:
539				goto tr_handle_set_wakeup;
540			default:
541				goto tr_stalled;
542			}
543			break;
544		default:
545			goto tr_stalled;
546		}
547		break;
548
549	case UT_WRITE_ENDPOINT:
550		switch (req.bRequest) {
551		case UR_CLEAR_FEATURE:
552			switch (wValue) {
553			case UF_ENDPOINT_HALT:
554				goto tr_handle_clear_halt;
555			default:
556				goto tr_stalled;
557			}
558			break;
559		case UR_SET_FEATURE:
560			switch (wValue) {
561			case UF_ENDPOINT_HALT:
562				goto tr_handle_set_halt;
563			default:
564				goto tr_stalled;
565			}
566			break;
567		default:
568			goto tr_stalled;
569		}
570		break;
571
572	case UT_READ_ENDPOINT:
573		switch (req.bRequest) {
574		case UR_GET_STATUS:
575			goto tr_handle_get_ep_status;
576		default:
577			goto tr_stalled;
578		}
579		break;
580	default:
581		/* we use "USB_ADD_BYTES" to de-const the src_zcopy */
582		err = usb_handle_iface_request(xfer,
583		    USB_ADD_BYTES(&src_zcopy, 0),
584		    &max_len, req, off, state);
585		if (err == 0) {
586			is_complete = 0;
587			goto tr_valid;
588		} else if (err == USB_ERR_SHORT_XFER) {
589			goto tr_valid;
590		}
591		/*
592		 * Reset zero-copy pointer and max length
593		 * variable in case they were unintentionally
594		 * set:
595		 */
596		src_zcopy = NULL;
597		max_len = 0;
598
599		/*
600		 * Check if we have a vendor specific
601		 * descriptor:
602		 */
603		goto tr_handle_get_descriptor;
604	}
605	goto tr_valid;
606
607tr_handle_get_descriptor:
608	err = (usb_temp_get_desc_p) (udev, &req, &src_zcopy, &max_len);
609	if (err)
610		goto tr_stalled;
611	if (src_zcopy == NULL)
612		goto tr_stalled;
613	goto tr_valid;
614
615tr_handle_get_config:
616	temp.buf[0] = udev->curr_config_no;
617	src_mcopy = temp.buf;
618	max_len = 1;
619	goto tr_valid;
620
621tr_handle_get_status:
622
623	wValue = 0;
624
625	USB_BUS_LOCK(udev->bus);
626	if (udev->flags.remote_wakeup) {
627		wValue |= UDS_REMOTE_WAKEUP;
628	}
629	if (udev->flags.self_powered) {
630		wValue |= UDS_SELF_POWERED;
631	}
632	USB_BUS_UNLOCK(udev->bus);
633
634	USETW(temp.wStatus, wValue);
635	src_mcopy = temp.wStatus;
636	max_len = sizeof(temp.wStatus);
637	goto tr_valid;
638
639tr_handle_set_address:
640	if (state == USB_HR_NOT_COMPLETE) {
641		if (wValue >= 0x80) {
642			/* invalid value */
643			goto tr_stalled;
644		} else if (udev->curr_config_no != 0) {
645			/* we are configured ! */
646			goto tr_stalled;
647		}
648	} else if (state != USB_HR_NOT_COMPLETE) {
649		udev->address = (wValue & 0x7F);
650		goto tr_bad_context;
651	}
652	goto tr_valid;
653
654tr_handle_set_config:
655	if (state == USB_HR_NOT_COMPLETE) {
656		if (usb_handle_set_config(xfer, req.wValue[0])) {
657			goto tr_stalled;
658		}
659	}
660	goto tr_valid;
661
662tr_handle_clear_halt:
663	if (state == USB_HR_NOT_COMPLETE) {
664		if (usb_handle_set_stall(xfer, req.wIndex[0], 0)) {
665			goto tr_stalled;
666		}
667	}
668	goto tr_valid;
669
670tr_handle_clear_wakeup:
671	if (state == USB_HR_NOT_COMPLETE) {
672		if (usb_handle_remote_wakeup(xfer, 0)) {
673			goto tr_stalled;
674		}
675	}
676	goto tr_valid;
677
678tr_handle_set_halt:
679	if (state == USB_HR_NOT_COMPLETE) {
680		if (usb_handle_set_stall(xfer, req.wIndex[0], 1)) {
681			goto tr_stalled;
682		}
683	}
684	goto tr_valid;
685
686tr_handle_set_wakeup:
687	if (state == USB_HR_NOT_COMPLETE) {
688		if (usb_handle_remote_wakeup(xfer, 1)) {
689			goto tr_stalled;
690		}
691	}
692	goto tr_valid;
693
694tr_handle_get_ep_status:
695	if (state == USB_HR_NOT_COMPLETE) {
696		temp.wStatus[0] =
697		    usb_handle_get_stall(udev, req.wIndex[0]);
698		temp.wStatus[1] = 0;
699		src_mcopy = temp.wStatus;
700		max_len = sizeof(temp.wStatus);
701	}
702	goto tr_valid;
703
704tr_valid:
705	if (state != USB_HR_NOT_COMPLETE) {
706		goto tr_stalled;
707	}
708	/* subtract offset from length */
709
710	max_len -= off;
711
712	/* Compute the real maximum data length */
713
714	if (max_len > xfer->max_data_length) {
715		max_len = usbd_xfer_max_len(xfer);
716	}
717	if (max_len > rem) {
718		max_len = rem;
719	}
720	/*
721	 * If the remainder is greater than the maximum data length,
722	 * we need to truncate the value for the sake of the
723	 * comparison below:
724	 */
725	if (rem > xfer->max_data_length) {
726		rem = usbd_xfer_max_len(xfer);
727	}
728	if ((rem != max_len) && (is_complete != 0)) {
729		/*
730	         * If we don't transfer the data we can transfer, then
731	         * the transfer is short !
732	         */
733		xfer->flags.force_short_xfer = 1;
734		xfer->nframes = 2;
735	} else {
736		/*
737		 * Default case
738		 */
739		xfer->flags.force_short_xfer = 0;
740		xfer->nframes = max_len ? 2 : 1;
741	}
742	if (max_len > 0) {
743		if (src_mcopy) {
744			src_mcopy = USB_ADD_BYTES(src_mcopy, off);
745			usbd_copy_in(xfer->frbuffers + 1, 0,
746			    src_mcopy, max_len);
747			usbd_xfer_set_frame_len(xfer, 1, max_len);
748		} else {
749			usbd_xfer_set_frame_data(xfer, 1,
750			    USB_ADD_BYTES(src_zcopy, off), max_len);
751		}
752	} else {
753		/* the end is reached, send status */
754		xfer->flags.manual_status = 0;
755		usbd_xfer_set_frame_len(xfer, 1, 0);
756	}
757	DPRINTF("success\n");
758	return (USB_ERR_NORMAL_COMPLETION);			/* success */
759
760tr_stalled:
761	DPRINTF("%s\n", (state != USB_HR_NOT_COMPLETE) ?
762	    "complete" : "stalled");
763	return (USB_ERR_STALLED);
764
765tr_bad_context:
766	DPRINTF("bad context\n");
767	return (USB_ERR_BAD_CONTEXT);
768}
769