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