usb_handle_request.c revision 233774
1/* $FreeBSD: head/sys/dev/usb/usb_handle_request.c 233774 2012-04-02 10:50:42Z 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/module.h>
36#include <sys/lock.h>
37#include <sys/mutex.h>
38#include <sys/condvar.h>
39#include <sys/sysctl.h>
40#include <sys/sx.h>
41#include <sys/unistd.h>
42#include <sys/callout.h>
43#include <sys/malloc.h>
44#include <sys/priv.h>
45
46#include <dev/usb/usb.h>
47#include <dev/usb/usbdi.h>
48#include <dev/usb/usbdi_util.h>
49#include "usb_if.h"
50
51#define	USB_DEBUG_VAR usb_debug
52
53#include <dev/usb/usb_core.h>
54#include <dev/usb/usb_process.h>
55#include <dev/usb/usb_busdma.h>
56#include <dev/usb/usb_transfer.h>
57#include <dev/usb/usb_device.h>
58#include <dev/usb/usb_debug.h>
59#include <dev/usb/usb_dynamic.h>
60#include <dev/usb/usb_hub.h>
61
62#include <dev/usb/usb_controller.h>
63#include <dev/usb/usb_bus.h>
64
65/* function prototypes */
66
67static uint8_t usb_handle_get_stall(struct usb_device *, uint8_t);
68static usb_error_t	 usb_handle_remote_wakeup(struct usb_xfer *, uint8_t);
69static usb_error_t	 usb_handle_request(struct usb_xfer *);
70static usb_error_t	 usb_handle_set_config(struct usb_xfer *, uint8_t);
71static usb_error_t	 usb_handle_set_stall(struct usb_xfer *, uint8_t,
72			    uint8_t);
73static usb_error_t	 usb_handle_iface_request(struct usb_xfer *, void **,
74			    uint16_t *, struct usb_device_request, uint16_t,
75			    uint8_t);
76
77/*------------------------------------------------------------------------*
78 *	usb_handle_request_callback
79 *
80 * This function is the USB callback for generic USB Device control
81 * transfers.
82 *------------------------------------------------------------------------*/
83void
84usb_handle_request_callback(struct usb_xfer *xfer, usb_error_t error)
85{
86	usb_error_t err;
87
88	/* check the current transfer state */
89
90	switch (USB_GET_STATE(xfer)) {
91	case USB_ST_SETUP:
92	case USB_ST_TRANSFERRED:
93
94		/* handle the request */
95		err = usb_handle_request(xfer);
96
97		if (err) {
98
99			if (err == USB_ERR_BAD_CONTEXT) {
100				/* we need to re-setup the control transfer */
101				usb_needs_explore(xfer->xroot->bus, 0);
102				break;
103			}
104			goto tr_restart;
105		}
106		usbd_transfer_submit(xfer);
107		break;
108
109	default:
110		/* check if a control transfer is active */
111		if (xfer->flags_int.control_rem != 0xFFFF) {
112			/* handle the request */
113			err = usb_handle_request(xfer);
114		}
115		if (xfer->error != USB_ERR_CANCELLED) {
116			/* should not happen - try stalling */
117			goto tr_restart;
118		}
119		break;
120	}
121	return;
122
123tr_restart:
124	/*
125	 * If a control transfer is active, stall it, and wait for the
126	 * next control transfer.
127	 */
128	usbd_xfer_set_frame_len(xfer, 0, sizeof(struct usb_device_request));
129	xfer->nframes = 1;
130	xfer->flags.manual_status = 1;
131	xfer->flags.force_short_xfer = 0;
132	usbd_xfer_set_stall(xfer);	/* cancel previous transfer, if any */
133	usbd_transfer_submit(xfer);
134}
135
136/*------------------------------------------------------------------------*
137 *	usb_handle_set_config
138 *
139 * Returns:
140 *    0: Success
141 * Else: Failure
142 *------------------------------------------------------------------------*/
143static usb_error_t
144usb_handle_set_config(struct usb_xfer *xfer, uint8_t conf_no)
145{
146	struct usb_device *udev = xfer->xroot->udev;
147	usb_error_t err = 0;
148
149	/*
150	 * We need to protect against other threads doing probe and
151	 * attach:
152	 */
153	USB_XFER_UNLOCK(xfer);
154
155	usbd_enum_lock(udev);
156
157	if (conf_no == USB_UNCONFIG_NO) {
158		conf_no = USB_UNCONFIG_INDEX;
159	} else {
160		/*
161		 * The relationship between config number and config index
162		 * is very simple in our case:
163		 */
164		conf_no--;
165	}
166
167	if (usbd_set_config_index(udev, conf_no)) {
168		DPRINTF("set config %d failed\n", conf_no);
169		err = USB_ERR_STALLED;
170		goto done;
171	}
172	if (usb_probe_and_attach(udev, USB_IFACE_INDEX_ANY)) {
173		DPRINTF("probe and attach failed\n");
174		err = USB_ERR_STALLED;
175		goto done;
176	}
177done:
178	usbd_enum_unlock(udev);
179	USB_XFER_LOCK(xfer);
180	return (err);
181}
182
183static usb_error_t
184usb_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	/* automatic locking */
191	if (usbd_enum_is_locked(udev)) {
192		do_unlock = 0;
193	} else {
194		do_unlock = 1;
195		usbd_enum_lock(udev);
196	}
197
198	if (alt_index >= usbd_get_no_alts(udev->cdesc, iface->idesc))
199		err = USB_ERR_INVAL;
200
201	if (do_unlock)
202		usbd_enum_unlock(udev);
203
204	return (err);
205}
206
207/*------------------------------------------------------------------------*
208 *	usb_handle_iface_request
209 *
210 * Returns:
211 *    0: Success
212 * Else: Failure
213 *------------------------------------------------------------------------*/
214static usb_error_t
215usb_handle_iface_request(struct usb_xfer *xfer,
216    void **ppdata, uint16_t *plen,
217    struct usb_device_request req, uint16_t off, uint8_t state)
218{
219	struct usb_interface *iface;
220	struct usb_interface *iface_parent;	/* parent interface */
221	struct usb_device *udev = xfer->xroot->udev;
222	int error;
223	uint8_t iface_index;
224	uint8_t temp_state;
225
226	if ((req.bmRequestType & 0x1F) == UT_INTERFACE) {
227		iface_index = req.wIndex[0];	/* unicast */
228	} else {
229		iface_index = 0;	/* broadcast */
230	}
231
232	/*
233	 * We need to protect against other threads doing probe and
234	 * attach:
235	 */
236	USB_XFER_UNLOCK(xfer);
237
238	usbd_enum_lock(udev);
239
240	error = ENXIO;
241
242tr_repeat:
243	iface = usbd_get_iface(udev, iface_index);
244	if ((iface == NULL) ||
245	    (iface->idesc == NULL)) {
246		/* end of interfaces non-existing interface */
247		goto tr_stalled;
248	}
249	/* set initial state */
250
251	temp_state = state;
252
253	/* forward request to interface, if any */
254
255	if ((error != 0) &&
256	    (error != ENOTTY) &&
257	    (iface->subdev != NULL) &&
258	    device_is_attached(iface->subdev)) {
259#if 0
260		DEVMETHOD(usb_handle_request, NULL);	/* dummy */
261#endif
262		error = USB_HANDLE_REQUEST(iface->subdev,
263		    &req, ppdata, plen,
264		    off, &temp_state);
265	}
266	iface_parent = usbd_get_iface(udev, iface->parent_iface_index);
267
268	if ((iface_parent == NULL) ||
269	    (iface_parent->idesc == NULL)) {
270		/* non-existing interface */
271		iface_parent = NULL;
272	}
273	/* forward request to parent interface, if any */
274
275	if ((error != 0) &&
276	    (error != ENOTTY) &&
277	    (iface_parent != NULL) &&
278	    (iface_parent->subdev != NULL) &&
279	    ((req.bmRequestType & 0x1F) == UT_INTERFACE) &&
280	    (iface_parent->subdev != iface->subdev) &&
281	    device_is_attached(iface_parent->subdev)) {
282		error = USB_HANDLE_REQUEST(iface_parent->subdev,
283		    &req, ppdata, plen, off, &temp_state);
284	}
285	if (error == 0) {
286		/* negativly adjust pointer and length */
287		*ppdata = ((uint8_t *)(*ppdata)) - off;
288		*plen += off;
289
290		if ((state == USB_HR_NOT_COMPLETE) &&
291		    (temp_state == USB_HR_COMPLETE_OK))
292			goto tr_short;
293		else
294			goto tr_valid;
295	} else if (error == ENOTTY) {
296		goto tr_stalled;
297	}
298	if ((req.bmRequestType & 0x1F) != UT_INTERFACE) {
299		iface_index++;		/* iterate */
300		goto tr_repeat;
301	}
302	if (state != USB_HR_NOT_COMPLETE) {
303		/* we are complete */
304		goto tr_valid;
305	}
306	switch (req.bmRequestType) {
307	case UT_WRITE_INTERFACE:
308		switch (req.bRequest) {
309		case UR_SET_INTERFACE:
310			/*
311			 * We assume that the endpoints are the same
312			 * accross the alternate settings.
313			 *
314			 * Reset the endpoints, because re-attaching
315			 * only a part of the device is not possible.
316			 */
317			error = usb_check_alt_setting(udev,
318			    iface, req.wValue[0]);
319			if (error) {
320				DPRINTF("alt setting does not exist %s\n",
321				    usbd_errstr(error));
322				goto tr_stalled;
323			}
324			error = usb_reset_iface_endpoints(udev, iface_index);
325			if (error) {
326				DPRINTF("alt setting failed %s\n",
327				    usbd_errstr(error));
328				goto tr_stalled;
329			}
330			/* update the current alternate setting */
331			iface->alt_index = req.wValue[0];
332			break;
333
334		default:
335			goto tr_stalled;
336		}
337		break;
338
339	case UT_READ_INTERFACE:
340		switch (req.bRequest) {
341		case UR_GET_INTERFACE:
342			*ppdata = &iface->alt_index;
343			*plen = 1;
344			break;
345
346		default:
347			goto tr_stalled;
348		}
349		break;
350	default:
351		goto tr_stalled;
352	}
353tr_valid:
354	usbd_enum_unlock(udev);
355	USB_XFER_LOCK(xfer);
356	return (0);
357
358tr_short:
359	usbd_enum_unlock(udev);
360	USB_XFER_LOCK(xfer);
361	return (USB_ERR_SHORT_XFER);
362
363tr_stalled:
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 *------------------------------------------------------------------------*/
376static usb_error_t
377usb_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 *------------------------------------------------------------------------*/
396static uint8_t
397usb_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 *------------------------------------------------------------------------*/
421static usb_error_t
422usb_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 *------------------------------------------------------------------------*/
458static usb_error_t
459usb_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
643tr_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
651tr_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
657tr_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
675tr_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
690tr_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
698tr_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
706tr_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
714tr_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
722tr_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
730tr_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
740tr_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
796tr_stalled:
797	DPRINTF("%s\n", (state != USB_HR_NOT_COMPLETE) ?
798	    "complete" : "stalled");
799	return (USB_ERR_STALLED);
800
801tr_bad_context:
802	DPRINTF("bad context\n");
803	return (USB_ERR_BAD_CONTEXT);
804}
805