1 /* $FreeBSD: releng/8.3/sys/dev/usb/usb_handle_request.c 221125 2011-04-27 18:00:46Z jhb $ */
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
67 static uint8_t usb_handle_get_stall(struct usb_device *, uint8_t);
68 static usb_error_t usb_handle_remote_wakeup(struct usb_xfer *, uint8_t);
69 static usb_error_t usb_handle_request(struct usb_xfer *);
70 static usb_error_t usb_handle_set_config(struct usb_xfer *, uint8_t);
71 static usb_error_t usb_handle_set_stall(struct usb_xfer *, uint8_t,
72 uint8_t);
73 static 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 *------------------------------------------------------------------------*/
83 void
84 usb_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
123 tr_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 *------------------------------------------------------------------------*/
143 static usb_error_t
144 usb_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 }
177 done:
178 usbd_enum_unlock(udev);
179 USB_XFER_LOCK(xfer);
180 return (err);
181 }
182
183 static usb_error_t
184 usb_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 *------------------------------------------------------------------------*/
214 static usb_error_t
215 usb_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
242 tr_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 }
353 tr_valid:
354 usbd_enum_unlock(udev);
355 USB_XFER_LOCK(xfer);
356 return (0);
357
358 tr_short:
359 usbd_enum_unlock(udev);
360 USB_XFER_LOCK(xfer);
361 return (USB_ERR_SHORT_XFER);
362
363 tr_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 *------------------------------------------------------------------------*/
376 static usb_error_t
377 usb_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 *------------------------------------------------------------------------*/
396 static uint8_t
397 usb_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 *------------------------------------------------------------------------*/
421 static usb_error_t
422 usb_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 *------------------------------------------------------------------------*/
458 static usb_error_t
459 usb_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 uint16_t wIndex;
470 uint8_t state;
471 uint8_t is_complete = 1;
472 usb_error_t err;
473 union {
474 uWord wStatus;
475 uint8_t buf[2];
476 } temp;
477
478 /*
479 * Filter the USB transfer state into
480 * something which we understand:
481 */
482
483 switch (USB_GET_STATE(xfer)) {
484 case USB_ST_SETUP:
485 state = USB_HR_NOT_COMPLETE;
486
487 if (!xfer->flags_int.control_act) {
488 /* nothing to do */
489 goto tr_stalled;
490 }
491 break;
492 case USB_ST_TRANSFERRED:
493 if (!xfer->flags_int.control_act) {
494 state = USB_HR_COMPLETE_OK;
495 } else {
496 state = USB_HR_NOT_COMPLETE;
497 }
498 break;
499 default:
500 state = USB_HR_COMPLETE_ERR;
501 break;
502 }
503
504 /* reset frame stuff */
505
506 usbd_xfer_set_frame_len(xfer, 0, 0);
507
508 usbd_xfer_set_frame_offset(xfer, 0, 0);
509 usbd_xfer_set_frame_offset(xfer, sizeof(req), 1);
510
511 /* get the current request, if any */
512
513 usbd_copy_out(xfer->frbuffers, 0, &req, sizeof(req));
514
515 if (xfer->flags_int.control_rem == 0xFFFF) {
516 /* first time - not initialised */
517 rem = UGETW(req.wLength);
518 off = 0;
519 } else {
520 /* not first time - initialised */
521 rem = xfer->flags_int.control_rem;
522 off = UGETW(req.wLength) - rem;
523 }
524
525 /* set some defaults */
526
527 max_len = 0;
528 src_zcopy = NULL;
529 src_mcopy = NULL;
530 udev = xfer->xroot->udev;
531
532 /* get some request fields decoded */
533
534 wValue = UGETW(req.wValue);
535 wIndex = UGETW(req.wIndex);
536
537 DPRINTF("req 0x%02x 0x%02x 0x%04x 0x%04x "
538 "off=0x%x rem=0x%x, state=%d\n", req.bmRequestType,
539 req.bRequest, wValue, wIndex, off, rem, state);
540
541 /* demultiplex the control request */
542
543 switch (req.bmRequestType) {
544 case UT_READ_DEVICE:
545 if (state != USB_HR_NOT_COMPLETE) {
546 break;
547 }
548 switch (req.bRequest) {
549 case UR_GET_DESCRIPTOR:
550 goto tr_handle_get_descriptor;
551 case UR_GET_CONFIG:
552 goto tr_handle_get_config;
553 case UR_GET_STATUS:
554 goto tr_handle_get_status;
555 default:
556 goto tr_stalled;
557 }
558 break;
559
560 case UT_WRITE_DEVICE:
561 switch (req.bRequest) {
562 case UR_SET_ADDRESS:
563 goto tr_handle_set_address;
564 case UR_SET_CONFIG:
565 goto tr_handle_set_config;
566 case UR_CLEAR_FEATURE:
567 switch (wValue) {
568 case UF_DEVICE_REMOTE_WAKEUP:
569 goto tr_handle_clear_wakeup;
570 default:
571 goto tr_stalled;
572 }
573 break;
574 case UR_SET_FEATURE:
575 switch (wValue) {
576 case UF_DEVICE_REMOTE_WAKEUP:
577 goto tr_handle_set_wakeup;
578 default:
579 goto tr_stalled;
580 }
581 break;
582 default:
583 goto tr_stalled;
584 }
585 break;
586
587 case UT_WRITE_ENDPOINT:
588 switch (req.bRequest) {
589 case UR_CLEAR_FEATURE:
590 switch (wValue) {
591 case UF_ENDPOINT_HALT:
592 goto tr_handle_clear_halt;
593 default:
594 goto tr_stalled;
595 }
596 break;
597 case UR_SET_FEATURE:
598 switch (wValue) {
599 case UF_ENDPOINT_HALT:
600 goto tr_handle_set_halt;
601 default:
602 goto tr_stalled;
603 }
604 break;
605 default:
606 goto tr_stalled;
607 }
608 break;
609
610 case UT_READ_ENDPOINT:
611 switch (req.bRequest) {
612 case UR_GET_STATUS:
613 goto tr_handle_get_ep_status;
614 default:
615 goto tr_stalled;
616 }
617 break;
618 default:
619 /* we use "USB_ADD_BYTES" to de-const the src_zcopy */
620 err = usb_handle_iface_request(xfer,
621 USB_ADD_BYTES(&src_zcopy, 0),
622 &max_len, req, off, state);
623 if (err == 0) {
624 is_complete = 0;
625 goto tr_valid;
626 } else if (err == USB_ERR_SHORT_XFER) {
627 goto tr_valid;
628 }
629 /*
630 * Reset zero-copy pointer and max length
631 * variable in case they were unintentionally
632 * set:
633 */
634 src_zcopy = NULL;
635 max_len = 0;
636
637 /*
638 * Check if we have a vendor specific
639 * descriptor:
640 */
641 goto tr_handle_get_descriptor;
642 }
643 goto tr_valid;
644
645 tr_handle_get_descriptor:
646 err = (usb_temp_get_desc_p) (udev, &req, &src_zcopy, &max_len);
647 if (err)
648 goto tr_stalled;
649 if (src_zcopy == NULL)
650 goto tr_stalled;
651 goto tr_valid;
652
653 tr_handle_get_config:
654 temp.buf[0] = udev->curr_config_no;
655 src_mcopy = temp.buf;
656 max_len = 1;
657 goto tr_valid;
658
659 tr_handle_get_status:
660
661 wValue = 0;
662
663 USB_BUS_LOCK(udev->bus);
664 if (udev->flags.remote_wakeup) {
665 wValue |= UDS_REMOTE_WAKEUP;
666 }
667 if (udev->flags.self_powered) {
668 wValue |= UDS_SELF_POWERED;
669 }
670 USB_BUS_UNLOCK(udev->bus);
671
672 USETW(temp.wStatus, wValue);
673 src_mcopy = temp.wStatus;
674 max_len = sizeof(temp.wStatus);
675 goto tr_valid;
676
677 tr_handle_set_address:
678 if (state == USB_HR_NOT_COMPLETE) {
679 if (wValue >= 0x80) {
680 /* invalid value */
681 goto tr_stalled;
682 } else if (udev->curr_config_no != 0) {
683 /* we are configured ! */
684 goto tr_stalled;
685 }
686 } else if (state != USB_HR_NOT_COMPLETE) {
687 udev->address = (wValue & 0x7F);
688 goto tr_bad_context;
689 }
690 goto tr_valid;
691
692 tr_handle_set_config:
693 if (state == USB_HR_NOT_COMPLETE) {
694 if (usb_handle_set_config(xfer, req.wValue[0])) {
695 goto tr_stalled;
696 }
697 }
698 goto tr_valid;
699
700 tr_handle_clear_halt:
701 if (state == USB_HR_NOT_COMPLETE) {
702 if (usb_handle_set_stall(xfer, req.wIndex[0], 0)) {
703 goto tr_stalled;
704 }
705 }
706 goto tr_valid;
707
708 tr_handle_clear_wakeup:
709 if (state == USB_HR_NOT_COMPLETE) {
710 if (usb_handle_remote_wakeup(xfer, 0)) {
711 goto tr_stalled;
712 }
713 }
714 goto tr_valid;
715
716 tr_handle_set_halt:
717 if (state == USB_HR_NOT_COMPLETE) {
718 if (usb_handle_set_stall(xfer, req.wIndex[0], 1)) {
719 goto tr_stalled;
720 }
721 }
722 goto tr_valid;
723
724 tr_handle_set_wakeup:
725 if (state == USB_HR_NOT_COMPLETE) {
726 if (usb_handle_remote_wakeup(xfer, 1)) {
727 goto tr_stalled;
728 }
729 }
730 goto tr_valid;
731
732 tr_handle_get_ep_status:
733 if (state == USB_HR_NOT_COMPLETE) {
734 temp.wStatus[0] =
735 usb_handle_get_stall(udev, req.wIndex[0]);
736 temp.wStatus[1] = 0;
737 src_mcopy = temp.wStatus;
738 max_len = sizeof(temp.wStatus);
739 }
740 goto tr_valid;
741
742 tr_valid:
743 if (state != USB_HR_NOT_COMPLETE) {
744 goto tr_stalled;
745 }
746 /* subtract offset from length */
747
748 max_len -= off;
749
750 /* Compute the real maximum data length */
751
752 if (max_len > xfer->max_data_length) {
753 max_len = usbd_xfer_max_len(xfer);
754 }
755 if (max_len > rem) {
756 max_len = rem;
757 }
758 /*
759 * If the remainder is greater than the maximum data length,
760 * we need to truncate the value for the sake of the
761 * comparison below:
762 */
763 if (rem > xfer->max_data_length) {
764 rem = usbd_xfer_max_len(xfer);
765 }
766 if ((rem != max_len) && (is_complete != 0)) {
767 /*
768 * If we don't transfer the data we can transfer, then
769 * the transfer is short !
770 */
771 xfer->flags.force_short_xfer = 1;
772 xfer->nframes = 2;
773 } else {
774 /*
775 * Default case
776 */
777 xfer->flags.force_short_xfer = 0;
778 xfer->nframes = max_len ? 2 : 1;
779 }
780 if (max_len > 0) {
781 if (src_mcopy) {
782 src_mcopy = USB_ADD_BYTES(src_mcopy, off);
783 usbd_copy_in(xfer->frbuffers + 1, 0,
784 src_mcopy, max_len);
785 usbd_xfer_set_frame_len(xfer, 1, max_len);
786 } else {
787 usbd_xfer_set_frame_data(xfer, 1,
788 USB_ADD_BYTES(src_zcopy, off), max_len);
789 }
790 } else {
791 /* the end is reached, send status */
792 xfer->flags.manual_status = 0;
793 usbd_xfer_set_frame_len(xfer, 1, 0);
794 }
795 DPRINTF("success\n");
796 return (0); /* success */
797
798 tr_stalled:
799 DPRINTF("%s\n", (state != USB_HR_NOT_COMPLETE) ?
800 "complete" : "stalled");
801 return (USB_ERR_STALLED);
802
803 tr_bad_context:
804 DPRINTF("bad context\n");
805 return (USB_ERR_BAD_CONTEXT);
806 }
Cache object: ee49a549ea6587e689ae5d8dd8d169ae
|