usb_handle_request.c revision 246616
1/* $FreeBSD: head/sys/dev/usb/usb_handle_request.c 246616 2013-02-10 10:56:13Z 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#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
71static uint8_t usb_handle_get_stall(struct usb_device *, uint8_t);
72static usb_error_t	 usb_handle_remote_wakeup(struct usb_xfer *, uint8_t);
73static usb_error_t	 usb_handle_request(struct usb_xfer *);
74static usb_error_t	 usb_handle_set_config(struct usb_xfer *, uint8_t);
75static usb_error_t	 usb_handle_set_stall(struct usb_xfer *, uint8_t,
76			    uint8_t);
77static 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 *------------------------------------------------------------------------*/
87void
88usb_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
127tr_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 *------------------------------------------------------------------------*/
147static usb_error_t
148usb_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	}
181done:
182	usbd_enum_unlock(udev);
183	USB_XFER_LOCK(xfer);
184	return (err);
185}
186
187static usb_error_t
188usb_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 *------------------------------------------------------------------------*/
213static usb_error_t
214usb_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
241tr_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	}
352tr_valid:
353	usbd_enum_unlock(udev);
354	USB_XFER_LOCK(xfer);
355	return (0);
356
357tr_short:
358	usbd_enum_unlock(udev);
359	USB_XFER_LOCK(xfer);
360	return (USB_ERR_SHORT_XFER);
361
362tr_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 *------------------------------------------------------------------------*/
375static usb_error_t
376usb_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 *------------------------------------------------------------------------*/
395static uint8_t
396usb_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 *------------------------------------------------------------------------*/
420static usb_error_t
421usb_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 *------------------------------------------------------------------------*/
457static usb_error_t
458usb_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
642tr_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
650tr_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
656tr_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
674tr_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
689tr_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
697tr_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
705tr_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
713tr_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
721tr_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
729tr_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
739tr_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
795tr_stalled:
796	DPRINTF("%s\n", (state != USB_HR_NOT_COMPLETE) ?
797	    "complete" : "stalled");
798	return (USB_ERR_STALLED);
799
800tr_bad_context:
801	DPRINTF("bad context\n");
802	return (USB_ERR_BAD_CONTEXT);
803}
804