xref: /freebsd/lib/libusb/libusb10.c (revision 872065688515c0c4549b568f7573eb9e7deeedd7)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2009 Sylvestre Gallon. All rights reserved.
5  * Copyright (c) 2009-2023 Hans Petter Selasky
6  * Copyright (c) 2024 Aymeric Wibo
7  * Copyright (c) 2025 ShengYi Hung
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
30 
31 #ifdef LIBUSB_GLOBAL_INCLUDE_FILE
32 #include LIBUSB_GLOBAL_INCLUDE_FILE
33 #else
34 #include <assert.h>
35 #include <ctype.h>
36 #include <errno.h>
37 #include <poll.h>
38 #include <pthread.h>
39 #include <signal.h>
40 #include <stdarg.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <unistd.h>
45 #include <time.h>
46 #include <sys/eventfd.h>
47 #include <sys/fcntl.h>
48 #include <sys/ioctl.h>
49 #include <sys/queue.h>
50 #include <sys/endian.h>
51 #endif
52 
53 #define	libusb_device_handle libusb20_device
54 #define	LIBUSB_LOG_BUFFER_SIZE 1024
55 
56 #include "libusb20.h"
57 #include "libusb20_desc.h"
58 #include "libusb20_int.h"
59 #include "libusb.h"
60 #include "libusb10.h"
61 
62 #define	LIBUSB_NUM_SW_ENDPOINTS	(16 * 4)
63 
64 static pthread_mutex_t default_context_lock = PTHREAD_MUTEX_INITIALIZER;
65 struct libusb_context *usbi_default_context = NULL;
66 
67 /* Prototypes */
68 
69 static struct libusb20_transfer *libusb10_get_transfer(struct libusb20_device *, uint8_t, uint8_t);
70 static int libusb10_get_buffsize(struct libusb20_device *, libusb_transfer *);
71 static int libusb10_convert_error(uint8_t status);
72 static void libusb10_complete_transfer(struct libusb20_transfer *, struct libusb_super_transfer *, int);
73 static void libusb10_isoc_proxy(struct libusb20_transfer *);
74 static void libusb10_bulk_intr_proxy(struct libusb20_transfer *);
75 static void libusb10_ctrl_proxy(struct libusb20_transfer *);
76 static void libusb10_submit_transfer_sub(struct libusb20_device *, uint8_t);
77 
78 /*  Library initialisation / deinitialisation */
79 
80 static const struct libusb_version libusb_version = {
81 	.major = 1,
82 	.minor = 0,
83 	.micro = 0,
84 	.nano = 2016,
85 	.rc = "",
86 	.describe = "https://www.freebsd.org"
87 };
88 
89 static const struct libusb_language_context libusb_language_ctx[] = {
90 	{
91 	    .lang_name = "en",
92 	    .err_strs = {
93 			[-LIBUSB_SUCCESS] = "Success",
94 			[-LIBUSB_ERROR_IO] = "I/O error",
95 			[-LIBUSB_ERROR_INVALID_PARAM] = "Invalid parameter",
96 			[-LIBUSB_ERROR_ACCESS] = "Permissions error",
97 			[-LIBUSB_ERROR_NO_DEVICE] = "No device",
98 			[-LIBUSB_ERROR_NOT_FOUND] = "Not found",
99 			[-LIBUSB_ERROR_BUSY] = "Device busy",
100 			[-LIBUSB_ERROR_TIMEOUT] = "Timeout",
101 			[-LIBUSB_ERROR_OVERFLOW] = "Overflow",
102 			[-LIBUSB_ERROR_PIPE] = "Pipe error",
103 			[-LIBUSB_ERROR_INTERRUPTED] = "Interrupted",
104 			[-LIBUSB_ERROR_NO_MEM] = "Out of memory",
105 			[-LIBUSB_ERROR_NOT_SUPPORTED]  ="Not supported",
106 			[LIBUSB_ERROR_COUNT - 1] = "Other error",
107 			[LIBUSB_ERROR_COUNT] = "Unknown error",
108 		}
109 	},
110 	{
111 		.lang_name = "zh",
112 		.err_strs = {
113 			[-LIBUSB_SUCCESS] = "成功",
114 			[-LIBUSB_ERROR_IO] = "I/O 錯誤",
115 			[-LIBUSB_ERROR_INVALID_PARAM] = "不合法的參數",
116 			[-LIBUSB_ERROR_ACCESS] = "權限錯誤",
117 			[-LIBUSB_ERROR_NO_DEVICE] = "裝置不存在",
118 			[-LIBUSB_ERROR_NOT_FOUND] = "不存在",
119 			[-LIBUSB_ERROR_BUSY] = "裝置忙碌中",
120 			[-LIBUSB_ERROR_TIMEOUT] = "逾時",
121 			[-LIBUSB_ERROR_OVERFLOW] = "溢位",
122 			[-LIBUSB_ERROR_PIPE] = "管道錯誤",
123 			[-LIBUSB_ERROR_INTERRUPTED] = "被中斷",
124 			[-LIBUSB_ERROR_NO_MEM] = "記憶體不足",
125 			[-LIBUSB_ERROR_NOT_SUPPORTED]  ="不支援",
126 			[LIBUSB_ERROR_COUNT - 1] = "其他錯誤",
127 			[LIBUSB_ERROR_COUNT] = "未知錯誤",
128 		}
129 	},
130 };
131 
132 static const struct libusb_language_context *default_language_context =
133     &libusb_language_ctx[0];
134 
135 const struct libusb_version *
libusb_get_version(void)136 libusb_get_version(void)
137 {
138 
139 	return (&libusb_version);
140 }
141 
142 void
libusb_set_debug(libusb_context * ctx,int level)143 libusb_set_debug(libusb_context *ctx, int level)
144 {
145 	ctx = GET_CONTEXT(ctx);
146 	/* debug_fixed is set when the environment overrides libusb_set_debug */
147 	if (ctx && ctx->debug_fixed == 0)
148 		ctx->debug = level;
149 }
150 
151 static void
libusb_set_nonblocking(int f)152 libusb_set_nonblocking(int f)
153 {
154 	int flags;
155 
156 	/*
157 	 * We ignore any failures in this function, hence the
158 	 * non-blocking flag is not critical to the operation of
159 	 * libUSB. We use F_GETFL and F_SETFL to be compatible with
160 	 * Linux.
161 	 */
162 
163 	flags = fcntl(f, F_GETFL, NULL);
164 	if (flags == -1)
165 		return;
166 	flags |= O_NONBLOCK;
167 	fcntl(f, F_SETFL, flags);
168 }
169 
170 void
libusb_interrupt_event_handler(libusb_context * ctx)171 libusb_interrupt_event_handler(libusb_context *ctx)
172 {
173 	int err;
174 
175 	if (ctx == NULL)
176 		return;
177 
178 	err = eventfd_write(ctx->event, 1);
179 	if (err < 0) {
180 		/* ignore error, if any */
181 		DPRINTF(ctx, LIBUSB_LOG_LEVEL_ERROR, "Waking up event loop failed!");
182 	}
183 }
184 
185 int
libusb_init(libusb_context ** context)186 libusb_init(libusb_context **context)
187 {
188 	return (libusb_init_context(context, NULL, 0));
189 }
190 
191 int
libusb_init_context(libusb_context ** context,const struct libusb_init_option option[],int num_options)192 libusb_init_context(libusb_context **context,
193     const struct libusb_init_option option[], int num_options)
194 {
195 	struct libusb_context *ctx;
196 	pthread_condattr_t attr;
197 	char *debug, *ep;
198 
199 	if (num_options < 0)
200 		return (LIBUSB_ERROR_INVALID_PARAM);
201 
202 	ctx = malloc(sizeof(*ctx));
203 	if (!ctx)
204 		return (LIBUSB_ERROR_INVALID_PARAM);
205 
206 	memset(ctx, 0, sizeof(*ctx));
207 	ctx->devd_pipe = -1;
208 
209 	debug = getenv("LIBUSB_DEBUG");
210 	if (debug != NULL) {
211 		/*
212 		 * If LIBUSB_DEBUG is set, we'll honor that first and
213 		 * use it to override any future libusb_set_debug()
214 		 * calls or init options.
215 		 */
216 		errno = 0;
217 		ctx->debug = strtol(debug, &ep, 10);
218 		if (errno == 0 && *ep == '\0') {
219 			ctx->debug_fixed = 1;
220 		} else {
221 			/*
222 			 * LIBUSB_DEBUG conversion failed for some reason, but
223 			 * we don't care about the specifics all that much.  We
224 			 * can't use it either way.  Force it to the default,
225 			 * 0, in case we had a partial number.
226 			 */
227 			ctx->debug = 0;
228 		}
229 	} else {
230 		/*
231 		 * If the LIBUSB_OPTION_LOG_LEVEL is set, honor that.
232 		 */
233 		for (int i = 0; i != num_options; i++) {
234 			if (option[i].option != LIBUSB_OPTION_LOG_LEVEL)
235 				continue;
236 
237 			ctx->debug = (int)option[i].value.ival;
238 			if ((int64_t)ctx->debug == option[i].value.ival) {
239 				ctx->debug_fixed = 1;
240 			} else {
241 				free(ctx);
242 				return (LIBUSB_ERROR_INVALID_PARAM);
243 			}
244 		}
245 	}
246 
247 	TAILQ_INIT(&ctx->pollfds);
248 	TAILQ_INIT(&ctx->tr_done);
249 	TAILQ_INIT(&ctx->hotplug_cbh);
250 	TAILQ_INIT(&ctx->hotplug_devs);
251 
252 	if (pthread_mutex_init(&ctx->ctx_lock, NULL) != 0) {
253 		free(ctx);
254 		return (LIBUSB_ERROR_NO_MEM);
255 	}
256 	if (pthread_mutex_init(&ctx->hotplug_lock, NULL) != 0) {
257 		pthread_mutex_destroy(&ctx->ctx_lock);
258 		free(ctx);
259 		return (LIBUSB_ERROR_NO_MEM);
260 	}
261 	if (pthread_condattr_init(&attr) != 0) {
262 		pthread_mutex_destroy(&ctx->ctx_lock);
263 		pthread_mutex_destroy(&ctx->hotplug_lock);
264 		free(ctx);
265 		return (LIBUSB_ERROR_NO_MEM);
266 	}
267 	if (pthread_condattr_setclock(&attr, CLOCK_MONOTONIC) != 0) {
268 		pthread_mutex_destroy(&ctx->ctx_lock);
269 		pthread_mutex_destroy(&ctx->hotplug_lock);
270 		pthread_condattr_destroy(&attr);
271 		free(ctx);
272 		return (LIBUSB_ERROR_OTHER);
273 	}
274 	if (pthread_cond_init(&ctx->ctx_cond, &attr) != 0) {
275 		pthread_mutex_destroy(&ctx->ctx_lock);
276 		pthread_mutex_destroy(&ctx->hotplug_lock);
277 		pthread_condattr_destroy(&attr);
278 		free(ctx);
279 		return (LIBUSB_ERROR_NO_MEM);
280 	}
281 	pthread_condattr_destroy(&attr);
282 
283 	ctx->ctx_handler = NO_THREAD;
284 	ctx->hotplug_handler = NO_THREAD;
285 
286 	ctx->event = eventfd(0, EFD_NONBLOCK);
287 	if (ctx->event < 0) {
288 		pthread_mutex_destroy(&ctx->ctx_lock);
289 		pthread_mutex_destroy(&ctx->hotplug_lock);
290 		pthread_cond_destroy(&ctx->ctx_cond);
291 		free(ctx);
292 		return (LIBUSB_ERROR_OTHER);
293 	}
294 
295 	libusb10_add_pollfd(ctx, &ctx->ctx_poll, NULL, ctx->event, POLLIN);
296 
297 	pthread_mutex_lock(&default_context_lock);
298 	if (usbi_default_context == NULL) {
299 		usbi_default_context = ctx;
300 	}
301 	pthread_mutex_unlock(&default_context_lock);
302 
303 	if (context)
304 		*context = ctx;
305 
306 	DPRINTF(ctx, LIBUSB_LOG_LEVEL_INFO, "libusb_init complete");
307 
308 	signal(SIGPIPE, SIG_IGN);
309 
310 	return (0);
311 }
312 
313 void
libusb_exit(libusb_context * ctx)314 libusb_exit(libusb_context *ctx)
315 {
316 	ctx = GET_CONTEXT(ctx);
317 
318 	if (ctx == NULL)
319 		return;
320 
321 	/* stop hotplug thread, if any */
322 
323 	if (ctx->hotplug_handler != NO_THREAD) {
324 		pthread_t td;
325 		void *ptr;
326 
327 		HOTPLUG_LOCK(ctx);
328 		td = ctx->hotplug_handler;
329 		ctx->hotplug_handler = NO_THREAD;
330 		if (ctx->usb_event_mode == usb_event_devd) {
331 			close(ctx->devd_pipe);
332 			ctx->devd_pipe = -1;
333 		} else if (ctx->usb_event_mode == usb_event_netlink) {
334 			close(ctx->ss.fd);
335 			ctx->ss.fd = -1;
336 		}
337 		HOTPLUG_UNLOCK(ctx);
338 
339 		pthread_join(td, &ptr);
340 	}
341 
342 	/* XXX cleanup devices */
343 
344 	libusb10_remove_pollfd(ctx, &ctx->ctx_poll);
345 	close(ctx->event);
346 	pthread_mutex_destroy(&ctx->ctx_lock);
347 	pthread_mutex_destroy(&ctx->hotplug_lock);
348 	pthread_cond_destroy(&ctx->ctx_cond);
349 
350 	pthread_mutex_lock(&default_context_lock);
351 	if (ctx == usbi_default_context) {
352 		usbi_default_context = NULL;
353 	}
354 	pthread_mutex_unlock(&default_context_lock);
355 
356 	free(ctx);
357 }
358 
359 /* Device handling and initialisation. */
360 
361 ssize_t
libusb_get_device_list(libusb_context * ctx,libusb_device *** list)362 libusb_get_device_list(libusb_context *ctx, libusb_device ***list)
363 {
364 	struct libusb20_backend *usb_backend;
365 	struct libusb20_device *pdev, *parent_dev;
366 	struct libusb_device *dev;
367 	int i, j, k;
368 
369 	ctx = GET_CONTEXT(ctx);
370 
371 	if (ctx == NULL)
372 		return (LIBUSB_ERROR_INVALID_PARAM);
373 
374 	if (list == NULL)
375 		return (LIBUSB_ERROR_INVALID_PARAM);
376 
377 	usb_backend = libusb20_be_alloc_default();
378 	if (usb_backend == NULL)
379 		return (LIBUSB_ERROR_NO_MEM);
380 
381 	/* figure out how many USB devices are present */
382 	pdev = NULL;
383 	i = 0;
384 	while ((pdev = libusb20_be_device_foreach(usb_backend, pdev)))
385 		i++;
386 
387 	/* allocate device pointer list */
388 	*list = malloc((i + 1) * sizeof(void *));
389 	if (*list == NULL) {
390 		libusb20_be_free(usb_backend);
391 		return (LIBUSB_ERROR_NO_MEM);
392 	}
393 	/* create libusb v1.0 compliant devices */
394 	i = 0;
395 	while ((pdev = libusb20_be_device_foreach(usb_backend, NULL))) {
396 
397 		dev = malloc(sizeof(*dev));
398 		if (dev == NULL) {
399 			while (i != 0) {
400 				libusb_unref_device((*list)[i - 1]);
401 				i--;
402 			}
403 			free(*list);
404 			*list = NULL;
405 			libusb20_be_free(usb_backend);
406 			return (LIBUSB_ERROR_NO_MEM);
407 		}
408 		/* get device into libUSB v1.0 list */
409 		libusb20_be_dequeue_device(usb_backend, pdev);
410 
411 		memset(dev, 0, sizeof(*dev));
412 
413 		/* init transfer queues */
414 		TAILQ_INIT(&dev->tr_head);
415 
416 		/* set context we belong to */
417 		dev->ctx = ctx;
418 
419 		/* assume we have no parent by default */
420 		dev->parent_dev = NULL;
421 
422 		/* link together the two structures */
423 		dev->os_priv = pdev;
424 		pdev->privLuData = dev;
425 
426 		(*list)[i] = libusb_ref_device(dev);
427 		i++;
428 	}
429 	(*list)[i] = NULL;
430 
431 	/* for each device, find its parent */
432 	for (j = 0; j < i; j++) {
433 		pdev = (*list)[j]->os_priv;
434 
435 		for (k = 0; k < i; k++) {
436 			if (k == j)
437 				continue;
438 
439 			parent_dev = (*list)[k]->os_priv;
440 
441 			if (parent_dev->bus_number != pdev->bus_number)
442 				continue;
443 			if (parent_dev->device_address == pdev->parent_address) {
444 				(*list)[j]->parent_dev = libusb_ref_device((*list)[k]);
445 				break;
446 			}
447 		}
448 	}
449 
450 	libusb20_be_free(usb_backend);
451 	return (i);
452 }
453 
454 void
libusb_free_device_list(libusb_device ** list,int unref_devices)455 libusb_free_device_list(libusb_device **list, int unref_devices)
456 {
457 	int i;
458 
459 	if (list == NULL)
460 		return;			/* be NULL safe */
461 
462 	if (unref_devices) {
463 		for (i = 0; list[i] != NULL; i++)
464 			libusb_unref_device(list[i]);
465 	}
466 	free(list);
467 }
468 
469 uint8_t
libusb_get_bus_number(libusb_device * dev)470 libusb_get_bus_number(libusb_device *dev)
471 {
472 	if (dev == NULL)
473 		return (0);		/* should not happen */
474 	return (libusb20_dev_get_bus_number(dev->os_priv));
475 }
476 
477 uint8_t
libusb_get_port_number(libusb_device * dev)478 libusb_get_port_number(libusb_device *dev)
479 {
480 	if (dev == NULL)
481 		return (0);		/* should not happen */
482 	return (libusb20_dev_get_parent_port(dev->os_priv));
483 }
484 
485 int
libusb_get_port_numbers(libusb_device * dev,uint8_t * buf,uint8_t bufsize)486 libusb_get_port_numbers(libusb_device *dev, uint8_t *buf, uint8_t bufsize)
487 {
488 	return (libusb20_dev_get_port_path(dev->os_priv, buf, bufsize));
489 }
490 
491 int
libusb_get_port_path(libusb_context * ctx,libusb_device * dev,uint8_t * buf,uint8_t bufsize)492 libusb_get_port_path(libusb_context *ctx, libusb_device *dev, uint8_t *buf,
493     uint8_t bufsize)
494 {
495 	return (libusb20_dev_get_port_path(dev->os_priv, buf, bufsize));
496 }
497 
498 uint8_t
libusb_get_device_address(libusb_device * dev)499 libusb_get_device_address(libusb_device *dev)
500 {
501 	if (dev == NULL)
502 		return (0);		/* should not happen */
503 	return (libusb20_dev_get_address(dev->os_priv));
504 }
505 
506 enum libusb_speed
libusb_get_device_speed(libusb_device * dev)507 libusb_get_device_speed(libusb_device *dev)
508 {
509 	if (dev == NULL)
510 		return (LIBUSB_SPEED_UNKNOWN);	/* should not happen */
511 
512 	switch (libusb20_dev_get_speed(dev->os_priv)) {
513 	case LIBUSB20_SPEED_LOW:
514 		return (LIBUSB_SPEED_LOW);
515 	case LIBUSB20_SPEED_FULL:
516 		return (LIBUSB_SPEED_FULL);
517 	case LIBUSB20_SPEED_HIGH:
518 		return (LIBUSB_SPEED_HIGH);
519 	case LIBUSB20_SPEED_SUPER:
520 		return (LIBUSB_SPEED_SUPER);
521 	case LIBUSB20_SPEED_SUPER_PLUS:
522 		return (LIBUSB_SPEED_SUPER_PLUS);
523 	default:
524 		break;
525 	}
526 	return (LIBUSB_SPEED_UNKNOWN);
527 }
528 
529 int
libusb_get_max_packet_size(libusb_device * dev,uint8_t endpoint)530 libusb_get_max_packet_size(libusb_device *dev, uint8_t endpoint)
531 {
532 	struct libusb_config_descriptor *pdconf;
533 	struct libusb_interface *pinf;
534 	struct libusb_interface_descriptor *pdinf;
535 	struct libusb_endpoint_descriptor *pdend;
536 	int i;
537 	int j;
538 	int k;
539 	int ret;
540 
541 	if (dev == NULL)
542 		return (LIBUSB_ERROR_NO_DEVICE);
543 
544 	ret = libusb_get_active_config_descriptor(dev, &pdconf);
545 	if (ret < 0)
546 		return (ret);
547 
548 	ret = LIBUSB_ERROR_NOT_FOUND;
549 	for (i = 0; i < pdconf->bNumInterfaces; i++) {
550 		pinf = &pdconf->interface[i];
551 		for (j = 0; j < pinf->num_altsetting; j++) {
552 			pdinf = &pinf->altsetting[j];
553 			for (k = 0; k < pdinf->bNumEndpoints; k++) {
554 				pdend = &pdinf->endpoint[k];
555 				if (pdend->bEndpointAddress == endpoint) {
556 					ret = pdend->wMaxPacketSize;
557 					goto out;
558 				}
559 			}
560 		}
561 	}
562 
563 out:
564 	libusb_free_config_descriptor(pdconf);
565 	return (ret);
566 }
567 
568 int
libusb_get_max_iso_packet_size(libusb_device * dev,uint8_t endpoint)569 libusb_get_max_iso_packet_size(libusb_device *dev, uint8_t endpoint)
570 {
571 	int multiplier;
572 	int ret;
573 
574 	ret = libusb_get_max_packet_size(dev, endpoint);
575 
576 	switch (libusb20_dev_get_speed(dev->os_priv)) {
577 	case LIBUSB20_SPEED_LOW:
578 	case LIBUSB20_SPEED_FULL:
579 		break;
580 	default:
581 		if (ret > -1) {
582 			multiplier = (1 + ((ret >> 11) & 3));
583 			if (multiplier > 3)
584 				multiplier = 3;
585 			ret = (ret & 0x7FF) * multiplier;
586 		}
587 		break;
588 	}
589 	return (ret);
590 }
591 
592 libusb_device *
libusb_ref_device(libusb_device * dev)593 libusb_ref_device(libusb_device *dev)
594 {
595 	if (dev == NULL)
596 		return (NULL);		/* be NULL safe */
597 
598 	CTX_LOCK(dev->ctx);
599 	dev->refcnt++;
600 	CTX_UNLOCK(dev->ctx);
601 
602 	return (dev);
603 }
604 
605 void
libusb_unref_device(libusb_device * dev)606 libusb_unref_device(libusb_device *dev)
607 {
608 	if (dev == NULL)
609 		return;			/* be NULL safe */
610 
611 	CTX_LOCK(dev->ctx);
612 	dev->refcnt--;
613 	CTX_UNLOCK(dev->ctx);
614 
615 	if (dev->refcnt == 0) {
616 		libusb_unref_device(dev->parent_dev);
617 		libusb20_dev_free(dev->os_priv);
618 		free(dev);
619 	}
620 }
621 
622 int
libusb_open(libusb_device * dev,libusb_device_handle ** devh)623 libusb_open(libusb_device *dev, libusb_device_handle **devh)
624 {
625 	libusb_context *ctx = dev->ctx;
626 	struct libusb20_device *pdev = dev->os_priv;
627 	int err;
628 
629 	if (devh == NULL)
630 		return (LIBUSB_ERROR_INVALID_PARAM);
631 
632 	/* set default device handle value */
633 	*devh = NULL;
634 
635 	dev = libusb_ref_device(dev);
636 	if (dev == NULL)
637 		return (LIBUSB_ERROR_INVALID_PARAM);
638 
639 	err = libusb20_dev_open(pdev, LIBUSB_NUM_SW_ENDPOINTS);
640 	if (err) {
641 		libusb_unref_device(dev);
642 		return (LIBUSB_ERROR_NO_MEM);
643 	}
644 
645 	/*
646 	 * Clear the device gone flag, in case the device was opened
647 	 * after a re-attach, to allow new transaction:
648 	 */
649 	CTX_LOCK(ctx);
650 	dev->device_is_gone = 0;
651 	CTX_UNLOCK(ctx);
652 
653 	libusb10_add_pollfd(ctx, &dev->dev_poll, pdev, libusb20_dev_get_fd(pdev), POLLIN |
654 	    POLLOUT | POLLRDNORM | POLLWRNORM);
655 
656 	/* make sure our event loop detects the new device */
657 	libusb_interrupt_event_handler(ctx);
658 
659 	*devh = pdev;
660 
661 	return (0);
662 }
663 
664 libusb_device_handle *
libusb_open_device_with_vid_pid(libusb_context * ctx,uint16_t vendor_id,uint16_t product_id)665 libusb_open_device_with_vid_pid(libusb_context *ctx, uint16_t vendor_id,
666     uint16_t product_id)
667 {
668 	struct libusb_device **devs;
669 	struct libusb20_device *pdev;
670 	struct LIBUSB20_DEVICE_DESC_DECODED *pdesc;
671 	int i;
672 	int j;
673 
674 	ctx = GET_CONTEXT(ctx);
675 	if (ctx == NULL)
676 		return (NULL);		/* be NULL safe */
677 
678 	DPRINTF(ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb_open_device_with_vid_pid enter");
679 
680 	if ((i = libusb_get_device_list(ctx, &devs)) < 0)
681 		return (NULL);
682 
683 	pdev = NULL;
684 	for (j = 0; j < i; j++) {
685 		struct libusb20_device *tdev;
686 
687 		tdev = devs[j]->os_priv;
688 		pdesc = libusb20_dev_get_device_desc(tdev);
689 		/*
690 		 * NOTE: The USB library will automatically swap the
691 		 * fields in the device descriptor to be of host
692 		 * endian type!
693 		 */
694 		if (pdesc->idVendor == vendor_id &&
695 		    pdesc->idProduct == product_id) {
696 			libusb_open(devs[j], &pdev);
697 			break;
698 		}
699 	}
700 
701 	libusb_free_device_list(devs, 1);
702 	DPRINTF(ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb_open_device_with_vid_pid leave");
703 	return (pdev);
704 }
705 
706 void
libusb_close(struct libusb20_device * pdev)707 libusb_close(struct libusb20_device *pdev)
708 {
709 	libusb_context *ctx;
710 	struct libusb_device *dev;
711 
712 	if (pdev == NULL)
713 		return;			/* be NULL safe */
714 
715 	dev = libusb_get_device(pdev);
716 	ctx = dev->ctx;
717 
718 	libusb10_remove_pollfd(ctx, &dev->dev_poll);
719 
720 	libusb20_dev_close(pdev);
721 
722 	/* unref will free the "pdev" when the refcount reaches zero */
723 	libusb_unref_device(dev);
724 
725 	/* make sure our event loop detects the closed device */
726 	libusb_interrupt_event_handler(ctx);
727 }
728 
729 libusb_device *
libusb_get_device(struct libusb20_device * pdev)730 libusb_get_device(struct libusb20_device *pdev)
731 {
732 	if (pdev == NULL)
733 		return (NULL);
734 	return ((libusb_device *)pdev->privLuData);
735 }
736 
737 int
libusb_get_configuration(struct libusb20_device * pdev,int * config)738 libusb_get_configuration(struct libusb20_device *pdev, int *config)
739 {
740 	struct libusb20_config *pconf;
741 
742 	if (pdev == NULL || config == NULL)
743 		return (LIBUSB_ERROR_INVALID_PARAM);
744 
745 	pconf = libusb20_dev_alloc_config(pdev, libusb20_dev_get_config_index(pdev));
746 	if (pconf == NULL)
747 		return (LIBUSB_ERROR_NO_MEM);
748 
749 	*config = pconf->desc.bConfigurationValue;
750 
751 	free(pconf);
752 
753 	return (0);
754 }
755 
756 int
libusb_set_configuration(struct libusb20_device * pdev,int configuration)757 libusb_set_configuration(struct libusb20_device *pdev, int configuration)
758 {
759 	struct libusb20_config *pconf;
760 	struct libusb_device *dev;
761 	int err;
762 	uint8_t i;
763 
764 	dev = libusb_get_device(pdev);
765 	if (dev == NULL)
766 		return (LIBUSB_ERROR_INVALID_PARAM);
767 
768 	if (configuration < 1) {
769 		/* unconfigure */
770 		i = 255;
771 	} else {
772 		for (i = 0; i != 255; i++) {
773 			uint8_t found;
774 
775 			pconf = libusb20_dev_alloc_config(pdev, i);
776 			if (pconf == NULL)
777 				return (LIBUSB_ERROR_INVALID_PARAM);
778 			found = (pconf->desc.bConfigurationValue
779 			    == configuration);
780 			free(pconf);
781 
782 			if (found)
783 				goto set_config;
784 		}
785 		return (LIBUSB_ERROR_INVALID_PARAM);
786 	}
787 
788 set_config:
789 
790 	libusb10_cancel_all_transfer(dev);
791 
792 	libusb10_remove_pollfd(dev->ctx, &dev->dev_poll);
793 
794 	err = libusb20_dev_set_config_index(pdev, i);
795 
796 	libusb10_add_pollfd(dev->ctx, &dev->dev_poll, pdev, libusb20_dev_get_fd(pdev), POLLIN |
797 	    POLLOUT | POLLRDNORM | POLLWRNORM);
798 
799 	return (err ? LIBUSB_ERROR_INVALID_PARAM : 0);
800 }
801 
802 int
libusb_claim_interface(struct libusb20_device * pdev,int interface_number)803 libusb_claim_interface(struct libusb20_device *pdev, int interface_number)
804 {
805 	libusb_device *dev;
806 	int err = 0;
807 
808 	dev = libusb_get_device(pdev);
809 	if (dev == NULL)
810 		return (LIBUSB_ERROR_INVALID_PARAM);
811 
812 	if (interface_number < 0 || interface_number > 31)
813 		return (LIBUSB_ERROR_INVALID_PARAM);
814 
815 	if (pdev->auto_detach != 0) {
816 		err = libusb_detach_kernel_driver(pdev, interface_number);
817 		if (err != 0)
818 			goto done;
819 	}
820 
821 	CTX_LOCK(dev->ctx);
822 	dev->claimed_interfaces |= (1 << interface_number);
823 	CTX_UNLOCK(dev->ctx);
824 done:
825 	return (err);
826 }
827 
828 int
libusb_release_interface(struct libusb20_device * pdev,int interface_number)829 libusb_release_interface(struct libusb20_device *pdev, int interface_number)
830 {
831 	libusb_device *dev;
832 	int err = 0;
833 
834 	dev = libusb_get_device(pdev);
835 	if (dev == NULL)
836 		return (LIBUSB_ERROR_INVALID_PARAM);
837 
838 	if (interface_number < 0 || interface_number > 31)
839 		return (LIBUSB_ERROR_INVALID_PARAM);
840 
841 	if (pdev->auto_detach != 0) {
842 		err = libusb_attach_kernel_driver(pdev, interface_number);
843 		if (err != 0)
844 			goto done;
845 	}
846 
847 	CTX_LOCK(dev->ctx);
848 	if (!(dev->claimed_interfaces & (1 << interface_number)))
849 		err = LIBUSB_ERROR_NOT_FOUND;
850 	else
851 		dev->claimed_interfaces &= ~(1 << interface_number);
852 	CTX_UNLOCK(dev->ctx);
853 done:
854 	return (err);
855 }
856 
857 int
libusb_set_interface_alt_setting(struct libusb20_device * pdev,int interface_number,int alternate_setting)858 libusb_set_interface_alt_setting(struct libusb20_device *pdev,
859     int interface_number, int alternate_setting)
860 {
861 	libusb_device *dev;
862 	int err = 0;
863 
864 	dev = libusb_get_device(pdev);
865 	if (dev == NULL)
866 		return (LIBUSB_ERROR_INVALID_PARAM);
867 
868 	if (interface_number < 0 || interface_number > 31)
869 		return (LIBUSB_ERROR_INVALID_PARAM);
870 
871 	CTX_LOCK(dev->ctx);
872 	if (!(dev->claimed_interfaces & (1 << interface_number)))
873 		err = LIBUSB_ERROR_NOT_FOUND;
874 	CTX_UNLOCK(dev->ctx);
875 
876 	if (err)
877 		return (err);
878 
879 	libusb10_cancel_all_transfer(dev);
880 
881 	libusb10_remove_pollfd(dev->ctx, &dev->dev_poll);
882 
883 	err = libusb20_dev_set_alt_index(pdev,
884 	    interface_number, alternate_setting);
885 
886 	libusb10_add_pollfd(dev->ctx, &dev->dev_poll,
887 	    pdev, libusb20_dev_get_fd(pdev),
888 	    POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM);
889 
890 	return (err ? LIBUSB_ERROR_OTHER : 0);
891 }
892 
893 libusb_device *
libusb_get_parent(libusb_device * dev)894 libusb_get_parent(libusb_device *dev)
895 {
896 	return (dev->parent_dev);
897 }
898 
899 static struct libusb20_transfer *
libusb10_get_transfer(struct libusb20_device * pdev,uint8_t endpoint,uint8_t xfer_index)900 libusb10_get_transfer(struct libusb20_device *pdev,
901     uint8_t endpoint, uint8_t xfer_index)
902 {
903 	xfer_index &= 1;	/* double buffering */
904 
905 	xfer_index |= (endpoint & LIBUSB20_ENDPOINT_ADDRESS_MASK) * 4;
906 
907 	if (endpoint & LIBUSB20_ENDPOINT_DIR_MASK) {
908 		/* this is an IN endpoint */
909 		xfer_index |= 2;
910 	}
911 	return (libusb20_tr_get_pointer(pdev, xfer_index));
912 }
913 
914 int
libusb_clear_halt(struct libusb20_device * pdev,uint8_t endpoint)915 libusb_clear_halt(struct libusb20_device *pdev, uint8_t endpoint)
916 {
917 	struct libusb20_transfer *xfer;
918 	struct libusb_device *dev;
919 	int err;
920 
921 	xfer = libusb10_get_transfer(pdev, endpoint, 0);
922 	if (xfer == NULL)
923 		return (LIBUSB_ERROR_INVALID_PARAM);
924 
925 	dev = libusb_get_device(pdev);
926 	if (dev == NULL)
927 		return (LIBUSB_ERROR_INVALID_PARAM);
928 
929 	CTX_LOCK(dev->ctx);
930 	err = libusb20_tr_open(xfer, 0, 1, endpoint);
931 	CTX_UNLOCK(dev->ctx);
932 
933 	if (err != 0 && err != LIBUSB20_ERROR_BUSY)
934 		return (LIBUSB_ERROR_OTHER);
935 
936 	libusb20_tr_clear_stall_sync(xfer);
937 
938 	/* check if we opened the transfer */
939 	if (err == 0) {
940 		CTX_LOCK(dev->ctx);
941 		libusb20_tr_close(xfer);
942 		CTX_UNLOCK(dev->ctx);
943 	}
944 	return (0);			/* success */
945 }
946 
947 int
libusb_reset_device(struct libusb20_device * pdev)948 libusb_reset_device(struct libusb20_device *pdev)
949 {
950 	libusb_device *dev;
951 	int err;
952 
953 	dev = libusb_get_device(pdev);
954 	if (dev == NULL)
955 		return (LIBUSB_ERROR_INVALID_PARAM);
956 
957 	libusb10_cancel_all_transfer(dev);
958 
959 	libusb10_remove_pollfd(dev->ctx, &dev->dev_poll);
960 
961 	err = libusb20_dev_reset(pdev);
962 
963 	libusb10_add_pollfd(dev->ctx, &dev->dev_poll,
964 	    pdev, libusb20_dev_get_fd(pdev),
965 	    POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM);
966 
967 	return (err ? LIBUSB_ERROR_OTHER : 0);
968 }
969 
970 int
libusb_check_connected(struct libusb20_device * pdev)971 libusb_check_connected(struct libusb20_device *pdev)
972 {
973 	libusb_device *dev;
974 	int err;
975 
976 	dev = libusb_get_device(pdev);
977 	if (dev == NULL)
978 		return (LIBUSB_ERROR_INVALID_PARAM);
979 
980 	err = libusb20_dev_check_connected(pdev);
981 
982 	return (err ? LIBUSB_ERROR_NO_DEVICE : 0);
983 }
984 
985 int
libusb_kernel_driver_active(struct libusb20_device * pdev,int interface)986 libusb_kernel_driver_active(struct libusb20_device *pdev, int interface)
987 {
988 	if (pdev == NULL)
989 		return (LIBUSB_ERROR_INVALID_PARAM);
990 
991 	if (libusb20_dev_kernel_driver_active(pdev, interface))
992 		return (0);		/* no kernel driver is active */
993 	else
994 		return (1);		/* kernel driver is active */
995 }
996 
997 int
libusb_get_driver_np(struct libusb20_device * pdev,int interface,char * name,int namelen)998 libusb_get_driver_np(struct libusb20_device *pdev, int interface,
999     char *name, int namelen)
1000 {
1001 	return (libusb_get_driver(pdev, interface, name, namelen));
1002 }
1003 
1004 int
libusb_get_driver(struct libusb20_device * pdev,int interface,char * name,int namelen)1005 libusb_get_driver(struct libusb20_device *pdev, int interface,
1006     char *name, int namelen)
1007 {
1008 	char *ptr;
1009 	int err;
1010 
1011 	if (pdev == NULL)
1012 		return (LIBUSB_ERROR_INVALID_PARAM);
1013 	if (namelen < 1)
1014 		return (LIBUSB_ERROR_INVALID_PARAM);
1015 	if (namelen > 255)
1016 		namelen = 255;
1017 
1018 	err = libusb20_dev_get_iface_desc(
1019 	    pdev, interface, name, namelen);
1020 
1021 	if (err != 0)
1022 		return (LIBUSB_ERROR_OTHER);
1023 
1024 	/* we only want the driver name */
1025 	ptr = strstr(name, ":");
1026 	if (ptr != NULL)
1027 		*ptr = 0;
1028 
1029 	return (0);
1030 }
1031 
1032 int
libusb_detach_kernel_driver_np(struct libusb20_device * pdev,int interface)1033 libusb_detach_kernel_driver_np(struct libusb20_device *pdev, int interface)
1034 {
1035 	return (libusb_detach_kernel_driver(pdev, interface));
1036 }
1037 
1038 int
libusb_detach_kernel_driver(struct libusb20_device * pdev,int interface)1039 libusb_detach_kernel_driver(struct libusb20_device *pdev, int interface)
1040 {
1041 	int err;
1042 
1043 	if (pdev == NULL)
1044 		return (LIBUSB_ERROR_INVALID_PARAM);
1045 
1046 	err = libusb20_dev_detach_kernel_driver(
1047 	    pdev, interface);
1048 
1049 	return (err ? LIBUSB_ERROR_OTHER : 0);
1050 }
1051 
1052 int
libusb_attach_kernel_driver(struct libusb20_device * pdev,int interface)1053 libusb_attach_kernel_driver(struct libusb20_device *pdev, int interface)
1054 {
1055 	if (pdev == NULL)
1056 		return (LIBUSB_ERROR_INVALID_PARAM);
1057 	/* stub - currently not supported by libusb20 */
1058 	return (0);
1059 }
1060 
1061 int
libusb_set_auto_detach_kernel_driver(libusb_device_handle * dev,int enable)1062 libusb_set_auto_detach_kernel_driver(libusb_device_handle *dev, int enable)
1063 {
1064 	dev->auto_detach = (enable ? 1 : 0);
1065 	return (0);
1066 }
1067 
1068 /* Asynchronous device I/O */
1069 
1070 struct libusb_transfer *
libusb_alloc_transfer(int iso_packets)1071 libusb_alloc_transfer(int iso_packets)
1072 {
1073 	struct libusb_transfer *uxfer;
1074 	struct libusb_super_transfer *sxfer;
1075 	int len;
1076 
1077 	len = sizeof(struct libusb_transfer) +
1078 	    sizeof(struct libusb_super_transfer) +
1079 	    (iso_packets * sizeof(libusb_iso_packet_descriptor));
1080 
1081 	sxfer = malloc(len);
1082 	if (sxfer == NULL)
1083 		return (NULL);
1084 
1085 	memset(sxfer, 0, len);
1086 
1087 	uxfer = (struct libusb_transfer *)(
1088 	    ((uint8_t *)sxfer) + sizeof(*sxfer));
1089 
1090 	/* set default value */
1091 	uxfer->num_iso_packets = iso_packets;
1092 
1093 	return (uxfer);
1094 }
1095 
1096 void
libusb_free_transfer(struct libusb_transfer * uxfer)1097 libusb_free_transfer(struct libusb_transfer *uxfer)
1098 {
1099 	struct libusb_super_transfer *sxfer;
1100 
1101 	if (uxfer == NULL)
1102 		return;			/* be NULL safe */
1103 
1104 	/* check if we should free the transfer buffer */
1105 	if (uxfer->flags & LIBUSB_TRANSFER_FREE_BUFFER)
1106 		free(uxfer->buffer);
1107 
1108 	sxfer = (struct libusb_super_transfer *)(
1109 	    (uint8_t *)uxfer - sizeof(*sxfer));
1110 
1111 	free(sxfer);
1112 }
1113 
1114 static uint32_t
libusb10_get_maxframe(struct libusb20_device * pdev,libusb_transfer * xfer)1115 libusb10_get_maxframe(struct libusb20_device *pdev, libusb_transfer *xfer)
1116 {
1117 	uint32_t ret;
1118 
1119 	switch (xfer->type) {
1120 	case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
1121 		ret = 60 | LIBUSB20_MAX_FRAME_PRE_SCALE;	/* 60ms */
1122 		break;
1123 	case LIBUSB_TRANSFER_TYPE_CONTROL:
1124 		ret = 2;
1125 		break;
1126 	default:
1127 		ret = 1;
1128 		break;
1129 	}
1130 	return (ret);
1131 }
1132 
1133 static int
libusb10_get_buffsize(struct libusb20_device * pdev,libusb_transfer * xfer)1134 libusb10_get_buffsize(struct libusb20_device *pdev, libusb_transfer *xfer)
1135 {
1136 	int ret;
1137 	int usb_speed;
1138 
1139 	usb_speed = libusb20_dev_get_speed(pdev);
1140 
1141 	switch (xfer->type) {
1142 	case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
1143 		ret = 0;		/* kernel will auto-select */
1144 		break;
1145 	case LIBUSB_TRANSFER_TYPE_CONTROL:
1146 		ret = 1024;
1147 		break;
1148 	default:
1149 		switch (usb_speed) {
1150 		case LIBUSB20_SPEED_LOW:
1151 			ret = 256;
1152 			break;
1153 		case LIBUSB20_SPEED_FULL:
1154 			ret = 4096;
1155 			break;
1156 		case LIBUSB20_SPEED_SUPER:
1157 			ret = 65536;
1158 			break;
1159 		case LIBUSB20_SPEED_SUPER_PLUS:
1160 			ret = 131072;
1161 			break;
1162 		default:
1163 			ret = 16384;
1164 			break;
1165 		}
1166 		break;
1167 	}
1168 	return (ret);
1169 }
1170 
1171 static int
libusb10_convert_error(uint8_t status)1172 libusb10_convert_error(uint8_t status)
1173 {
1174 	;				/* indent fix */
1175 
1176 	switch (status) {
1177 	case LIBUSB20_TRANSFER_START:
1178 	case LIBUSB20_TRANSFER_COMPLETED:
1179 		return (LIBUSB_TRANSFER_COMPLETED);
1180 	case LIBUSB20_TRANSFER_OVERFLOW:
1181 		return (LIBUSB_TRANSFER_OVERFLOW);
1182 	case LIBUSB20_TRANSFER_NO_DEVICE:
1183 		return (LIBUSB_TRANSFER_NO_DEVICE);
1184 	case LIBUSB20_TRANSFER_STALL:
1185 		return (LIBUSB_TRANSFER_STALL);
1186 	case LIBUSB20_TRANSFER_CANCELLED:
1187 		return (LIBUSB_TRANSFER_CANCELLED);
1188 	case LIBUSB20_TRANSFER_TIMED_OUT:
1189 		return (LIBUSB_TRANSFER_TIMED_OUT);
1190 	default:
1191 		return (LIBUSB_TRANSFER_ERROR);
1192 	}
1193 }
1194 
1195 /* This function must be called locked */
1196 
1197 static void
libusb10_complete_transfer(struct libusb20_transfer * pxfer,struct libusb_super_transfer * sxfer,int status)1198 libusb10_complete_transfer(struct libusb20_transfer *pxfer,
1199     struct libusb_super_transfer *sxfer, int status)
1200 {
1201 	struct libusb_transfer *uxfer;
1202 	struct libusb_device *dev;
1203 
1204 	uxfer = (struct libusb_transfer *)(
1205 	    ((uint8_t *)sxfer) + sizeof(*sxfer));
1206 
1207 	if (pxfer != NULL)
1208 		libusb20_tr_set_priv_sc1(pxfer, NULL);
1209 
1210 	/* set transfer status */
1211 	uxfer->status = status;
1212 
1213 	/* update super transfer state */
1214 	sxfer->state = LIBUSB_SUPER_XFER_ST_NONE;
1215 
1216 	dev = libusb_get_device(uxfer->dev_handle);
1217 
1218 	TAILQ_INSERT_TAIL(&dev->ctx->tr_done, sxfer, entry);
1219 }
1220 
1221 /* This function must be called locked */
1222 
1223 static void
libusb10_isoc_proxy(struct libusb20_transfer * pxfer)1224 libusb10_isoc_proxy(struct libusb20_transfer *pxfer)
1225 {
1226 	struct libusb_super_transfer *sxfer;
1227 	struct libusb_transfer *uxfer;
1228 	uint32_t actlen;
1229 	uint16_t iso_packets;
1230 	uint16_t i;
1231 	uint8_t status;
1232 
1233 	status = libusb20_tr_get_status(pxfer);
1234 	sxfer = libusb20_tr_get_priv_sc1(pxfer);
1235 	actlen = libusb20_tr_get_actual_length(pxfer);
1236 	iso_packets = libusb20_tr_get_max_frames(pxfer);
1237 
1238 	if (sxfer == NULL)
1239 		return; /* cancelled - nothing to do */
1240 
1241 	uxfer = (struct libusb_transfer *)(
1242 	    ((uint8_t *)sxfer) + sizeof(*sxfer));
1243 
1244 	if (iso_packets > uxfer->num_iso_packets)
1245 		iso_packets = uxfer->num_iso_packets;
1246 
1247 	if (iso_packets == 0)
1248 		return; /* nothing to do */
1249 
1250 	/* make sure that the number of ISOCHRONOUS packets is valid */
1251 	uxfer->num_iso_packets = iso_packets;
1252 
1253 	switch (status) {
1254 	case LIBUSB20_TRANSFER_COMPLETED:
1255 		/* update actual length */
1256 		uxfer->actual_length = actlen;
1257 		for (i = 0; i != iso_packets; i++) {
1258 			uxfer->iso_packet_desc[i].actual_length =
1259 			    libusb20_tr_get_length(pxfer, i);
1260 		}
1261 		libusb10_complete_transfer(pxfer, sxfer, LIBUSB_TRANSFER_COMPLETED);
1262 		break;
1263 	case LIBUSB20_TRANSFER_START:
1264 		/* setup length(s) */
1265 		actlen = 0;
1266 		for (i = 0; i != iso_packets; i++) {
1267 			libusb20_tr_setup_isoc(pxfer,
1268 			    &uxfer->buffer[actlen],
1269 			    uxfer->iso_packet_desc[i].length, i);
1270 			actlen += uxfer->iso_packet_desc[i].length;
1271 		}
1272 
1273 		/* no remainder */
1274 		sxfer->rem_len = 0;
1275 
1276 		libusb20_tr_set_total_frames(pxfer, iso_packets);
1277 		libusb20_tr_submit(pxfer);
1278 
1279 		/* fork another USB transfer, if any */
1280 		libusb10_submit_transfer_sub(libusb20_tr_get_priv_sc0(pxfer), uxfer->endpoint);
1281 		break;
1282 	default:
1283 		libusb10_complete_transfer(pxfer, sxfer, libusb10_convert_error(status));
1284 		break;
1285 	}
1286 }
1287 
1288 /* This function must be called locked */
1289 
1290 static void
libusb10_bulk_intr_proxy(struct libusb20_transfer * pxfer)1291 libusb10_bulk_intr_proxy(struct libusb20_transfer *pxfer)
1292 {
1293 	struct libusb_super_transfer *sxfer;
1294 	struct libusb_transfer *uxfer;
1295 	uint32_t max_bulk;
1296 	uint32_t actlen;
1297 	uint8_t status;
1298 	uint8_t flags;
1299 
1300 	status = libusb20_tr_get_status(pxfer);
1301 	sxfer = libusb20_tr_get_priv_sc1(pxfer);
1302 	max_bulk = libusb20_tr_get_max_total_length(pxfer);
1303 	actlen = libusb20_tr_get_actual_length(pxfer);
1304 
1305 	if (sxfer == NULL)
1306 		return;			/* cancelled - nothing to do */
1307 
1308 	uxfer = (struct libusb_transfer *)(
1309 	    ((uint8_t *)sxfer) + sizeof(*sxfer));
1310 
1311 	flags = uxfer->flags;
1312 
1313 	switch (status) {
1314 	case LIBUSB20_TRANSFER_COMPLETED:
1315 
1316 		uxfer->actual_length += actlen;
1317 
1318 		/* check for short packet */
1319 		if (sxfer->last_len != actlen) {
1320 			if (flags & LIBUSB_TRANSFER_SHORT_NOT_OK) {
1321 				libusb10_complete_transfer(pxfer, sxfer, LIBUSB_TRANSFER_ERROR);
1322 			} else {
1323 				libusb10_complete_transfer(pxfer, sxfer, LIBUSB_TRANSFER_COMPLETED);
1324 			}
1325 			break;
1326 		}
1327 		/* check for end of data */
1328 		if (sxfer->rem_len == 0) {
1329 			libusb10_complete_transfer(pxfer, sxfer, LIBUSB_TRANSFER_COMPLETED);
1330 			break;
1331 		}
1332 		/* FALLTHROUGH */
1333 
1334 	case LIBUSB20_TRANSFER_START:
1335 		if (max_bulk > sxfer->rem_len) {
1336 			max_bulk = sxfer->rem_len;
1337 		}
1338 		/* setup new BULK or INTERRUPT transaction */
1339 		libusb20_tr_setup_bulk(pxfer,
1340 		    sxfer->curr_data, max_bulk, uxfer->timeout);
1341 
1342 		/* update counters */
1343 		sxfer->last_len = max_bulk;
1344 		sxfer->curr_data += max_bulk;
1345 		sxfer->rem_len -= max_bulk;
1346 
1347 		libusb20_tr_submit(pxfer);
1348 
1349 		/* check if we can fork another USB transfer */
1350 		if (sxfer->rem_len == 0)
1351 			libusb10_submit_transfer_sub(libusb20_tr_get_priv_sc0(pxfer), uxfer->endpoint);
1352 		break;
1353 
1354 	default:
1355 		libusb10_complete_transfer(pxfer, sxfer, libusb10_convert_error(status));
1356 		break;
1357 	}
1358 }
1359 
1360 /* This function must be called locked */
1361 
1362 static void
libusb10_ctrl_proxy(struct libusb20_transfer * pxfer)1363 libusb10_ctrl_proxy(struct libusb20_transfer *pxfer)
1364 {
1365 	struct libusb_super_transfer *sxfer;
1366 	struct libusb_transfer *uxfer;
1367 	uint32_t max_bulk;
1368 	uint32_t actlen;
1369 	uint8_t status;
1370 	uint8_t flags;
1371 
1372 	status = libusb20_tr_get_status(pxfer);
1373 	sxfer = libusb20_tr_get_priv_sc1(pxfer);
1374 	max_bulk = libusb20_tr_get_max_total_length(pxfer);
1375 	actlen = libusb20_tr_get_actual_length(pxfer);
1376 
1377 	if (sxfer == NULL)
1378 		return;			/* cancelled - nothing to do */
1379 
1380 	uxfer = (struct libusb_transfer *)(
1381 	    ((uint8_t *)sxfer) + sizeof(*sxfer));
1382 
1383 	flags = uxfer->flags;
1384 
1385 	switch (status) {
1386 	case LIBUSB20_TRANSFER_COMPLETED:
1387 
1388 		uxfer->actual_length += actlen;
1389 
1390 		/* subtract length of SETUP packet, if any */
1391 		actlen -= libusb20_tr_get_length(pxfer, 0);
1392 
1393 		/* check for short packet */
1394 		if (sxfer->last_len != actlen) {
1395 			if (flags & LIBUSB_TRANSFER_SHORT_NOT_OK) {
1396 				libusb10_complete_transfer(pxfer, sxfer, LIBUSB_TRANSFER_ERROR);
1397 			} else {
1398 				libusb10_complete_transfer(pxfer, sxfer, LIBUSB_TRANSFER_COMPLETED);
1399 			}
1400 			break;
1401 		}
1402 		/* check for end of data */
1403 		if (sxfer->rem_len == 0) {
1404 			libusb10_complete_transfer(pxfer, sxfer, LIBUSB_TRANSFER_COMPLETED);
1405 			break;
1406 		}
1407 		/* FALLTHROUGH */
1408 
1409 	case LIBUSB20_TRANSFER_START:
1410 		if (max_bulk > sxfer->rem_len) {
1411 			max_bulk = sxfer->rem_len;
1412 		}
1413 		/* setup new CONTROL transaction */
1414 		if (status == LIBUSB20_TRANSFER_COMPLETED) {
1415 			/* next fragment - don't send SETUP packet */
1416 			libusb20_tr_set_length(pxfer, 0, 0);
1417 		} else {
1418 			/* first fragment - send SETUP packet */
1419 			libusb20_tr_set_length(pxfer, 8, 0);
1420 			libusb20_tr_set_buffer(pxfer, uxfer->buffer, 0);
1421 		}
1422 
1423 		if (max_bulk != 0) {
1424 			libusb20_tr_set_length(pxfer, max_bulk, 1);
1425 			libusb20_tr_set_buffer(pxfer, sxfer->curr_data, 1);
1426 			libusb20_tr_set_total_frames(pxfer, 2);
1427 		} else {
1428 			libusb20_tr_set_total_frames(pxfer, 1);
1429 		}
1430 
1431 		/* update counters */
1432 		sxfer->last_len = max_bulk;
1433 		sxfer->curr_data += max_bulk;
1434 		sxfer->rem_len -= max_bulk;
1435 
1436 		libusb20_tr_submit(pxfer);
1437 
1438 		/* check if we can fork another USB transfer */
1439 		if (sxfer->rem_len == 0)
1440 			libusb10_submit_transfer_sub(libusb20_tr_get_priv_sc0(pxfer), uxfer->endpoint);
1441 		break;
1442 
1443 	default:
1444 		libusb10_complete_transfer(pxfer, sxfer, libusb10_convert_error(status));
1445 		break;
1446 	}
1447 }
1448 
1449 /* The following function must be called locked */
1450 
1451 static void
libusb10_submit_transfer_sub(struct libusb20_device * pdev,uint8_t endpoint)1452 libusb10_submit_transfer_sub(struct libusb20_device *pdev, uint8_t endpoint)
1453 {
1454 	struct libusb20_transfer *pxfer0;
1455 	struct libusb20_transfer *pxfer1;
1456 	struct libusb_super_transfer *sxfer;
1457 	struct libusb_transfer *uxfer;
1458 	struct libusb_device *dev;
1459 	int err;
1460 	int buffsize;
1461 	int maxframe;
1462 	int temp;
1463 
1464 	dev = libusb_get_device(pdev);
1465 
1466 	pxfer0 = libusb10_get_transfer(pdev, endpoint, 0);
1467 	pxfer1 = libusb10_get_transfer(pdev, endpoint, 1);
1468 
1469 	if (pxfer0 == NULL || pxfer1 == NULL)
1470 		return;			/* shouldn't happen */
1471 
1472 	temp = 0;
1473 	if (libusb20_tr_pending(pxfer0))
1474 		temp |= 1;
1475 	if (libusb20_tr_pending(pxfer1))
1476 		temp |= 2;
1477 
1478 	switch (temp) {
1479 	case 3:
1480 		/* wait till one of the transfers complete */
1481 		return;
1482 	case 2:
1483 		sxfer = libusb20_tr_get_priv_sc1(pxfer1);
1484 		if (sxfer == NULL)
1485 			return;		/* cancelling */
1486 		if (sxfer->rem_len)
1487 			return;		/* cannot queue another one */
1488 		/* swap transfers */
1489 		pxfer1 = pxfer0;
1490 		break;
1491 	case 1:
1492 		sxfer = libusb20_tr_get_priv_sc1(pxfer0);
1493 		if (sxfer == NULL)
1494 			return;		/* cancelling */
1495 		if (sxfer->rem_len)
1496 			return;		/* cannot queue another one */
1497 		/* swap transfers */
1498 		pxfer0 = pxfer1;
1499 		break;
1500 	default:
1501 		break;
1502 	}
1503 
1504 	/* find next transfer on same endpoint */
1505 	TAILQ_FOREACH(sxfer, &dev->tr_head, entry) {
1506 
1507 		uxfer = (struct libusb_transfer *)(
1508 		    ((uint8_t *)sxfer) + sizeof(*sxfer));
1509 
1510 		if (uxfer->endpoint == endpoint) {
1511 			TAILQ_REMOVE(&dev->tr_head, sxfer, entry);
1512 			sxfer->entry.tqe_prev = NULL;
1513 			goto found;
1514 		}
1515 	}
1516 	return;				/* success */
1517 
1518 found:
1519 
1520 	libusb20_tr_set_priv_sc0(pxfer0, pdev);
1521 	libusb20_tr_set_priv_sc1(pxfer0, sxfer);
1522 
1523 	/* reset super transfer state */
1524 	sxfer->rem_len = uxfer->length;
1525 	sxfer->curr_data = uxfer->buffer;
1526 	uxfer->actual_length = 0;
1527 
1528 	switch (uxfer->type) {
1529 	case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
1530 		libusb20_tr_set_callback(pxfer0, libusb10_isoc_proxy);
1531 		break;
1532 	case LIBUSB_TRANSFER_TYPE_BULK:
1533 	case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
1534 	case LIBUSB_TRANSFER_TYPE_INTERRUPT:
1535 		libusb20_tr_set_callback(pxfer0, libusb10_bulk_intr_proxy);
1536 		break;
1537 	case LIBUSB_TRANSFER_TYPE_CONTROL:
1538 		libusb20_tr_set_callback(pxfer0, libusb10_ctrl_proxy);
1539 		if (sxfer->rem_len < 8)
1540 			goto failure;
1541 
1542 		/* remove SETUP packet from data */
1543 		sxfer->rem_len -= 8;
1544 		sxfer->curr_data += 8;
1545 		break;
1546 	default:
1547 		goto failure;
1548 	}
1549 
1550 	buffsize = libusb10_get_buffsize(pdev, uxfer);
1551 	maxframe = libusb10_get_maxframe(pdev, uxfer);
1552 
1553 	/* make sure the transfer is opened */
1554 	err = libusb20_tr_open_stream(pxfer0, buffsize, maxframe,
1555 	    endpoint, sxfer->stream_id);
1556 	if (err && (err != LIBUSB20_ERROR_BUSY)) {
1557 		goto failure;
1558 	}
1559 	libusb20_tr_start(pxfer0);
1560 	return;
1561 
1562 failure:
1563 	libusb10_complete_transfer(pxfer0, sxfer, LIBUSB_TRANSFER_ERROR);
1564 	/* make sure our event loop spins the done handler */
1565 	libusb_interrupt_event_handler(dev->ctx);
1566 }
1567 
1568 /* The following function must be called unlocked */
1569 
1570 int
libusb_submit_transfer(struct libusb_transfer * uxfer)1571 libusb_submit_transfer(struct libusb_transfer *uxfer)
1572 {
1573 	struct libusb20_transfer *pxfer0;
1574 	struct libusb20_transfer *pxfer1;
1575 	struct libusb_super_transfer *sxfer;
1576 	struct libusb_device *dev;
1577 	uint8_t endpoint;
1578 	int err;
1579 
1580 	if (uxfer == NULL)
1581 		return (LIBUSB_ERROR_INVALID_PARAM);
1582 
1583 	if (uxfer->dev_handle == NULL)
1584 		return (LIBUSB_ERROR_INVALID_PARAM);
1585 
1586 	endpoint = uxfer->endpoint;
1587 
1588 	dev = libusb_get_device(uxfer->dev_handle);
1589 
1590 	DPRINTF(dev->ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb_submit_transfer enter");
1591 
1592 	sxfer = (struct libusb_super_transfer *)(
1593 	    (uint8_t *)uxfer - sizeof(*sxfer));
1594 
1595 	CTX_LOCK(dev->ctx);
1596 
1597 	pxfer0 = libusb10_get_transfer(uxfer->dev_handle, endpoint, 0);
1598 	pxfer1 = libusb10_get_transfer(uxfer->dev_handle, endpoint, 1);
1599 
1600 	if (pxfer0 == NULL || pxfer1 == NULL) {
1601 		err = LIBUSB_ERROR_OTHER;
1602 	} else if ((sxfer->entry.tqe_prev != NULL) ||
1603 	    (libusb20_tr_get_priv_sc1(pxfer0) == sxfer) ||
1604 	    (libusb20_tr_get_priv_sc1(pxfer1) == sxfer)) {
1605 		err = LIBUSB_ERROR_BUSY;
1606 	} else if (dev->device_is_gone != 0) {
1607 		err = LIBUSB_ERROR_NO_DEVICE;
1608 	} else {
1609 
1610 		/* set pending state */
1611 		sxfer->state = LIBUSB_SUPER_XFER_ST_PEND;
1612 
1613 		/* insert transfer into transfer head list */
1614 		TAILQ_INSERT_TAIL(&dev->tr_head, sxfer, entry);
1615 
1616 		/* start work transfers */
1617 		libusb10_submit_transfer_sub(
1618 		    uxfer->dev_handle, endpoint);
1619 
1620 		err = 0;		/* success */
1621 	}
1622 
1623 	CTX_UNLOCK(dev->ctx);
1624 
1625 	DPRINTF(dev->ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb_submit_transfer leave %d", err);
1626 
1627 	return (err);
1628 }
1629 
1630 /* Asynchronous transfer cancel */
1631 
1632 int
libusb_cancel_transfer(struct libusb_transfer * uxfer)1633 libusb_cancel_transfer(struct libusb_transfer *uxfer)
1634 {
1635 	struct libusb20_transfer *pxfer0;
1636 	struct libusb20_transfer *pxfer1;
1637 	struct libusb_super_transfer *sxfer;
1638 	struct libusb_device *dev;
1639 	struct libusb_device_handle *devh;
1640 	uint8_t endpoint;
1641 	int retval;
1642 
1643 	if (uxfer == NULL)
1644 		return (LIBUSB_ERROR_INVALID_PARAM);
1645 
1646 	/* check if not initialised */
1647 	if ((devh = uxfer->dev_handle) == NULL)
1648 		return (LIBUSB_ERROR_NOT_FOUND);
1649 
1650 	endpoint = uxfer->endpoint;
1651 
1652 	dev = libusb_get_device(devh);
1653 
1654 	DPRINTF(dev->ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb_cancel_transfer enter");
1655 
1656 	sxfer = (struct libusb_super_transfer *)(
1657 	    (uint8_t *)uxfer - sizeof(*sxfer));
1658 
1659 	retval = 0;
1660 
1661 	CTX_LOCK(dev->ctx);
1662 
1663 	pxfer0 = libusb10_get_transfer(devh, endpoint, 0);
1664 	pxfer1 = libusb10_get_transfer(devh, endpoint, 1);
1665 
1666 	if (sxfer->state != LIBUSB_SUPER_XFER_ST_PEND) {
1667 		/* only update the transfer status */
1668 		uxfer->status = LIBUSB_TRANSFER_CANCELLED;
1669 		retval = LIBUSB_ERROR_NOT_FOUND;
1670 	} else if (sxfer->entry.tqe_prev != NULL) {
1671 		/* we are lucky - transfer is on a queue */
1672 		TAILQ_REMOVE(&dev->tr_head, sxfer, entry);
1673 		sxfer->entry.tqe_prev = NULL;
1674 		libusb10_complete_transfer(NULL,
1675 		    sxfer, LIBUSB_TRANSFER_CANCELLED);
1676 		/* make sure our event loop spins the done handler */
1677 		libusb_interrupt_event_handler(dev->ctx);
1678 	} else if (pxfer0 == NULL || pxfer1 == NULL) {
1679 		/* not started */
1680 		retval = LIBUSB_ERROR_NOT_FOUND;
1681 	} else if (libusb20_tr_get_priv_sc1(pxfer0) == sxfer) {
1682 		libusb10_complete_transfer(pxfer0,
1683 		    sxfer, LIBUSB_TRANSFER_CANCELLED);
1684 		if (dev->device_is_gone != 0) {
1685 			/* clear transfer pointer */
1686 			libusb20_tr_set_priv_sc1(pxfer0, NULL);
1687 			/* make sure our event loop spins the done handler */
1688 			libusb_interrupt_event_handler(dev->ctx);
1689 		} else {
1690 			libusb20_tr_stop(pxfer0);
1691 			/* make sure the queue doesn't stall */
1692 			libusb10_submit_transfer_sub(devh, endpoint);
1693 		}
1694 	} else if (libusb20_tr_get_priv_sc1(pxfer1) == sxfer) {
1695 		libusb10_complete_transfer(pxfer1,
1696 		    sxfer, LIBUSB_TRANSFER_CANCELLED);
1697 		/* check if handle is still active */
1698 		if (dev->device_is_gone != 0) {
1699 			/* clear transfer pointer */
1700 			libusb20_tr_set_priv_sc1(pxfer1, NULL);
1701 			/* make sure our event loop spins the done handler */
1702 			libusb_interrupt_event_handler(dev->ctx);
1703 		} else {
1704 			libusb20_tr_stop(pxfer1);
1705 			/* make sure the queue doesn't stall */
1706 			libusb10_submit_transfer_sub(devh, endpoint);
1707 		}
1708 	} else {
1709 		/* not started */
1710 		retval = LIBUSB_ERROR_NOT_FOUND;
1711 	}
1712 
1713 	CTX_UNLOCK(dev->ctx);
1714 
1715 	DPRINTF(dev->ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb_cancel_transfer leave");
1716 
1717 	return (retval);
1718 }
1719 
1720 UNEXPORTED void
libusb10_cancel_all_transfer(libusb_device * dev)1721 libusb10_cancel_all_transfer(libusb_device *dev)
1722 {
1723 	struct libusb20_device *pdev = dev->os_priv;
1724 	unsigned x;
1725 
1726 	for (x = 0; x != LIBUSB_NUM_SW_ENDPOINTS; x++) {
1727 		struct libusb20_transfer *xfer;
1728 
1729 		xfer = libusb20_tr_get_pointer(pdev, x);
1730 		if (xfer == NULL)
1731 			continue;
1732 		libusb20_tr_close(xfer);
1733 	}
1734 }
1735 
1736 UNEXPORTED void
libusb10_cancel_all_transfer_locked(struct libusb20_device * pdev,struct libusb_device * dev)1737 libusb10_cancel_all_transfer_locked(struct libusb20_device *pdev, struct libusb_device *dev)
1738 {
1739 	struct libusb_super_transfer *sxfer;
1740 	unsigned x;
1741 
1742 	for (x = 0; x != LIBUSB_NUM_SW_ENDPOINTS; x++) {
1743 		struct libusb20_transfer *xfer;
1744 
1745 		xfer = libusb20_tr_get_pointer(pdev, x);
1746 		if (xfer == NULL)
1747 			continue;
1748 		if (libusb20_tr_pending(xfer) == 0)
1749 			continue;
1750 		sxfer = libusb20_tr_get_priv_sc1(xfer);
1751 		if (sxfer == NULL)
1752 			continue;
1753 		/* complete pending transfer */
1754 		libusb10_complete_transfer(xfer, sxfer, LIBUSB_TRANSFER_ERROR);
1755 	}
1756 
1757 	while ((sxfer = TAILQ_FIRST(&dev->tr_head))) {
1758 		TAILQ_REMOVE(&dev->tr_head, sxfer, entry);
1759 
1760 		/* complete pending transfer */
1761 		libusb10_complete_transfer(NULL, sxfer, LIBUSB_TRANSFER_ERROR);
1762 	}
1763 }
1764 
1765 uint16_t
libusb_cpu_to_le16(uint16_t x)1766 libusb_cpu_to_le16(uint16_t x)
1767 {
1768 	return (htole16(x));
1769 }
1770 
1771 uint16_t
libusb_le16_to_cpu(uint16_t x)1772 libusb_le16_to_cpu(uint16_t x)
1773 {
1774 	return (le16toh(x));
1775 }
1776 
1777 const char *
libusb_strerror(int code)1778 libusb_strerror(int code)
1779 {
1780 	int entry = -code;
1781 
1782 	if (code == LIBUSB_ERROR_OTHER)
1783 		entry = LIBUSB_ERROR_COUNT - 1;
1784 	/*
1785 	 * The libusb upstream considers all code out of range a
1786 	 * LIBUSB_ERROR_OTHER. In FreeBSD, it is a special unknown error. We
1787 	 * preserve the FreeBSD implementation as I think it make sense.
1788 	 */
1789 	if (entry < 0 || entry >= LIBUSB_ERROR_COUNT)
1790 		entry = LIBUSB_ERROR_COUNT;
1791 
1792 	/*
1793 	 * Fall back to English one as the translation may be unimplemented
1794 	 * when adding new error code.
1795 	 */
1796 	if (default_language_context->err_strs[entry] == NULL)
1797 		return (libusb_language_ctx[0].err_strs[entry]);
1798 
1799 	return (default_language_context->err_strs[entry]);
1800 }
1801 
1802 const char *
libusb_error_name(int code)1803 libusb_error_name(int code)
1804 {
1805 	switch (code) {
1806 	case LIBUSB_SUCCESS:
1807 		return ("LIBUSB_SUCCESS");
1808 	case LIBUSB_ERROR_IO:
1809 		return ("LIBUSB_ERROR_IO");
1810 	case LIBUSB_ERROR_INVALID_PARAM:
1811 		return ("LIBUSB_ERROR_INVALID_PARAM");
1812 	case LIBUSB_ERROR_ACCESS:
1813 		return ("LIBUSB_ERROR_ACCESS");
1814 	case LIBUSB_ERROR_NO_DEVICE:
1815 		return ("LIBUSB_ERROR_NO_DEVICE");
1816 	case LIBUSB_ERROR_NOT_FOUND:
1817 		return ("LIBUSB_ERROR_NOT_FOUND");
1818 	case LIBUSB_ERROR_BUSY:
1819 		return ("LIBUSB_ERROR_BUSY");
1820 	case LIBUSB_ERROR_TIMEOUT:
1821 		return ("LIBUSB_ERROR_TIMEOUT");
1822 	case LIBUSB_ERROR_OVERFLOW:
1823 		return ("LIBUSB_ERROR_OVERFLOW");
1824 	case LIBUSB_ERROR_PIPE:
1825 		return ("LIBUSB_ERROR_PIPE");
1826 	case LIBUSB_ERROR_INTERRUPTED:
1827 		return ("LIBUSB_ERROR_INTERRUPTED");
1828 	case LIBUSB_ERROR_NO_MEM:
1829 		return ("LIBUSB_ERROR_NO_MEM");
1830 	case LIBUSB_ERROR_NOT_SUPPORTED:
1831 		return ("LIBUSB_ERROR_NOT_SUPPORTED");
1832 	case LIBUSB_ERROR_OTHER:
1833 		return ("LIBUSB_ERROR_OTHER");
1834 	default:
1835 		return ("LIBUSB_ERROR_UNKNOWN");
1836 	}
1837 }
1838 
1839 int
libusb_has_capability(uint32_t capability)1840 libusb_has_capability(uint32_t capability)
1841 {
1842 
1843 	switch (capability) {
1844 	case LIBUSB_CAP_HAS_CAPABILITY:
1845 	case LIBUSB_CAP_HAS_HOTPLUG:
1846 	case LIBUSB_CAP_HAS_HID_ACCESS:
1847 	case LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER:
1848 		return (1);
1849 	default:
1850 		return (0);
1851 	}
1852 }
1853 
1854 void
libusb_log_va_args(struct libusb_context * ctx,enum libusb_log_level level,const char * fmt,...)1855 libusb_log_va_args(struct libusb_context *ctx, enum libusb_log_level level,
1856     const char *fmt, ...)
1857 {
1858 	static const char *log_prefix[5] = {
1859 		[LIBUSB_LOG_LEVEL_ERROR] = "LIBUSB_ERROR",
1860 		[LIBUSB_LOG_LEVEL_WARNING] = "LIBUSB_WARN",
1861 		[LIBUSB_LOG_LEVEL_INFO] = "LIBUSB_INFO",
1862 		[LIBUSB_LOG_LEVEL_DEBUG] = "LIBUSB_DEBUG",
1863 	};
1864 
1865 	char buffer[LIBUSB_LOG_BUFFER_SIZE];
1866 	char new_fmt[LIBUSB_LOG_BUFFER_SIZE];
1867 	va_list args;
1868 
1869 	ctx = GET_CONTEXT(ctx);
1870 
1871 	if (ctx->debug < level)
1872 		return;
1873 
1874 	va_start(args, fmt);
1875 
1876 	snprintf(new_fmt, sizeof(new_fmt), "%s: %s\n", log_prefix[level], fmt);
1877 	vsnprintf(buffer, sizeof(buffer), new_fmt, args);
1878 	fputs(buffer, stdout);
1879 
1880 	va_end(args);
1881 }
1882 
1883 /*
1884  * Upstream code actually recognizes the first two characters to identify a
1885  * language. We do so to provide API compatibility with setlocale.
1886  */
1887 int
libusb_setlocale(const char * locale)1888 libusb_setlocale(const char *locale)
1889 {
1890 	size_t idx;
1891 	const char *lang;
1892 
1893 	if (locale == NULL || strlen(locale) < 2 ||
1894 	    (locale[2] != '\0' && strchr("-_.", locale[2]) == NULL))
1895 		return (LIBUSB_ERROR_INVALID_PARAM);
1896 
1897 	for (idx = 0; idx < nitems(libusb_language_ctx); ++idx) {
1898 		lang = libusb_language_ctx[idx].lang_name;
1899 		if (tolower(locale[0]) == lang[0] &&
1900 		    tolower(locale[1]) == lang[1]) {
1901 			default_language_context = &libusb_language_ctx[idx];
1902 			return (LIBUSB_SUCCESS);
1903 		}
1904 	}
1905 
1906 	return (LIBUSB_ERROR_INVALID_PARAM);
1907 }
1908 
1909 unsigned char *
libusb_dev_mem_alloc(libusb_device_handle * devh)1910 libusb_dev_mem_alloc(libusb_device_handle *devh)
1911 {
1912 	return (NULL);
1913 }
1914 
1915 int
libusb_dev_mem_free(libusb_device_handle * devh,unsigned char * buffer,size_t size)1916 libusb_dev_mem_free(libusb_device_handle *devh, unsigned char *buffer,
1917     size_t size)
1918 {
1919 	return (LIBUSB_ERROR_NOT_SUPPORTED);
1920 }
1921 
1922 int
libusb_wrap_sys_device(libusb_context * ctx,intptr_t sys_dev,libusb_device_handle ** dev_handle)1923 libusb_wrap_sys_device(libusb_context *ctx, intptr_t sys_dev,
1924     libusb_device_handle **dev_handle)
1925 {
1926 	return (LIBUSB_ERROR_NOT_SUPPORTED);
1927 }
1928