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