1/*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2009 Sylvestre Gallon. 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#ifdef LIBUSB_GLOBAL_INCLUDE_FILE
29#include LIBUSB_GLOBAL_INCLUDE_FILE
30#else
31#include <errno.h>
32#include <poll.h>
33#include <pthread.h>
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37#include <time.h>
38#include <unistd.h>
39#include <sys/queue.h>
40#include <sys/endian.h>
41#endif
42
43#define	libusb_device_handle libusb20_device
44
45#include "libusb20.h"
46#include "libusb20_desc.h"
47#include "libusb20_int.h"
48#include "libusb.h"
49#include "libusb10.h"
50
51UNEXPORTED void
52libusb10_add_pollfd(libusb_context *ctx, struct libusb_super_pollfd *pollfd,
53    struct libusb20_device *pdev, int fd, short events)
54{
55	if (ctx == NULL)
56		return;			/* invalid */
57
58	if (pollfd->entry.tqe_prev != NULL)
59		return;			/* already queued */
60
61	if (fd < 0)
62		return;			/* invalid */
63
64	pollfd->pdev = pdev;
65	pollfd->pollfd.fd = fd;
66	pollfd->pollfd.events = events;
67
68	CTX_LOCK(ctx);
69	TAILQ_INSERT_TAIL(&ctx->pollfds, pollfd, entry);
70	CTX_UNLOCK(ctx);
71
72	if (ctx->fd_added_cb)
73		ctx->fd_added_cb(fd, events, ctx->fd_cb_user_data);
74}
75
76UNEXPORTED void
77libusb10_remove_pollfd(libusb_context *ctx, struct libusb_super_pollfd *pollfd)
78{
79	if (ctx == NULL)
80		return;			/* invalid */
81
82	if (pollfd->entry.tqe_prev == NULL)
83		return;			/* already dequeued */
84
85	CTX_LOCK(ctx);
86	TAILQ_REMOVE(&ctx->pollfds, pollfd, entry);
87	pollfd->entry.tqe_prev = NULL;
88	CTX_UNLOCK(ctx);
89
90	if (ctx->fd_removed_cb)
91		ctx->fd_removed_cb(pollfd->pollfd.fd, ctx->fd_cb_user_data);
92}
93
94/* This function must be called locked */
95
96static int
97libusb10_handle_events_sub(struct libusb_context *ctx, struct timeval *tv)
98{
99	struct libusb_device *dev;
100	struct libusb20_device **ppdev;
101	struct libusb_super_pollfd *pfd;
102	struct pollfd *fds;
103	struct libusb_super_transfer *sxfer;
104	struct libusb_transfer *uxfer;
105	nfds_t nfds;
106	int timeout;
107	int i;
108	int err;
109
110	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb10_handle_events_sub enter");
111
112	nfds = 0;
113	i = 0;
114	TAILQ_FOREACH(pfd, &ctx->pollfds, entry)
115	    nfds++;
116
117	fds = alloca(sizeof(*fds) * nfds);
118	if (fds == NULL)
119		return (LIBUSB_ERROR_NO_MEM);
120
121	ppdev = alloca(sizeof(*ppdev) * nfds);
122	if (ppdev == NULL)
123		return (LIBUSB_ERROR_NO_MEM);
124
125	TAILQ_FOREACH(pfd, &ctx->pollfds, entry) {
126		fds[i].fd = pfd->pollfd.fd;
127		fds[i].events = pfd->pollfd.events;
128		fds[i].revents = 0;
129		ppdev[i] = pfd->pdev;
130		if (pfd->pdev != NULL)
131			libusb_get_device(pfd->pdev)->refcnt++;
132		i++;
133	}
134
135	if (tv == NULL)
136		timeout = -1;
137	else
138		timeout = (tv->tv_sec * 1000) + ((tv->tv_usec + 999) / 1000);
139
140	CTX_UNLOCK(ctx);
141	err = poll(fds, nfds, timeout);
142	CTX_LOCK(ctx);
143
144	if ((err == -1) && (errno == EINTR))
145		err = LIBUSB_ERROR_INTERRUPTED;
146	else if (err < 0)
147		err = LIBUSB_ERROR_IO;
148
149	if (err < 1) {
150		for (i = 0; i != (int)nfds; i++) {
151			if (ppdev[i] != NULL) {
152				CTX_UNLOCK(ctx);
153				libusb_unref_device(libusb_get_device(ppdev[i]));
154				CTX_LOCK(ctx);
155			}
156		}
157		goto do_done;
158	}
159	for (i = 0; i != (int)nfds; i++) {
160		if (ppdev[i] != NULL) {
161			dev = libusb_get_device(ppdev[i]);
162
163			if (fds[i].revents != 0) {
164				err = libusb20_dev_process(ppdev[i]);
165
166				if (err) {
167					/*
168					 * When the device is opened
169					 * set the "device_is_gone"
170					 * flag. This prevents the
171					 * client from submitting new
172					 * USB transfers to a detached
173					 * device.
174					 */
175					if (ppdev[i]->is_opened)
176						dev->device_is_gone = 1;
177
178					/* remove USB device from polling loop */
179					libusb10_remove_pollfd(dev->ctx, &dev->dev_poll);
180
181					/* cancel all pending transfers */
182					libusb10_cancel_all_transfer_locked(ppdev[i], dev);
183				}
184			}
185			CTX_UNLOCK(ctx);
186			libusb_unref_device(dev);
187			CTX_LOCK(ctx);
188
189		} else {
190			uint8_t dummy;
191
192			while (read(fds[i].fd, &dummy, 1) == 1)
193				;
194		}
195	}
196
197	err = 0;
198
199do_done:
200
201	/* Do all done callbacks */
202
203	while ((sxfer = TAILQ_FIRST(&ctx->tr_done))) {
204		uint8_t flags;
205
206		TAILQ_REMOVE(&ctx->tr_done, sxfer, entry);
207		sxfer->entry.tqe_prev = NULL;
208
209		ctx->tr_done_ref++;
210
211		CTX_UNLOCK(ctx);
212
213		uxfer = (struct libusb_transfer *)(
214		    ((uint8_t *)sxfer) + sizeof(*sxfer));
215
216		/* Allow the callback to free the transfer itself. */
217		flags = uxfer->flags;
218
219		if (uxfer->callback != NULL)
220			(uxfer->callback) (uxfer);
221
222		/* Check if the USB transfer should be automatically freed. */
223		if (flags & LIBUSB_TRANSFER_FREE_TRANSFER)
224			libusb_free_transfer(uxfer);
225
226		CTX_LOCK(ctx);
227
228		ctx->tr_done_ref--;
229		ctx->tr_done_gen++;
230	}
231
232	/* Wakeup other waiters */
233	pthread_cond_broadcast(&ctx->ctx_cond);
234
235	return (err);
236}
237
238/* Polling and timing */
239
240int
241libusb_try_lock_events(libusb_context *ctx)
242{
243	int err;
244
245	ctx = GET_CONTEXT(ctx);
246	if (ctx == NULL)
247		return (1);
248
249	err = CTX_TRYLOCK(ctx);
250	if (err)
251		return (1);
252
253	err = (ctx->ctx_handler != NO_THREAD);
254	if (err)
255		CTX_UNLOCK(ctx);
256	else
257		ctx->ctx_handler = pthread_self();
258
259	return (err);
260}
261
262void
263libusb_lock_events(libusb_context *ctx)
264{
265	ctx = GET_CONTEXT(ctx);
266	CTX_LOCK(ctx);
267	if (ctx->ctx_handler == NO_THREAD)
268		ctx->ctx_handler = pthread_self();
269}
270
271void
272libusb_unlock_events(libusb_context *ctx)
273{
274	ctx = GET_CONTEXT(ctx);
275	if (ctx->ctx_handler == pthread_self()) {
276		ctx->ctx_handler = NO_THREAD;
277		pthread_cond_broadcast(&ctx->ctx_cond);
278	}
279	CTX_UNLOCK(ctx);
280}
281
282int
283libusb_event_handling_ok(libusb_context *ctx)
284{
285	ctx = GET_CONTEXT(ctx);
286	return (ctx->ctx_handler == pthread_self());
287}
288
289int
290libusb_event_handler_active(libusb_context *ctx)
291{
292	ctx = GET_CONTEXT(ctx);
293	return (ctx->ctx_handler != NO_THREAD);
294}
295
296void
297libusb_lock_event_waiters(libusb_context *ctx)
298{
299	ctx = GET_CONTEXT(ctx);
300	CTX_LOCK(ctx);
301}
302
303void
304libusb_unlock_event_waiters(libusb_context *ctx)
305{
306	ctx = GET_CONTEXT(ctx);
307	CTX_UNLOCK(ctx);
308}
309
310int
311libusb_wait_for_event(libusb_context *ctx, struct timeval *tv)
312{
313	struct timespec ts;
314	int err;
315
316	ctx = GET_CONTEXT(ctx);
317	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_wait_for_event enter");
318
319	if (tv == NULL) {
320		pthread_cond_wait(&ctx->ctx_cond,
321		    &ctx->ctx_lock);
322		/* try to grab polling of actual events, if any */
323		if (ctx->ctx_handler == NO_THREAD)
324			ctx->ctx_handler = pthread_self();
325		return (0);
326	}
327	err = clock_gettime(CLOCK_MONOTONIC, &ts);
328	if (err < 0)
329		return (LIBUSB_ERROR_OTHER);
330
331	/*
332	 * The "tv" arguments points to a relative time structure and
333	 * not an absolute time structure.
334	 */
335	ts.tv_sec += tv->tv_sec;
336	ts.tv_nsec += tv->tv_usec * 1000;
337	if (ts.tv_nsec >= 1000000000) {
338		ts.tv_nsec -= 1000000000;
339		ts.tv_sec++;
340	}
341	err = pthread_cond_timedwait(&ctx->ctx_cond,
342	    &ctx->ctx_lock, &ts);
343	/* try to grab polling of actual events, if any */
344	if (ctx->ctx_handler == NO_THREAD)
345		ctx->ctx_handler = pthread_self();
346
347	if (err == ETIMEDOUT)
348		return (1);
349
350	return (0);
351}
352
353int
354libusb_handle_events_timeout_completed(libusb_context *ctx,
355    struct timeval *tv, int *completed)
356{
357	int err = 0;
358
359	ctx = GET_CONTEXT(ctx);
360
361	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_handle_events_timeout_completed enter");
362
363	libusb_lock_events(ctx);
364
365	while (1) {
366		if (completed != NULL) {
367			if (*completed != 0 || err != 0)
368				break;
369		}
370		err = libusb_handle_events_locked(ctx, tv);
371		if (completed == NULL)
372			break;
373	}
374
375	libusb_unlock_events(ctx);
376
377	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_handle_events_timeout_completed exit");
378
379	return (err);
380}
381
382int
383libusb_handle_events_completed(libusb_context *ctx, int *completed)
384{
385	return (libusb_handle_events_timeout_completed(ctx, NULL, completed));
386}
387
388int
389libusb_handle_events_timeout(libusb_context *ctx, struct timeval *tv)
390{
391	return (libusb_handle_events_timeout_completed(ctx, tv, NULL));
392}
393
394int
395libusb_handle_events(libusb_context *ctx)
396{
397	return (libusb_handle_events_timeout_completed(ctx, NULL, NULL));
398}
399
400int
401libusb_handle_events_locked(libusb_context *ctx, struct timeval *tv)
402{
403	int err;
404
405	ctx = GET_CONTEXT(ctx);
406
407	if (libusb_event_handling_ok(ctx)) {
408		err = libusb10_handle_events_sub(ctx, tv);
409	} else {
410		err = libusb_wait_for_event(ctx, tv);
411		if (err != 0)
412			err = LIBUSB_ERROR_TIMEOUT;
413	}
414	return (err);
415}
416
417int
418libusb_get_next_timeout(libusb_context *ctx, struct timeval *tv)
419{
420	/* all timeouts are currently being done by the kernel */
421	timerclear(tv);
422	return (0);
423}
424
425void
426libusb_set_pollfd_notifiers(libusb_context *ctx,
427    libusb_pollfd_added_cb added_cb, libusb_pollfd_removed_cb removed_cb,
428    void *user_data)
429{
430	ctx = GET_CONTEXT(ctx);
431
432	ctx->fd_added_cb = added_cb;
433	ctx->fd_removed_cb = removed_cb;
434	ctx->fd_cb_user_data = user_data;
435}
436
437const struct libusb_pollfd **
438libusb_get_pollfds(libusb_context *ctx)
439{
440	struct libusb_super_pollfd *pollfd;
441	libusb_pollfd **ret;
442	int i;
443
444	ctx = GET_CONTEXT(ctx);
445
446	CTX_LOCK(ctx);
447
448	i = 0;
449	TAILQ_FOREACH(pollfd, &ctx->pollfds, entry)
450	    i++;
451
452	ret = calloc(i + 1, sizeof(struct libusb_pollfd *));
453	if (ret == NULL)
454		goto done;
455
456	i = 0;
457	TAILQ_FOREACH(pollfd, &ctx->pollfds, entry)
458	    ret[i++] = &pollfd->pollfd;
459	ret[i] = NULL;
460
461done:
462	CTX_UNLOCK(ctx);
463	return ((const struct libusb_pollfd **)ret);
464}
465
466
467/* Synchronous device I/O */
468
469int
470libusb_control_transfer(libusb_device_handle *devh,
471    uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex,
472    uint8_t *data, uint16_t wLength, unsigned int timeout)
473{
474	struct LIBUSB20_CONTROL_SETUP_DECODED req;
475	int err;
476	uint16_t actlen;
477
478	if (devh == NULL)
479		return (LIBUSB_ERROR_INVALID_PARAM);
480
481	if ((wLength != 0) && (data == NULL))
482		return (LIBUSB_ERROR_INVALID_PARAM);
483
484	LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &req);
485
486	req.bmRequestType = bmRequestType;
487	req.bRequest = bRequest;
488	req.wValue = wValue;
489	req.wIndex = wIndex;
490	req.wLength = wLength;
491
492	err = libusb20_dev_request_sync(devh, &req, data,
493	    &actlen, timeout, 0);
494
495	if (err == LIBUSB20_ERROR_PIPE)
496		return (LIBUSB_ERROR_PIPE);
497	else if (err == LIBUSB20_ERROR_TIMEOUT)
498		return (LIBUSB_ERROR_TIMEOUT);
499	else if (err)
500		return (LIBUSB_ERROR_NO_DEVICE);
501
502	return (actlen);
503}
504
505static libusb_context *
506libusb10_get_context_by_device_handle(libusb_device_handle *devh)
507{
508	libusb_context *ctx;
509
510	if (devh != NULL)
511		ctx = libusb_get_device(devh)->ctx;
512	else
513		ctx = NULL;
514
515	return (GET_CONTEXT(ctx));
516}
517
518static void
519libusb10_do_transfer_cb(struct libusb_transfer *transfer)
520{
521	libusb_context *ctx;
522	int *pdone;
523
524	ctx = libusb10_get_context_by_device_handle(transfer->dev_handle);
525
526	DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "sync I/O done");
527
528	pdone = transfer->user_data;
529	*pdone = 1;
530}
531
532/*
533 * TODO: Replace the following function. Allocating and freeing on a
534 * per-transfer basis is slow.  --HPS
535 */
536static int
537libusb10_do_transfer(libusb_device_handle *devh,
538    uint8_t endpoint, uint8_t *data, int length,
539    int *transferred, unsigned int timeout, int type)
540{
541	libusb_context *ctx;
542	struct libusb_transfer *xfer;
543	int done;
544	int ret;
545
546	if (devh == NULL)
547		return (LIBUSB_ERROR_INVALID_PARAM);
548
549	if ((length != 0) && (data == NULL))
550		return (LIBUSB_ERROR_INVALID_PARAM);
551
552	xfer = libusb_alloc_transfer(0);
553	if (xfer == NULL)
554		return (LIBUSB_ERROR_NO_MEM);
555
556	ctx = libusb_get_device(devh)->ctx;
557
558	xfer->dev_handle = devh;
559	xfer->endpoint = endpoint;
560	xfer->type = type;
561	xfer->timeout = timeout;
562	xfer->buffer = data;
563	xfer->length = length;
564	xfer->user_data = (void *)&done;
565	xfer->callback = libusb10_do_transfer_cb;
566	done = 0;
567
568	if ((ret = libusb_submit_transfer(xfer)) < 0) {
569		libusb_free_transfer(xfer);
570		return (ret);
571	}
572	while (done == 0) {
573		if ((ret = libusb_handle_events(ctx)) < 0) {
574			libusb_cancel_transfer(xfer);
575			usleep(1000);	/* nice it */
576		}
577	}
578
579	*transferred = xfer->actual_length;
580
581	switch (xfer->status) {
582	case LIBUSB_TRANSFER_COMPLETED:
583		ret = 0;
584		break;
585	case LIBUSB_TRANSFER_TIMED_OUT:
586		ret = LIBUSB_ERROR_TIMEOUT;
587		break;
588	case LIBUSB_TRANSFER_OVERFLOW:
589		ret = LIBUSB_ERROR_OVERFLOW;
590		break;
591	case LIBUSB_TRANSFER_STALL:
592		ret = LIBUSB_ERROR_PIPE;
593		break;
594	case LIBUSB_TRANSFER_NO_DEVICE:
595		ret = LIBUSB_ERROR_NO_DEVICE;
596		break;
597	default:
598		ret = LIBUSB_ERROR_OTHER;
599		break;
600	}
601
602	libusb_free_transfer(xfer);
603	return (ret);
604}
605
606int
607libusb_bulk_transfer(libusb_device_handle *devh,
608    uint8_t endpoint, uint8_t *data, int length,
609    int *transferred, unsigned int timeout)
610{
611	libusb_context *ctx;
612	int ret;
613
614	ctx = libusb10_get_context_by_device_handle(devh);
615
616	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_bulk_transfer enter");
617
618	ret = libusb10_do_transfer(devh, endpoint, data, length, transferred,
619	    timeout, LIBUSB_TRANSFER_TYPE_BULK);
620
621	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_bulk_transfer leave");
622	return (ret);
623}
624
625int
626libusb_interrupt_transfer(libusb_device_handle *devh,
627    uint8_t endpoint, uint8_t *data, int length,
628    int *transferred, unsigned int timeout)
629{
630	libusb_context *ctx;
631	int ret;
632
633	ctx = libusb10_get_context_by_device_handle(devh);
634
635	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_interrupt_transfer enter");
636
637	ret = libusb10_do_transfer(devh, endpoint, data, length, transferred,
638	    timeout, LIBUSB_TRANSFER_TYPE_INTERRUPT);
639
640	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_interrupt_transfer leave");
641	return (ret);
642}
643
644uint8_t *
645libusb_get_iso_packet_buffer(struct libusb_transfer *transfer, uint32_t off)
646{
647	uint8_t *ptr;
648	uint32_t n;
649
650	if (transfer->num_iso_packets < 0)
651		return (NULL);
652
653	if (off >= (uint32_t)transfer->num_iso_packets)
654		return (NULL);
655
656	ptr = transfer->buffer;
657	if (ptr == NULL)
658		return (NULL);
659
660	for (n = 0; n != off; n++) {
661		ptr += transfer->iso_packet_desc[n].length;
662	}
663	return (ptr);
664}
665
666uint8_t *
667libusb_get_iso_packet_buffer_simple(struct libusb_transfer *transfer, uint32_t off)
668{
669	uint8_t *ptr;
670
671	if (transfer->num_iso_packets < 0)
672		return (NULL);
673
674	if (off >= (uint32_t)transfer->num_iso_packets)
675		return (NULL);
676
677	ptr = transfer->buffer;
678	if (ptr == NULL)
679		return (NULL);
680
681	ptr += transfer->iso_packet_desc[0].length * off;
682
683	return (ptr);
684}
685
686void
687libusb_set_iso_packet_lengths(struct libusb_transfer *transfer, uint32_t length)
688{
689	int n;
690
691	if (transfer->num_iso_packets < 0)
692		return;
693
694	for (n = 0; n != transfer->num_iso_packets; n++)
695		transfer->iso_packet_desc[n].length = length;
696}
697
698uint8_t *
699libusb_control_transfer_get_data(struct libusb_transfer *transfer)
700{
701	if (transfer->buffer == NULL)
702		return (NULL);
703
704	return (transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE);
705}
706
707struct libusb_control_setup *
708libusb_control_transfer_get_setup(struct libusb_transfer *transfer)
709{
710	return ((struct libusb_control_setup *)transfer->buffer);
711}
712
713void
714libusb_fill_control_setup(uint8_t *buf, uint8_t bmRequestType,
715    uint8_t bRequest, uint16_t wValue,
716    uint16_t wIndex, uint16_t wLength)
717{
718	struct libusb_control_setup *req = (struct libusb_control_setup *)buf;
719
720	/* The alignment is OK for all fields below. */
721	req->bmRequestType = bmRequestType;
722	req->bRequest = bRequest;
723	req->wValue = htole16(wValue);
724	req->wIndex = htole16(wIndex);
725	req->wLength = htole16(wLength);
726}
727
728void
729libusb_fill_control_transfer(struct libusb_transfer *transfer,
730    libusb_device_handle *devh, uint8_t *buf,
731    libusb_transfer_cb_fn callback, void *user_data,
732    uint32_t timeout)
733{
734	struct libusb_control_setup *setup = (struct libusb_control_setup *)buf;
735
736	transfer->dev_handle = devh;
737	transfer->endpoint = 0;
738	transfer->type = LIBUSB_TRANSFER_TYPE_CONTROL;
739	transfer->timeout = timeout;
740	transfer->buffer = buf;
741	if (setup != NULL)
742		transfer->length = LIBUSB_CONTROL_SETUP_SIZE
743			+ le16toh(setup->wLength);
744	else
745		transfer->length = 0;
746	transfer->user_data = user_data;
747	transfer->callback = callback;
748
749}
750
751void
752libusb_fill_bulk_transfer(struct libusb_transfer *transfer,
753    libusb_device_handle *devh, uint8_t endpoint, uint8_t *buf,
754    int length, libusb_transfer_cb_fn callback, void *user_data,
755    uint32_t timeout)
756{
757	transfer->dev_handle = devh;
758	transfer->endpoint = endpoint;
759	transfer->type = LIBUSB_TRANSFER_TYPE_BULK;
760	transfer->timeout = timeout;
761	transfer->buffer = buf;
762	transfer->length = length;
763	transfer->user_data = user_data;
764	transfer->callback = callback;
765}
766
767void
768libusb_fill_interrupt_transfer(struct libusb_transfer *transfer,
769    libusb_device_handle *devh, uint8_t endpoint, uint8_t *buf,
770    int length, libusb_transfer_cb_fn callback, void *user_data,
771    uint32_t timeout)
772{
773	transfer->dev_handle = devh;
774	transfer->endpoint = endpoint;
775	transfer->type = LIBUSB_TRANSFER_TYPE_INTERRUPT;
776	transfer->timeout = timeout;
777	transfer->buffer = buf;
778	transfer->length = length;
779	transfer->user_data = user_data;
780	transfer->callback = callback;
781}
782
783void
784libusb_fill_iso_transfer(struct libusb_transfer *transfer,
785    libusb_device_handle *devh, uint8_t endpoint, uint8_t *buf,
786    int length, int npacket, libusb_transfer_cb_fn callback,
787    void *user_data, uint32_t timeout)
788{
789	transfer->dev_handle = devh;
790	transfer->endpoint = endpoint;
791	transfer->type = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS;
792	transfer->timeout = timeout;
793	transfer->buffer = buf;
794	transfer->length = length;
795	transfer->num_iso_packets = npacket;
796	transfer->user_data = user_data;
797	transfer->callback = callback;
798}
799
800int
801libusb_alloc_streams(libusb_device_handle *dev, uint32_t num_streams,
802    unsigned char *endpoints, int num_endpoints)
803{
804	if (num_streams > 1)
805		return (LIBUSB_ERROR_INVALID_PARAM);
806	return (0);
807}
808
809int
810libusb_free_streams(libusb_device_handle *dev, unsigned char *endpoints, int num_endpoints)
811{
812
813	return (0);
814}
815
816void
817libusb_transfer_set_stream_id(struct libusb_transfer *transfer, uint32_t stream_id)
818{
819	struct libusb_super_transfer *sxfer;
820
821	if (transfer == NULL)
822		return;
823
824	sxfer = (struct libusb_super_transfer *)(
825	    ((uint8_t *)transfer) - sizeof(*sxfer));
826
827	/* set stream ID */
828	sxfer->stream_id = stream_id;
829}
830
831uint32_t
832libusb_transfer_get_stream_id(struct libusb_transfer *transfer)
833{
834	struct libusb_super_transfer *sxfer;
835
836	if (transfer == NULL)
837		return (0);
838
839	sxfer = (struct libusb_super_transfer *)(
840	    ((uint8_t *)transfer) - sizeof(*sxfer));
841
842	/* get stream ID */
843	return (sxfer->stream_id);
844}
845