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