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