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