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