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