1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28 #include "implementation/global_implementation.h"
29
30 /* function prototypes */
31
32 static uint8_t usb_handle_get_stall(struct usb_device *, uint8_t);
33 static usb_error_t usb_handle_remote_wakeup(struct usb_xfer *, uint8_t);
34 static usb_error_t usb_handle_request(struct usb_xfer *);
35 static usb_error_t usb_handle_set_config(struct usb_xfer *, uint8_t);
36 static usb_error_t usb_handle_set_stall(struct usb_xfer *, uint8_t,
37 uint8_t);
38 static usb_error_t usb_handle_iface_request(struct usb_xfer *, void **,
39 uint16_t *, struct usb_device_request, uint16_t,
40 uint8_t);
41
42 /*------------------------------------------------------------------------*
43 * usb_handle_request_callback
44 *
45 * This function is the USB callback for generic USB Device control
46 * transfers.
47 *------------------------------------------------------------------------*/
48 void
usb_handle_request_callback(struct usb_xfer * xfer,usb_error_t error)49 usb_handle_request_callback(struct usb_xfer *xfer, usb_error_t error)
50 {
51 usb_error_t err;
52
53 /* check the current transfer state */
54
55 switch (USB_GET_STATE(xfer)) {
56 case USB_ST_SETUP:
57 case USB_ST_TRANSFERRED:
58
59 /* handle the request */
60 err = usb_handle_request(xfer);
61
62 if (err) {
63 if (err == USB_ERR_BAD_CONTEXT) {
64 /* we need to re-setup the control transfer */
65 usb_needs_explore(xfer->xroot->bus, 0);
66 break;
67 }
68 goto tr_restart;
69 }
70 usbd_transfer_submit(xfer);
71 break;
72
73 default:
74 /* check if a control transfer is active */
75 if (xfer->flags_int.control_rem != 0xFFFF) {
76 /* handle the request */
77 (void)usb_handle_request(xfer);
78 }
79 if (xfer->error != USB_ERR_CANCELLED) {
80 /* should not happen - try stalling */
81 goto tr_restart;
82 }
83 break;
84 }
85 return;
86
87 tr_restart:
88 /*
89 * If a control transfer is active, stall it, and wait for the
90 * next control transfer.
91 */
92 usbd_xfer_set_frame_len(xfer, 0, sizeof(struct usb_device_request));
93 xfer->nframes = 1;
94 xfer->flags.manual_status = 1;
95 xfer->flags.force_short_xfer = 0;
96 usbd_xfer_set_stall(xfer); /* cancel previous transfer, if any */
97 usbd_transfer_submit(xfer);
98 }
99
100 /*------------------------------------------------------------------------*
101 * usb_handle_set_config
102 *
103 * Returns:
104 * 0: Success
105 * Else: Failure
106 *------------------------------------------------------------------------*/
107 static usb_error_t
usb_handle_set_config(struct usb_xfer * xfer,uint8_t conf_no)108 usb_handle_set_config(struct usb_xfer *xfer, uint8_t conf_no)
109 {
110 struct usb_device *udev = xfer->xroot->udev;
111 usb_error_t err = USB_ERR_NORMAL_COMPLETION;
112 uint8_t do_unlock;
113
114 /*
115 * We need to protect against other threads doing probe and
116 * attach:
117 */
118 USB_XFER_UNLOCK(xfer);
119
120 /* Prevent re-enumeration */
121 do_unlock = usbd_enum_lock(udev);
122
123 if (conf_no == USB_UNCONFIG_NO) {
124 conf_no = USB_UNCONFIG_INDEX;
125 } else {
126 /*
127 * The relationship between config number and config index
128 * is very simple in our case:
129 */
130 conf_no--;
131 }
132
133 if (usbd_set_config_index(udev, conf_no)) {
134 DPRINTF("set config %d failed\n", conf_no);
135 err = USB_ERR_STALLED;
136 goto done;
137 }
138 if (usb_probe_and_attach(udev, USB_IFACE_INDEX_ANY)) {
139 DPRINTF("probe and attach failed\n");
140 err = USB_ERR_STALLED;
141 goto done;
142 }
143 done:
144 if (do_unlock)
145 usbd_enum_unlock(udev);
146 USB_XFER_LOCK(xfer);
147 return (err);
148 }
149
150 static usb_error_t
usb_check_alt_setting(struct usb_device * udev,struct usb_interface * iface,uint8_t alt_index)151 usb_check_alt_setting(struct usb_device *udev,
152 struct usb_interface *iface, uint8_t alt_index)
153 {
154 uint8_t do_unlock;
155 usb_error_t err = USB_ERR_NORMAL_COMPLETION;
156
157 /* Prevent re-enumeration */
158 do_unlock = usbd_enum_lock(udev);
159
160 if (alt_index >= usbd_get_no_alts(udev->cdesc, iface->idesc))
161 err = USB_ERR_INVAL;
162
163 if (do_unlock)
164 usbd_enum_unlock(udev);
165
166 return (err);
167 }
168
169 /*------------------------------------------------------------------------*
170 * usb_handle_iface_request
171 *
172 * Returns:
173 * 0: Success
174 * Else: Failure
175 *------------------------------------------------------------------------*/
176 static usb_error_t
usb_handle_iface_request(struct usb_xfer * xfer,void ** ppdata,uint16_t * plen,struct usb_device_request req,uint16_t off,uint8_t state)177 usb_handle_iface_request(struct usb_xfer *xfer,
178 void **ppdata, uint16_t *plen,
179 struct usb_device_request req, uint16_t off, uint8_t state)
180 {
181 struct usb_interface *iface;
182 struct usb_interface *iface_parent; /* parent interface */
183 struct usb_device *udev = xfer->xroot->udev;
184 int error;
185 uint8_t iface_index;
186 uint8_t temp_state;
187 uint8_t do_unlock;
188
189 if ((req.bmRequestType & 0x1F) == UT_INTERFACE) {
190 iface_index = req.wIndex[0]; /* unicast */
191 } else {
192 iface_index = 0; /* broadcast */
193 }
194
195 /*
196 * We need to protect against other threads doing probe and
197 * attach:
198 */
199 USB_XFER_UNLOCK(xfer);
200
201 /* Prevent re-enumeration */
202 do_unlock = usbd_enum_lock(udev);
203
204 error = ENXIO;
205
206 tr_repeat:
207 iface = usbd_get_iface(udev, iface_index);
208 if ((iface == NULL) ||
209 (iface->idesc == NULL)) {
210 /* end of interfaces non-existing interface */
211 goto tr_stalled;
212 }
213 /* set initial state */
214
215 temp_state = state;
216
217 /* forward request to interface, if any */
218
219 if ((error != 0) &&
220 (error != ENOTTY) &&
221 (iface->subdev != NULL) &&
222 device_is_attached(iface->subdev)) {
223 error = USB_HANDLE_REQUEST(iface->subdev,
224 &req, ppdata, plen,
225 off, &temp_state);
226 }
227 iface_parent = usbd_get_iface(udev, iface->parent_iface_index);
228
229 if ((iface_parent == NULL) ||
230 (iface_parent->idesc == NULL)) {
231 /* non-existing interface */
232 iface_parent = NULL;
233 }
234 /* forward request to parent interface, if any */
235
236 if ((error != 0) &&
237 (error != ENOTTY) &&
238 (iface_parent != NULL) &&
239 (iface_parent->subdev != NULL) &&
240 ((req.bmRequestType & 0x1F) == UT_INTERFACE) &&
241 (iface_parent->subdev != iface->subdev) &&
242 device_is_attached(iface_parent->subdev)) {
243 error = USB_HANDLE_REQUEST(iface_parent->subdev,
244 &req, ppdata, plen, off, &temp_state);
245 }
246 if (error == 0) {
247 /* negativly adjust pointer and length */
248 *ppdata = ((uint8_t *)(*ppdata)) - off;
249 *plen += off;
250
251 if ((state == USB_HR_NOT_COMPLETE) &&
252 (temp_state == USB_HR_COMPLETE_OK))
253 goto tr_short;
254 else
255 goto tr_valid;
256 } else if (error == ENOTTY) {
257 goto tr_stalled;
258 }
259 if ((req.bmRequestType & 0x1F) != UT_INTERFACE) {
260 iface_index++; /* iterate */
261 goto tr_repeat;
262 }
263 if (state != USB_HR_NOT_COMPLETE) {
264 /* we are complete */
265 goto tr_valid;
266 }
267 switch (req.bmRequestType) {
268 case UT_WRITE_INTERFACE:
269 switch (req.bRequest) {
270 case UR_SET_INTERFACE:
271 /*
272 * We assume that the endpoints are the same
273 * across the alternate settings.
274 *
275 * Reset the endpoints, because re-attaching
276 * only a part of the device is not possible.
277 */
278 error = usb_check_alt_setting(udev,
279 iface, req.wValue[0]);
280 if (error) {
281 DPRINTF("alt setting does not exist %s\n",
282 usbd_errstr(error));
283 goto tr_stalled;
284 }
285 error = usb_reset_iface_endpoints(udev, iface_index);
286 if (error) {
287 DPRINTF("alt setting failed %s\n",
288 usbd_errstr(error));
289 goto tr_stalled;
290 }
291 /* update the current alternate setting */
292 iface->alt_index = req.wValue[0];
293 break;
294
295 default:
296 goto tr_stalled;
297 }
298 break;
299
300 case UT_READ_INTERFACE:
301 switch (req.bRequest) {
302 case UR_GET_INTERFACE:
303 *ppdata = &iface->alt_index;
304 *plen = 1;
305 break;
306
307 default:
308 goto tr_stalled;
309 }
310 break;
311 default:
312 goto tr_stalled;
313 }
314 tr_valid:
315 if (do_unlock)
316 usbd_enum_unlock(udev);
317 USB_XFER_LOCK(xfer);
318 return (USB_ERR_NORMAL_COMPLETION);
319
320 tr_short:
321 if (do_unlock)
322 usbd_enum_unlock(udev);
323 USB_XFER_LOCK(xfer);
324 return (USB_ERR_SHORT_XFER);
325
326 tr_stalled:
327 if (do_unlock)
328 usbd_enum_unlock(udev);
329 USB_XFER_LOCK(xfer);
330 return (USB_ERR_STALLED);
331 }
332
333 /*------------------------------------------------------------------------*
334 * usb_handle_stall
335 *
336 * Returns:
337 * 0: Success
338 * Else: Failure
339 *------------------------------------------------------------------------*/
340 static usb_error_t
usb_handle_set_stall(struct usb_xfer * xfer,uint8_t ep,uint8_t do_stall)341 usb_handle_set_stall(struct usb_xfer *xfer, uint8_t ep, uint8_t do_stall)
342 {
343 struct usb_device *udev = xfer->xroot->udev;
344 usb_error_t err;
345
346 USB_XFER_UNLOCK(xfer);
347 err = usbd_set_endpoint_stall(udev,
348 usbd_get_ep_by_addr(udev, ep), do_stall);
349 USB_XFER_LOCK(xfer);
350 return (err);
351 }
352
353 /*------------------------------------------------------------------------*
354 * usb_handle_get_stall
355 *
356 * Returns:
357 * 0: Success
358 * Else: Failure
359 *------------------------------------------------------------------------*/
360 static uint8_t
usb_handle_get_stall(struct usb_device * udev,uint8_t ea_val)361 usb_handle_get_stall(struct usb_device *udev, uint8_t ea_val)
362 {
363 struct usb_endpoint *ep;
364 uint8_t halted;
365
366 ep = usbd_get_ep_by_addr(udev, ea_val);
367 if (ep == NULL) {
368 /* nothing to do */
369 return (0);
370 }
371 USB_BUS_LOCK(udev->bus);
372 halted = ep->is_stalled;
373 USB_BUS_UNLOCK(udev->bus);
374
375 return (halted);
376 }
377
378 /*------------------------------------------------------------------------*
379 * usb_handle_remote_wakeup
380 *
381 * Returns:
382 * 0: Success
383 * Else: Failure
384 *------------------------------------------------------------------------*/
385 static usb_error_t
usb_handle_remote_wakeup(struct usb_xfer * xfer,uint8_t is_on)386 usb_handle_remote_wakeup(struct usb_xfer *xfer, uint8_t is_on)
387 {
388 struct usb_device *udev;
389 struct usb_bus *bus;
390
391 udev = xfer->xroot->udev;
392 bus = udev->bus;
393
394 USB_BUS_LOCK(bus);
395
396 if (is_on) {
397 udev->flags.remote_wakeup = 1;
398 } else {
399 udev->flags.remote_wakeup = 0;
400 }
401
402 USB_BUS_UNLOCK(bus);
403
404 #if USB_HAVE_POWERD
405 /* In case we are out of sync, update the power state. */
406 usb_bus_power_update(udev->bus);
407 #endif
408 return (USB_ERR_NORMAL_COMPLETION); /* success */
409 }
410
411 /*------------------------------------------------------------------------*
412 * usb_handle_request
413 *
414 * Internal state sequence:
415 *
416 * USB_HR_NOT_COMPLETE -> USB_HR_COMPLETE_OK v USB_HR_COMPLETE_ERR
417 *
418 * Returns:
419 * 0: Ready to start hardware
420 * Else: Stall current transfer, if any
421 *------------------------------------------------------------------------*/
422 static usb_error_t
usb_handle_request(struct usb_xfer * xfer)423 usb_handle_request(struct usb_xfer *xfer)
424 {
425 struct usb_device_request req;
426 struct usb_device *udev;
427 const void *src_zcopy; /* zero-copy source pointer */
428 const void *src_mcopy; /* non zero-copy source pointer */
429 uint16_t off; /* data offset */
430 uint16_t rem; /* data remainder */
431 uint16_t max_len; /* max fragment length */
432 uint16_t wValue;
433 uint8_t state;
434 uint8_t is_complete = 1;
435 usb_error_t err;
436 union {
437 uWord wStatus;
438 uint8_t buf[2];
439 } temp;
440
441 /*
442 * Filter the USB transfer state into
443 * something which we understand:
444 */
445
446 switch (USB_GET_STATE(xfer)) {
447 case USB_ST_SETUP:
448 state = USB_HR_NOT_COMPLETE;
449
450 if (!xfer->flags_int.control_act) {
451 /* nothing to do */
452 goto tr_stalled;
453 }
454 break;
455 case USB_ST_TRANSFERRED:
456 if (!xfer->flags_int.control_act) {
457 state = USB_HR_COMPLETE_OK;
458 } else {
459 state = USB_HR_NOT_COMPLETE;
460 }
461 break;
462 default:
463 state = USB_HR_COMPLETE_ERR;
464 break;
465 }
466
467 /* reset frame stuff */
468
469 usbd_xfer_set_frame_len(xfer, 0, 0);
470
471 usbd_xfer_set_frame_offset(xfer, 0, 0);
472 usbd_xfer_set_frame_offset(xfer, sizeof(req), 1);
473
474 /* get the current request, if any */
475
476 usbd_copy_out(xfer->frbuffers, 0, &req, sizeof(req));
477
478 if (xfer->flags_int.control_rem == 0xFFFF) {
479 /* first time - not initialised */
480 rem = UGETW(req.wLength);
481 off = 0;
482 } else {
483 /* not first time - initialised */
484 rem = xfer->flags_int.control_rem;
485 off = UGETW(req.wLength) - rem;
486 }
487
488 /* set some defaults */
489
490 max_len = 0;
491 src_zcopy = NULL;
492 src_mcopy = NULL;
493 udev = xfer->xroot->udev;
494
495 /* get some request fields decoded */
496
497 wValue = UGETW(req.wValue);
498
499 DPRINTF("req 0x%02x 0x%02x 0x%04x 0x%04x "
500 "off=0x%x rem=0x%x, state=%d\n", req.bmRequestType,
501 req.bRequest, wValue, UGETW(req.wIndex), off, rem, state);
502
503 /* demultiplex the control request */
504
505 switch (req.bmRequestType) {
506 case UT_READ_DEVICE:
507 if (state != USB_HR_NOT_COMPLETE) {
508 break;
509 }
510 switch (req.bRequest) {
511 case UR_GET_DESCRIPTOR:
512 goto tr_handle_get_descriptor;
513 case UR_GET_CONFIG:
514 goto tr_handle_get_config;
515 case UR_GET_STATUS:
516 goto tr_handle_get_status;
517 default:
518 goto tr_stalled;
519 }
520 break;
521
522 case UT_WRITE_DEVICE:
523 switch (req.bRequest) {
524 case UR_SET_ADDRESS:
525 goto tr_handle_set_address;
526 case UR_SET_CONFIG:
527 goto tr_handle_set_config;
528 case UR_CLEAR_FEATURE:
529 switch (wValue) {
530 case UF_DEVICE_REMOTE_WAKEUP:
531 goto tr_handle_clear_wakeup;
532 default:
533 goto tr_stalled;
534 }
535 break;
536 case UR_SET_FEATURE:
537 switch (wValue) {
538 case UF_DEVICE_REMOTE_WAKEUP:
539 goto tr_handle_set_wakeup;
540 default:
541 goto tr_stalled;
542 }
543 break;
544 default:
545 goto tr_stalled;
546 }
547 break;
548
549 case UT_WRITE_ENDPOINT:
550 switch (req.bRequest) {
551 case UR_CLEAR_FEATURE:
552 switch (wValue) {
553 case UF_ENDPOINT_HALT:
554 goto tr_handle_clear_halt;
555 default:
556 goto tr_stalled;
557 }
558 break;
559 case UR_SET_FEATURE:
560 switch (wValue) {
561 case UF_ENDPOINT_HALT:
562 goto tr_handle_set_halt;
563 default:
564 goto tr_stalled;
565 }
566 break;
567 default:
568 goto tr_stalled;
569 }
570 break;
571
572 case UT_READ_ENDPOINT:
573 switch (req.bRequest) {
574 case UR_GET_STATUS:
575 goto tr_handle_get_ep_status;
576 default:
577 goto tr_stalled;
578 }
579 break;
580 default:
581 /* we use "USB_ADD_BYTES" to de-const the src_zcopy */
582 err = usb_handle_iface_request(xfer,
583 USB_ADD_BYTES(&src_zcopy, 0),
584 &max_len, req, off, state);
585 if (err == 0) {
586 is_complete = 0;
587 goto tr_valid;
588 } else if (err == USB_ERR_SHORT_XFER) {
589 goto tr_valid;
590 }
591 /*
592 * Reset zero-copy pointer and max length
593 * variable in case they were unintentionally
594 * set:
595 */
596 src_zcopy = NULL;
597 max_len = 0;
598
599 /*
600 * Check if we have a vendor specific
601 * descriptor:
602 */
603 goto tr_handle_get_descriptor;
604 }
605 goto tr_valid;
606
607 tr_handle_get_descriptor:
608 err = (usb_temp_get_desc_p) (udev, &req, &src_zcopy, &max_len);
609 if (err)
610 goto tr_stalled;
611 if (src_zcopy == NULL)
612 goto tr_stalled;
613 goto tr_valid;
614
615 tr_handle_get_config:
616 temp.buf[0] = udev->curr_config_no;
617 src_mcopy = temp.buf;
618 max_len = 1;
619 goto tr_valid;
620
621 tr_handle_get_status:
622
623 wValue = 0;
624
625 USB_BUS_LOCK(udev->bus);
626 if (udev->flags.remote_wakeup) {
627 wValue |= UDS_REMOTE_WAKEUP;
628 }
629 if (udev->flags.self_powered) {
630 wValue |= UDS_SELF_POWERED;
631 }
632 USB_BUS_UNLOCK(udev->bus);
633
634 USETW(temp.wStatus, wValue);
635 src_mcopy = temp.wStatus;
636 max_len = sizeof(temp.wStatus);
637 goto tr_valid;
638
639 tr_handle_set_address:
640 if (state == USB_HR_NOT_COMPLETE) {
641 if (wValue >= 0x80) {
642 /* invalid value */
643 goto tr_stalled;
644 } else if (udev->curr_config_no != 0) {
645 /* we are configured ! */
646 goto tr_stalled;
647 }
648 } else if (state != USB_HR_NOT_COMPLETE) {
649 udev->address = (wValue & 0x7F);
650 goto tr_bad_context;
651 }
652 goto tr_valid;
653
654 tr_handle_set_config:
655 if (state == USB_HR_NOT_COMPLETE) {
656 if (usb_handle_set_config(xfer, req.wValue[0])) {
657 goto tr_stalled;
658 }
659 }
660 goto tr_valid;
661
662 tr_handle_clear_halt:
663 if (state == USB_HR_NOT_COMPLETE) {
664 if (usb_handle_set_stall(xfer, req.wIndex[0], 0)) {
665 goto tr_stalled;
666 }
667 }
668 goto tr_valid;
669
670 tr_handle_clear_wakeup:
671 if (state == USB_HR_NOT_COMPLETE) {
672 if (usb_handle_remote_wakeup(xfer, 0)) {
673 goto tr_stalled;
674 }
675 }
676 goto tr_valid;
677
678 tr_handle_set_halt:
679 if (state == USB_HR_NOT_COMPLETE) {
680 if (usb_handle_set_stall(xfer, req.wIndex[0], 1)) {
681 goto tr_stalled;
682 }
683 }
684 goto tr_valid;
685
686 tr_handle_set_wakeup:
687 if (state == USB_HR_NOT_COMPLETE) {
688 if (usb_handle_remote_wakeup(xfer, 1)) {
689 goto tr_stalled;
690 }
691 }
692 goto tr_valid;
693
694 tr_handle_get_ep_status:
695 if (state == USB_HR_NOT_COMPLETE) {
696 temp.wStatus[0] =
697 usb_handle_get_stall(udev, req.wIndex[0]);
698 temp.wStatus[1] = 0;
699 src_mcopy = temp.wStatus;
700 max_len = sizeof(temp.wStatus);
701 }
702 goto tr_valid;
703
704 tr_valid:
705 if (state != USB_HR_NOT_COMPLETE) {
706 goto tr_stalled;
707 }
708 /* subtract offset from length */
709
710 max_len -= off;
711
712 /* Compute the real maximum data length */
713
714 if (max_len > xfer->max_data_length) {
715 max_len = usbd_xfer_max_len(xfer);
716 }
717 if (max_len > rem) {
718 max_len = rem;
719 }
720 /*
721 * If the remainder is greater than the maximum data length,
722 * we need to truncate the value for the sake of the
723 * comparison below:
724 */
725 if (rem > xfer->max_data_length) {
726 rem = usbd_xfer_max_len(xfer);
727 }
728 if ((rem != max_len) && (is_complete != 0)) {
729 /*
730 * If we don't transfer the data we can transfer, then
731 * the transfer is short !
732 */
733 xfer->flags.force_short_xfer = 1;
734 xfer->nframes = 2;
735 } else {
736 /*
737 * Default case
738 */
739 xfer->flags.force_short_xfer = 0;
740 xfer->nframes = max_len ? 2 : 1;
741 }
742 if (max_len > 0) {
743 if (src_mcopy) {
744 src_mcopy = USB_ADD_BYTES(src_mcopy, off);
745 usbd_copy_in(xfer->frbuffers + 1, 0,
746 src_mcopy, max_len);
747 usbd_xfer_set_frame_len(xfer, 1, max_len);
748 } else {
749 usbd_xfer_set_frame_data(xfer, 1,
750 USB_ADD_BYTES(src_zcopy, off), max_len);
751 }
752 } else {
753 /* the end is reached, send status */
754 xfer->flags.manual_status = 0;
755 usbd_xfer_set_frame_len(xfer, 1, 0);
756 }
757 DPRINTF("success\n");
758 return (USB_ERR_NORMAL_COMPLETION); /* success */
759
760 tr_stalled:
761 DPRINTF("%s\n", (state != USB_HR_NOT_COMPLETE) ?
762 "complete" : "stalled");
763 return (USB_ERR_STALLED);
764
765 tr_bad_context:
766 DPRINTF("bad context\n");
767 return (USB_ERR_BAD_CONTEXT);
768 }
769