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