FreeBSD kernel usb device Code
g_audio.c
Go to the documentation of this file.
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2010 Hans Petter Selasky. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28/*
29 * USB audio specs: http://www.usb.org/developers/devclass_docs/audio10.pdf
30 * http://www.usb.org/developers/devclass_docs/frmts10.pdf
31 * http://www.usb.org/developers/devclass_docs/termt10.pdf
32 */
33
34#include <sys/param.h>
35__FBSDID("$FreeBSD$");
36
37#include <sys/stdint.h>
38#include <sys/stddef.h>
39#include <sys/queue.h>
40#include <sys/systm.h>
41#include <sys/kernel.h>
42#include <sys/bus.h>
43#include <sys/linker_set.h>
44#include <sys/module.h>
45#include <sys/lock.h>
46#include <sys/mutex.h>
47#include <sys/condvar.h>
48#include <sys/sysctl.h>
49#include <sys/sx.h>
50#include <sys/unistd.h>
51#include <sys/callout.h>
52#include <sys/malloc.h>
53#include <sys/priv.h>
54
55#include <dev/usb/usb.h>
56#include <dev/usb/usb_cdc.h>
57#include <dev/usb/usbdi.h>
58#include <dev/usb/usbdi_util.h>
59#include <dev/usb/usbhid.h>
60#include "usb_if.h"
61
62#define USB_DEBUG_VAR g_audio_debug
63#include <dev/usb/usb_debug.h>
64
66
67enum {
73};
74
76 struct mtx sc_mtx;
80
87
89
91
93
94 uint8_t sc_volume_setting[32];
95 uint8_t sc_volume_limit[32];
96 uint8_t sc_sample_rate[32];
97};
98
99static SYSCTL_NODE(_hw_usb, OID_AUTO, g_audio, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
100 "USB audio gadget");
101
102#ifdef USB_DEBUG
103static int g_audio_debug = 0;
104
105SYSCTL_INT(_hw_usb_g_audio, OID_AUTO, debug, CTLFLAG_RWTUN,
106 &g_audio_debug, 0, "Debug level");
107#endif
108
109static int g_audio_mode = 0;
110
111SYSCTL_INT(_hw_usb_g_audio, OID_AUTO, mode, CTLFLAG_RWTUN,
112 &g_audio_mode, 0, "Mode selection");
113
114static int g_audio_pattern_interval = 1000;
115
116SYSCTL_INT(_hw_usb_g_audio, OID_AUTO, pattern_interval, CTLFLAG_RWTUN,
117 &g_audio_pattern_interval, 0, "Pattern interval in milliseconds");
118
120
121SYSCTL_STRING(_hw_usb_g_audio, OID_AUTO, pattern, CTLFLAG_RW,
122 &g_audio_pattern_data, sizeof(g_audio_pattern_data), "Data pattern");
123
125
126SYSCTL_INT(_hw_usb_g_audio, OID_AUTO, throughput, CTLFLAG_RD,
127 &g_audio_throughput, sizeof(g_audio_throughput), "Throughput in bytes per second");
128
129static device_probe_t g_audio_probe;
130static device_attach_t g_audio_attach;
131static device_detach_t g_audio_detach;
132static usb_handle_request_t g_audio_handle_request;
133
136
137static devclass_t g_audio_devclass;
138
139static void g_audio_watchdog(void *arg);
140static void g_audio_timeout(void *arg);
141
142static device_method_t g_audio_methods[] = {
143 /* USB interface */
145
146 /* Device interface */
147 DEVMETHOD(device_probe, g_audio_probe),
148 DEVMETHOD(device_attach, g_audio_attach),
149 DEVMETHOD(device_detach, g_audio_detach),
150
151 DEVMETHOD_END
152};
153
154static driver_t g_audio_driver = {
155 .name = "g_audio",
156 .methods = g_audio_methods,
157 .size = sizeof(struct g_audio_softc),
158};
159
161MODULE_DEPEND(g_audio, usb, 1, 1, 1);
162
164 [G_AUDIO_ISOC0_RD] = {
166 .endpoint = UE_ADDR_ANY,
167 .direction = UE_DIR_RX,
168 .flags = {.ext_buffer = 1,.pipe_bof = 1,.short_xfer_ok = 1,},
169 .bufsize = G_AUDIO_BUFSIZE,
170 .callback = &g_audio_isoc_read_callback,
171 .frames = G_AUDIO_FRAMES,
172 .usb_mode = USB_MODE_DEVICE,
173 .if_index = 1,
174 },
175
176 [G_AUDIO_ISOC1_RD] = {
177 .type = UE_ISOCHRONOUS,
178 .endpoint = UE_ADDR_ANY,
179 .direction = UE_DIR_RX,
180 .flags = {.ext_buffer = 1,.pipe_bof = 1,.short_xfer_ok = 1,},
181 .bufsize = G_AUDIO_BUFSIZE,
182 .callback = &g_audio_isoc_read_callback,
183 .frames = G_AUDIO_FRAMES,
184 .usb_mode = USB_MODE_DEVICE,
185 .if_index = 1,
186 },
187
188 [G_AUDIO_ISOC0_WR] = {
189 .type = UE_ISOCHRONOUS,
190 .endpoint = UE_ADDR_ANY,
191 .direction = UE_DIR_TX,
192 .flags = {.ext_buffer = 1,.pipe_bof = 1,},
193 .bufsize = G_AUDIO_BUFSIZE,
194 .callback = &g_audio_isoc_write_callback,
195 .frames = G_AUDIO_FRAMES,
196 .usb_mode = USB_MODE_DEVICE,
197 .if_index = 2,
198 },
199
200 [G_AUDIO_ISOC1_WR] = {
201 .type = UE_ISOCHRONOUS,
202 .endpoint = UE_ADDR_ANY,
203 .direction = UE_DIR_TX,
204 .flags = {.ext_buffer = 1,.pipe_bof = 1,},
205 .bufsize = G_AUDIO_BUFSIZE,
206 .callback = &g_audio_isoc_write_callback,
207 .frames = G_AUDIO_FRAMES,
208 .usb_mode = USB_MODE_DEVICE,
209 .if_index = 2,
210 },
211};
212
213static void
215{
217
218 sc->sc_tx_interval = i;
219
220 if (i <= 0)
221 i = 1;
222 else if (i > 1023)
223 i = 1023;
224
225 i = USB_MS_TO_TICKS(i);
226
228}
229
230static void
232{
233 struct g_audio_softc *sc = arg;
234
235 sc->sc_mode = g_audio_mode;
236
237 memcpy(sc->sc_pattern, g_audio_pattern_data, sizeof(sc->sc_pattern));
238
239 sc->sc_pattern[G_AUDIO_MAX_STRLEN - 1] = 0;
240
241 sc->sc_pattern_len = strlen(sc->sc_pattern);
242
243 if (sc->sc_mode != G_AUDIO_MODE_LOOP) {
246 }
248}
249
250static void
252{
254}
255
256static void
258{
259 struct g_audio_softc *sc = arg;
260 int i;
261
262 i = sc->sc_throughput;
263
264 sc->sc_throughput = 0;
265
267
269}
270
271static int
272g_audio_probe(device_t dev)
273{
274 struct usb_attach_arg *uaa = device_get_ivars(dev);
275
276 DPRINTFN(11, "\n");
277
278 if (uaa->usb_mode != USB_MODE_DEVICE)
279 return (ENXIO);
280
281 if ((uaa->info.bInterfaceClass == UICLASS_AUDIO) &&
283 return (0);
284
285 return (ENXIO);
286}
287
288static int
289g_audio_attach(device_t dev)
290{
291 struct g_audio_softc *sc = device_get_softc(dev);
292 struct usb_attach_arg *uaa = device_get_ivars(dev);
293 int error;
294 int i;
295 uint8_t iface_index[3];
296
297 DPRINTFN(11, "\n");
298
300
301 mtx_init(&sc->sc_mtx, "g_audio", NULL, MTX_DEF);
302
305
307
308 sc->sc_noise_rem = 1;
309
310 for (i = 0; i != G_AUDIO_FRAMES; i++) {
313 }
314
315 iface_index[0] = uaa->info.bIfaceIndex;
316 iface_index[1] = uaa->info.bIfaceIndex + 1;
317 iface_index[2] = uaa->info.bIfaceIndex + 2;
318
319 error = usbd_set_alt_interface_index(uaa->device, iface_index[1], 1);
320 if (error) {
321 DPRINTF("alt iface setting error=%s\n", usbd_errstr(error));
322 goto detach;
323 }
324 error = usbd_set_alt_interface_index(uaa->device, iface_index[2], 1);
325 if (error) {
326 DPRINTF("alt iface setting error=%s\n", usbd_errstr(error));
327 goto detach;
328 }
330 iface_index, sc->sc_xfer, g_audio_config,
331 G_AUDIO_N_TRANSFER, sc, &sc->sc_mtx);
332
333 if (error) {
334 DPRINTF("error=%s\n", usbd_errstr(error));
335 goto detach;
336 }
337 usbd_set_parent_iface(uaa->device, iface_index[1], iface_index[0]);
338 usbd_set_parent_iface(uaa->device, iface_index[2], iface_index[0]);
339
340 mtx_lock(&sc->sc_mtx);
341
344
347
349
351
352 mtx_unlock(&sc->sc_mtx);
353
354 return (0); /* success */
355
356detach:
358
359 return (ENXIO); /* error */
360}
361
362static int
363g_audio_detach(device_t dev)
364{
365 struct g_audio_softc *sc = device_get_softc(dev);
366
367 DPRINTF("\n");
368
369 mtx_lock(&sc->sc_mtx);
372 mtx_unlock(&sc->sc_mtx);
373
375
378
379 mtx_destroy(&sc->sc_mtx);
380
381 return (0);
382}
383
384static int32_t
386{
387 uint32_t temp;
388 const uint32_t prime = 0xFFFF1D;
389
390 if (sc->sc_noise_rem & 1) {
391 sc->sc_noise_rem += prime;
392 }
393 sc->sc_noise_rem /= 2;
394
395 temp = sc->sc_noise_rem;
396
397 /* unsigned to signed conversion */
398
399 temp ^= 0x800000;
400 if (temp & 0x800000) {
401 temp |= (-0x800000);
402 }
403 return temp;
404}
405
406static void
407g_audio_make_samples(struct g_audio_softc *sc, int16_t *ptr, int samples)
408{
409 int i;
410 int j;
411
412 for (i = 0; i != samples; i++) {
413 j = g_noise(sc);
414
415 if ((sc->sc_state < 0) || (sc->sc_state >= sc->sc_pattern_len))
416 sc->sc_state = 0;
417
418 if (sc->sc_pattern_len != 0) {
419 j = (j * sc->sc_pattern[sc->sc_state]) >> 16;
420 sc->sc_state++;
421 }
422 *ptr++ = j / 256;
423 *ptr++ = j / 256;
424 }
425}
426
427static void
429{
430 struct g_audio_softc *sc = usbd_xfer_softc(xfer);
431 int actlen;
432 int aframes;
433 int nr = (xfer == sc->sc_xfer[G_AUDIO_ISOC0_WR]) ? 0 : 1;
434 int16_t *ptr;
435 int i;
436
437 usbd_xfer_status(xfer, &actlen, NULL, &aframes, NULL);
438
439 DPRINTF("st=%d aframes=%d actlen=%d bytes\n",
440 USB_GET_STATE(xfer), aframes, actlen);
441
442 switch (USB_GET_STATE(xfer)) {
444
445 sc->sc_throughput += actlen;
446
447 if (sc->sc_mode == G_AUDIO_MODE_LOOP)
448 break; /* sync with RX */
449
450 case USB_ST_SETUP:
451tr_setup:
452
453 ptr = sc->sc_data_buf[nr];
454
455 if (sc->sc_mode == G_AUDIO_MODE_PATTERN) {
456 for (i = 0; i != G_AUDIO_FRAMES; i++) {
457 usbd_xfer_set_frame_data(xfer, i, ptr, sc->sc_data_len[nr][i]);
458
460
461 ptr += (G_AUDIO_BUFSIZE / G_AUDIO_FRAMES) / 2;
462 }
463 } else if (sc->sc_mode == G_AUDIO_MODE_LOOP) {
464 for (i = 0; i != G_AUDIO_FRAMES; i++) {
465 usbd_xfer_set_frame_data(xfer, i, ptr, sc->sc_data_len[nr][i] & ~3);
466
467 g_audio_make_samples(sc, ptr, sc->sc_data_len[nr][i] / 4);
468
469 ptr += (G_AUDIO_BUFSIZE / G_AUDIO_FRAMES) / 2;
470 }
471 }
472 break;
473
474 default: /* Error */
475 DPRINTF("error=%s\n", usbd_errstr(error));
476
477 if (error != USB_ERR_CANCELLED) {
478 /* try to clear stall first */
480 goto tr_setup;
481 }
482 break;
483 }
484}
485
486static void
488{
489 struct g_audio_softc *sc = usbd_xfer_softc(xfer);
490 int actlen;
491 int aframes;
492 int nr = (xfer == sc->sc_xfer[G_AUDIO_ISOC0_RD]) ? 0 : 1;
493 int16_t *ptr;
494 int i;
495
496 usbd_xfer_status(xfer, &actlen, NULL, &aframes, NULL);
497
498 DPRINTF("st=%d aframes=%d actlen=%d bytes\n",
499 USB_GET_STATE(xfer), aframes, actlen);
500
501 switch (USB_GET_STATE(xfer)) {
503
504 sc->sc_throughput += actlen;
505
506 for (i = 0; i != G_AUDIO_FRAMES; i++) {
507 sc->sc_data_len[nr][i] = usbd_xfer_frame_len(xfer, i);
508 }
509
512
513 break;
514
515 case USB_ST_SETUP:
516tr_setup:
517 ptr = sc->sc_data_buf[nr];
518
519 for (i = 0; i != G_AUDIO_FRAMES; i++) {
520 usbd_xfer_set_frame_data(xfer, i, ptr,
522
523 ptr += (G_AUDIO_BUFSIZE / G_AUDIO_FRAMES) / 2;
524 }
525
527 break;
528
529 default: /* Error */
530 DPRINTF("error=%s\n", usbd_errstr(error));
531
532 if (error != USB_ERR_CANCELLED) {
533 /* try to clear stall first */
535 goto tr_setup;
536 }
537 break;
538 }
539}
540
541static int
543 const void *preq, void **pptr, uint16_t *plen,
544 uint16_t offset, uint8_t *pstate)
545{
546 struct g_audio_softc *sc = device_get_softc(dev);
547 const struct usb_device_request *req = preq;
548 uint8_t is_complete = *pstate;
549
550 if (!is_complete) {
551 if ((req->bmRequestType == UT_READ_CLASS_INTERFACE) &&
552 (req->bRequest == 0x82 /* get min */ )) {
553 if (offset == 0) {
554 USETW(sc->sc_volume_limit, 0);
555 *plen = 2;
556 *pptr = &sc->sc_volume_limit;
557 } else {
558 *plen = 0;
559 }
560 return (0);
561 } else if ((req->bmRequestType == UT_READ_CLASS_INTERFACE) &&
562 (req->bRequest == 0x83 /* get max */ )) {
563 if (offset == 0) {
564 USETW(sc->sc_volume_limit, 0x2000);
565 *plen = 2;
566 *pptr = &sc->sc_volume_limit;
567 } else {
568 *plen = 0;
569 }
570 return (0);
571 } else if ((req->bmRequestType == UT_READ_CLASS_INTERFACE) &&
572 (req->bRequest == 0x84 /* get residue */ )) {
573 if (offset == 0) {
574 USETW(sc->sc_volume_limit, 1);
575 *plen = 2;
576 *pptr = &sc->sc_volume_limit;
577 } else {
578 *plen = 0;
579 }
580 return (0);
581 } else if ((req->bmRequestType == UT_READ_CLASS_INTERFACE) &&
582 (req->bRequest == 0x81 /* get value */ )) {
583 if (offset == 0) {
584 USETW(sc->sc_volume_setting, 0x2000);
585 *plen = sizeof(sc->sc_volume_setting);
586 *pptr = &sc->sc_volume_setting;
587 } else {
588 *plen = 0;
589 }
590 return (0);
591 } else if ((req->bmRequestType == UT_WRITE_CLASS_INTERFACE) &&
592 (req->bRequest == 0x01 /* set value */ )) {
593 if (offset == 0) {
594 *plen = sizeof(sc->sc_volume_setting);
595 *pptr = &sc->sc_volume_setting;
596 } else {
597 *plen = 0;
598 }
599 return (0);
600 } else if ((req->bmRequestType == UT_WRITE_CLASS_ENDPOINT) &&
601 (req->bRequest == 0x01 /* set value */ )) {
602 if (offset == 0) {
603 *plen = sizeof(sc->sc_sample_rate);
604 *pptr = &sc->sc_sample_rate;
605 } else {
606 *plen = 0;
607 }
608 return (0);
609 }
610 }
611 return (ENXIO); /* use builtin handler */
612}
static int debug
Definition: cfumass.c:73
static const struct usb_config g_audio_config[G_AUDIO_N_TRANSFER]
Definition: g_audio.c:163
static device_detach_t g_audio_detach
Definition: g_audio.c:131
static void g_audio_timeout(void *arg)
Definition: g_audio.c:231
static void g_audio_make_samples(struct g_audio_softc *sc, int16_t *ptr, int samples)
Definition: g_audio.c:407
static SYSCTL_NODE(_hw_usb, OID_AUTO, g_audio, CTLFLAG_RW|CTLFLAG_MPSAFE, 0, "USB audio gadget")
static driver_t g_audio_driver
Definition: g_audio.c:154
static devclass_t g_audio_devclass
Definition: g_audio.c:137
static usb_handle_request_t g_audio_handle_request
Definition: g_audio.c:132
static usb_callback_t g_audio_isoc_read_callback
Definition: g_audio.c:134
SYSCTL_STRING(_hw_usb_g_audio, OID_AUTO, pattern, CTLFLAG_RW, &g_audio_pattern_data, sizeof(g_audio_pattern_data), "Data pattern")
static void g_audio_timeout_reset(struct g_audio_softc *sc)
Definition: g_audio.c:214
__FBSDID("$FreeBSD$")
static int32_t g_noise(struct g_audio_softc *sc)
Definition: g_audio.c:385
static device_method_t g_audio_methods[]
Definition: g_audio.c:142
static int g_audio_throughput
Definition: g_audio.c:124
static char g_audio_pattern_data[G_AUDIO_MAX_STRLEN]
Definition: g_audio.c:119
static int g_audio_pattern_interval
Definition: g_audio.c:114
static int g_audio_mode
Definition: g_audio.c:109
@ G_AUDIO_ISOC1_RD
Definition: g_audio.c:69
@ G_AUDIO_N_TRANSFER
Definition: g_audio.c:72
@ G_AUDIO_ISOC0_RD
Definition: g_audio.c:68
@ G_AUDIO_ISOC0_WR
Definition: g_audio.c:70
@ G_AUDIO_ISOC1_WR
Definition: g_audio.c:71
static usb_callback_t g_audio_isoc_write_callback
Definition: g_audio.c:135
DRIVER_MODULE(g_audio, uhub, g_audio_driver, g_audio_devclass, 0, 0)
static device_probe_t g_audio_probe
Definition: g_audio.c:129
static device_attach_t g_audio_attach
Definition: g_audio.c:130
MODULE_DEPEND(g_audio, usb, 1, 1, 1)
static void g_audio_watchdog(void *arg)
Definition: g_audio.c:257
static void g_audio_watchdog_reset(struct g_audio_softc *sc)
Definition: g_audio.c:251
SYSCTL_INT(_hw_usb_g_audio, OID_AUTO, mode, CTLFLAG_RWTUN, &g_audio_mode, 0, "Mode selection")
#define G_AUDIO_MODE_PATTERN
Definition: g_audio.h:39
#define G_AUDIO_MAX_STRLEN
Definition: g_audio.h:32
#define G_AUDIO_FRAMES
Definition: g_audio.h:33
#define G_AUDIO_MODE_SILENT
Definition: g_audio.h:36
#define G_AUDIO_MODE_LOOP
Definition: g_audio.h:38
#define G_AUDIO_BUFSIZE
Definition: g_audio.h:34
struct @109 error
device_t dev
int sc_tx_interval
Definition: g_audio.c:84
int sc_mode
Definition: g_audio.c:81
int sc_state
Definition: g_audio.c:85
struct mtx sc_mtx
Definition: g_audio.c:76
int8_t sc_pattern[G_AUDIO_MAX_STRLEN]
Definition: g_audio.c:88
uint8_t sc_sample_rate[32]
Definition: g_audio.c:96
uint8_t sc_volume_setting[32]
Definition: g_audio.c:94
uint8_t sc_volume_limit[32]
Definition: g_audio.c:95
struct usb_callout sc_callout
Definition: g_audio.c:77
struct usb_callout sc_watchdog
Definition: g_audio.c:78
int16_t sc_data_buf[2][G_AUDIO_BUFSIZE/2]
Definition: g_audio.c:92
uint16_t sc_data_len[2][G_AUDIO_FRAMES]
Definition: g_audio.c:90
int sc_noise_rem
Definition: g_audio.c:86
struct usb_xfer * sc_xfer[G_AUDIO_N_TRANSFER]
Definition: g_audio.c:79
int sc_throughput
Definition: g_audio.c:83
int sc_pattern_len
Definition: g_audio.c:82
enum usb_hc_mode usb_mode
Definition: usbdi.h:432
struct usbd_lookup_info info
Definition: usbdi.h:426
struct usb_device * device
Definition: usbdi.h:430
uint8_t type
Definition: usbdi.h:238
uint8_t bIfaceIndex
Definition: usbdi.h:417
uint8_t bInterfaceSubClass
Definition: usbdi.h:415
uint8_t bInterfaceClass
Definition: usbdi.h:414
#define DPRINTF(...)
Definition: umass.c:179
#define UE_ADDR_ANY
Definition: usb.h:537
#define UT_READ_CLASS_INTERFACE
Definition: usb.h:173
#define UE_DIR_RX
Definition: usb.h:533
@ USB_MODE_DEVICE
Definition: usb.h:779
#define UICLASS_AUDIO
Definition: usb.h:429
#define UISUBCLASS_AUDIOCONTROL
Definition: usb.h:430
#define UE_DIR_TX
Definition: usb.h:534
#define UT_WRITE_CLASS_INTERFACE
Definition: usb.h:177
#define UT_WRITE_CLASS_ENDPOINT
Definition: usb.h:179
#define UE_ISOCHRONOUS
Definition: usb.h:542
usb_error_t usbd_set_alt_interface_index(struct usb_device *udev, uint8_t iface_index, uint8_t alt_index)
Definition: usb_device.c:1034
void usbd_set_parent_iface(struct usb_device *udev, uint8_t iface_index, uint8_t parent_index)
Definition: usb_device.c:1395
#define USETW(w, v)
Definition: usb_endian.h:77
const char * usbd_errstr(usb_error_t err)
Definition: usb_error.c:93
static usb_error_t usb_handle_request(struct usb_xfer *)
void ** pptr
Definition: usb_if.m:52
uint8_t * pstate
Definition: usb_if.m:55
uint16_t * plen
Definition: usb_if.m:53
uint16_t offset
Definition: usb_if.m:54
const void * req
Definition: usb_if.m:51
INTERFACE usb
Definition: usb_if.m:35
void usbd_transfer_submit(struct usb_xfer *xfer)
void usbd_transfer_unsetup(struct usb_xfer **pxfer, uint16_t n_setup)
void usbd_xfer_set_frame_data(struct usb_xfer *xfer, usb_frcount_t frindex, void *ptr, usb_frlength_t len)
usb_frlength_t usbd_xfer_frame_len(struct usb_xfer *xfer, usb_frcount_t frindex)
usb_error_t usbd_transfer_setup(struct usb_device *udev, const uint8_t *ifaces, struct usb_xfer **ppxfer, const struct usb_config *setup_start, uint16_t n_setup, void *priv_sc, struct mtx *xfer_mtx)
Definition: usb_transfer.c:987
void usbd_transfer_start(struct usb_xfer *xfer)
void * usbd_xfer_softc(struct usb_xfer *xfer)
void usbd_xfer_set_stall(struct usb_xfer *xfer)
void usbd_xfer_status(struct usb_xfer *xfer, int *actlen, int *sumlen, int *aframes, int *nframes)
void device_set_usb_desc(device_t dev)
Definition: usb_util.c:73
#define usb_callout_init_mtx(c, m, f)
Definition: usbdi.h:480
#define USB_ST_SETUP
Definition: usbdi.h:502
#define usb_callout_reset(c,...)
Definition: usbdi.h:481
usb_error_t
Definition: usbdi.h:45
@ USB_ERR_CANCELLED
Definition: usbdi.h:51
#define usb_callout_drain(c)
Definition: usbdi.h:497
#define USB_ST_TRANSFERRED
Definition: usbdi.h:503
#define USB_MS_TO_TICKS(ms)
Definition: usbdi.h:120
void() usb_callback_t(struct usb_xfer *, usb_error_t)
Definition: usbdi.h:94
#define usb_callout_stop(c)
Definition: usbdi.h:489
#define USB_GET_STATE(xfer)
Definition: usbdi.h:515