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