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