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