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