xref: /freebsd/lib/libusb/libusb10.c (revision eb6219e337483cb80eccb6f2b4ad649bc1d751ec)
1 /* $FreeBSD$ */
2 /*-
3  * Copyright (c) 2009 Sylvestre Gallon. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26 
27 #include <sys/queue.h>
28 #include <stdlib.h>
29 #include <unistd.h>
30 #include <stdio.h>
31 #include <poll.h>
32 #include <pthread.h>
33 #include <time.h>
34 #include <errno.h>
35 
36 #include "libusb20.h"
37 #include "libusb20_desc.h"
38 #include "libusb20_int.h"
39 #include "libusb.h"
40 #include "libusb10.h"
41 
42 static pthread_mutex_t default_context_lock = PTHREAD_MUTEX_INITIALIZER;
43 struct libusb_context *usbi_default_context = NULL;
44 pthread_mutex_t libusb20_lock = PTHREAD_MUTEX_INITIALIZER;
45 
46 /*  Library initialisation / deinitialisation */
47 
48 void
49 libusb_set_debug(libusb_context * ctx, int level)
50 {
51 	GET_CONTEXT(ctx);
52 	if (ctx)
53 		ctx->debug = level;
54 }
55 
56 int
57 libusb_init(libusb_context ** context)
58 {
59 	struct libusb_context *ctx;
60 	char * debug;
61 	int ret;
62 
63 	ctx = malloc(sizeof(*ctx));
64 	if (!ctx)
65 		return (LIBUSB_ERROR_INVALID_PARAM);
66 
67 	memset(ctx, 0, sizeof(*ctx));
68 
69 	debug = getenv("LIBUSB_DEBUG");
70 	if (debug != NULL) {
71 		ctx->debug = atoi(debug);
72 		if (ctx->debug != 0)
73 			ctx->debug_fixed = 1;
74 	}
75 
76 	pthread_mutex_init(&ctx->usb_devs_lock, NULL);
77 	pthread_mutex_init(&ctx->open_devs_lock, NULL);
78 	USB_LIST_INIT(&ctx->usb_devs);
79 	USB_LIST_INIT(&ctx->open_devs);
80 
81 	pthread_mutex_init(&ctx->flying_transfers_lock, NULL);
82 	pthread_mutex_init(&ctx->pollfds_lock, NULL);
83 	pthread_mutex_init(&ctx->pollfd_modify_lock, NULL);
84 	pthread_mutex_init(&ctx->events_lock, NULL);
85 	pthread_mutex_init(&ctx->event_waiters_lock, NULL);
86 	pthread_cond_init(&ctx->event_waiters_cond, NULL);
87 
88 	USB_LIST_INIT(&ctx->flying_transfers);
89 	USB_LIST_INIT(&ctx->pollfds);
90 
91 	ret = pipe(ctx->ctrl_pipe);
92 	if (ret < 0) {
93 		usb_remove_pollfd(ctx, ctx->ctrl_pipe[0]);
94 		close(ctx->ctrl_pipe[0]);
95 		close(ctx->ctrl_pipe[1]);
96 		free(ctx);
97 		return (LIBUSB_ERROR_OTHER);
98 	}
99 
100 	ret = usb_add_pollfd(ctx, ctx->ctrl_pipe[0], POLLIN);
101 	if (ret < 0) {
102 		usb_remove_pollfd(ctx, ctx->ctrl_pipe[0]);
103 		close(ctx->ctrl_pipe[0]);
104 		close(ctx->ctrl_pipe[1]);
105 		free(ctx);
106 		return ret;
107 	}
108 
109 	pthread_mutex_lock(&default_context_lock);
110 	if (usbi_default_context == NULL) {
111 		usbi_default_context = ctx;
112 	}
113 	pthread_mutex_unlock(&default_context_lock);
114 
115 	if (context)
116 		*context = ctx;
117 
118 	return (0);
119 }
120 
121 void
122 libusb_exit(libusb_context * ctx)
123 {
124 	GET_CONTEXT(ctx);
125 
126 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_exit enter");
127 	usb_remove_pollfd(ctx, ctx->ctrl_pipe[0]);
128 	close(ctx->ctrl_pipe[0]);
129 	close(ctx->ctrl_pipe[1]);
130 
131 	pthread_mutex_lock(&default_context_lock);
132 	if (ctx == usbi_default_context) {
133 		usbi_default_context = NULL;
134 	}
135 	pthread_mutex_unlock(&default_context_lock);
136 
137 	free(ctx);
138 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_exit leave");
139 }
140 
141 /* Device handling and initialisation. */
142 
143 ssize_t
144 libusb_get_device_list(libusb_context * ctx, libusb_device *** list)
145 {
146 	struct libusb20_device *pdev;
147 	struct LIBUSB20_DEVICE_DESC_DECODED *ddesc;
148 	struct libusb_device *dev;
149 	struct libusb20_backend *usb_backend;
150 	int i;
151 
152 	GET_CONTEXT(ctx);
153 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device_list enter");
154 
155 	usb_backend = libusb20_be_alloc_default();
156 	if (usb_backend == NULL)
157 		return (-1);
158 
159 	pdev = NULL;
160 	i = 0;
161 	while ((pdev = libusb20_be_device_foreach(usb_backend, pdev)))
162 		i++;
163 
164 	if (list == NULL) {
165 		libusb20_be_free(usb_backend);
166 		return (LIBUSB_ERROR_INVALID_PARAM);
167 	}
168 	*list = malloc((i + 1) * sizeof(void *));
169 	if (*list == NULL) {
170 		libusb20_be_free(usb_backend);
171 		return (LIBUSB_ERROR_NO_MEM);
172 	}
173 	i = 0;
174 	while ((pdev = libusb20_be_device_foreach(usb_backend, NULL))) {
175 		/* get device into libUSB v1.0 list */
176 		libusb20_be_dequeue_device(usb_backend, pdev);
177 
178 		ddesc = libusb20_dev_get_device_desc(pdev);
179 		dev = malloc(sizeof(*dev));
180 		if (dev == NULL) {
181 			free(*list);
182 			libusb20_be_free(usb_backend);
183 			return (LIBUSB_ERROR_NO_MEM);
184 		}
185 		memset(dev, 0, sizeof(*dev));
186 
187 		pthread_mutex_init(&dev->lock, NULL);
188 		dev->ctx = ctx;
189 		dev->bus_number = pdev->bus_number;
190 		dev->device_address = pdev->device_address;
191 		dev->num_configurations = ddesc->bNumConfigurations;
192 
193 		/* link together the two structures */
194 		dev->os_priv = pdev;
195 
196 		pthread_mutex_lock(&ctx->usb_devs_lock);
197 		LIST_ADD(&dev->list, &ctx->usb_devs);
198 		pthread_mutex_unlock(&ctx->usb_devs_lock);
199 
200 		(*list)[i] = libusb_ref_device(dev);
201 		i++;
202 	}
203 	(*list)[i] = NULL;
204 
205 	libusb20_be_free(usb_backend);
206 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device_list leave");
207 	return (i);
208 }
209 
210 /*
211  * In this function we cant free all the device contained into list because
212  * open_with_pid_vid use some node of list after the free_device_list.
213  */
214 void
215 libusb_free_device_list(libusb_device **list, int unref_devices)
216 {
217 	int i;
218 	libusb_context *ctx;
219 
220 	ctx = NULL;
221 	GET_CONTEXT(ctx);
222 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_free_device_list enter");
223 
224 	if (list == NULL)
225 		return ;
226 
227 	if (unref_devices) {
228 		for (i = 0; list[i] != NULL; i++)
229 			libusb_unref_device(list[i]);
230 	}
231 	free(list);
232 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_free_device_list leave");
233 }
234 
235 uint8_t
236 libusb_get_bus_number(libusb_device * dev)
237 {
238 	libusb_context *ctx;
239 
240 	ctx = NULL;
241 	GET_CONTEXT(ctx);
242 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_bus_number enter");
243 
244 	if (dev == NULL)
245 		return (LIBUSB_ERROR_NO_DEVICE);
246 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_bus_number leave");
247 	return (dev->bus_number);
248 }
249 
250 uint8_t
251 libusb_get_device_address(libusb_device * dev)
252 {
253 	libusb_context *ctx;
254 
255 	ctx = NULL;
256 	GET_CONTEXT(ctx);
257 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device_address enter");
258 
259 	if (dev == NULL)
260 		return (LIBUSB_ERROR_NO_DEVICE);
261 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device_address leave");
262 	return (dev->device_address);
263 }
264 
265 int
266 libusb_get_max_packet_size(libusb_device *dev, unsigned char endpoint)
267 {
268 	struct libusb_config_descriptor *pdconf;
269 	struct libusb_interface *pinf;
270 	struct libusb_interface_descriptor *pdinf;
271 	struct libusb_endpoint_descriptor *pdend;
272 	libusb_context *ctx;
273 	int i, j, k, ret;
274 
275 	ctx = NULL;
276 	GET_CONTEXT(ctx);
277 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_max_packet_size enter");
278 
279 	if (dev == NULL)
280 		return (LIBUSB_ERROR_NO_DEVICE);
281 
282 	if (libusb_get_active_config_descriptor(dev, &pdconf) < 0)
283 		return (LIBUSB_ERROR_OTHER);
284 
285 	ret = LIBUSB_ERROR_NOT_FOUND;
286 	for (i = 0 ; i < pdconf->bNumInterfaces ; i++) {
287 		pinf = &pdconf->interface[i];
288 		for (j = 0 ; j < pinf->num_altsetting ; j++) {
289 			pdinf = &pinf->altsetting[j];
290 			for (k = 0 ; k < pdinf->bNumEndpoints ; k++) {
291 				pdend = &pdinf->endpoint[k];
292 				if (pdend->bEndpointAddress == endpoint) {
293 					ret = pdend->wMaxPacketSize;
294 					goto out;
295 				}
296 			}
297 		}
298 	}
299 
300 out:
301 	libusb_free_config_descriptor(pdconf);
302 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_max_packet_size leave");
303 	return (ret);
304 }
305 
306 libusb_device *
307 libusb_ref_device(libusb_device * dev)
308 {
309 	libusb_context *ctx;
310 
311 	ctx = NULL;
312 	GET_CONTEXT(ctx);
313 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_ref_device enter");
314 
315 	if (dev == NULL)
316 		return (NULL);
317 
318 	pthread_mutex_lock(&dev->lock);
319 	dev->refcnt++;
320 	pthread_mutex_unlock(&dev->lock);
321 
322 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_ref_device leave");
323 	return (dev);
324 }
325 
326 void
327 libusb_unref_device(libusb_device * dev)
328 {
329 	libusb_context *ctx;
330 
331 	ctx = NULL;
332 	GET_CONTEXT(ctx);
333 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_unref_device enter");
334 
335 	if (dev == NULL)
336 		return;
337 
338 	pthread_mutex_lock(&dev->lock);
339 	dev->refcnt--;
340 	pthread_mutex_unlock(&dev->lock);
341 
342 	if (dev->refcnt == 0) {
343 		pthread_mutex_lock(&dev->ctx->usb_devs_lock);
344 		LIST_DEL(&dev->list);
345 		pthread_mutex_unlock(&dev->ctx->usb_devs_lock);
346 
347 		libusb20_dev_free(dev->os_priv);
348 		free(dev);
349 	}
350 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_unref_device leave");
351 }
352 
353 int
354 libusb_open(libusb_device * dev, libusb_device_handle **devh)
355 {
356 	libusb_context *ctx = dev->ctx;
357 	struct libusb20_device *pdev = dev->os_priv;
358 	libusb_device_handle *hdl;
359 	unsigned char dummy;
360 	int err;
361 
362 	GET_CONTEXT(ctx);
363 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open enter");
364 
365 	dummy = 1;
366 	if (devh == NULL)
367 		return (LIBUSB_ERROR_INVALID_PARAM);
368 
369 	hdl = malloc(sizeof(*hdl));
370 	if (hdl == NULL)
371 		return (LIBUSB_ERROR_NO_MEM);
372 
373 	err = libusb20_dev_open(pdev, 16 * 4 /* number of endpoints */ );
374 	if (err) {
375 		free(hdl);
376 		return (LIBUSB_ERROR_NO_MEM);
377 	}
378 	memset(hdl, 0, sizeof(*hdl));
379 	pthread_mutex_init(&hdl->lock, NULL);
380 
381 	hdl->dev = libusb_ref_device(dev);
382 	hdl->claimed_interfaces = 0;
383 	hdl->os_priv = dev->os_priv;
384 	err = usb_add_pollfd(ctx, libusb20_dev_get_fd(pdev), POLLIN |
385 	    POLLOUT | POLLRDNORM | POLLWRNORM);
386 	if (err < 0) {
387 		libusb_unref_device(dev);
388 		free(hdl);
389 		return (err);
390 	}
391 
392 	pthread_mutex_lock(&ctx->open_devs_lock);
393 	LIST_ADD(&hdl->list, &ctx->open_devs);
394 	pthread_mutex_unlock(&ctx->open_devs_lock);
395 
396 	*devh = hdl;
397 
398 	pthread_mutex_lock(&ctx->pollfd_modify_lock);
399 	ctx->pollfd_modify++;
400 	pthread_mutex_unlock(&ctx->pollfd_modify_lock);
401 
402 	err = write(ctx->ctrl_pipe[1], &dummy, sizeof(dummy));
403 	if (err <= 0) {
404 		pthread_mutex_lock(&ctx->pollfd_modify_lock);
405 		ctx->pollfd_modify--;
406 		pthread_mutex_unlock(&ctx->pollfd_modify_lock);
407 		return 0;
408 	}
409 
410 	libusb_lock_events(ctx);
411 	read(ctx->ctrl_pipe[0], &dummy, sizeof(dummy));
412 	pthread_mutex_lock(&ctx->pollfd_modify_lock);
413 	ctx->pollfd_modify--;
414 	pthread_mutex_unlock(&ctx->pollfd_modify_lock);
415 	libusb_unlock_events(ctx);
416 
417 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open leave");
418 	return (0);
419 }
420 
421 libusb_device_handle *
422 libusb_open_device_with_vid_pid(libusb_context * ctx, uint16_t vendor_id,
423     uint16_t product_id)
424 {
425 	struct libusb_device **devs;
426 	struct libusb_device_handle *devh;
427 	struct libusb20_device *pdev;
428 	struct LIBUSB20_DEVICE_DESC_DECODED *pdesc;
429 	int i, j;
430 
431 	GET_CONTEXT(ctx);
432 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open_device_width_vid_pid enter");
433 
434 	devh = NULL;
435 
436 	if ((i = libusb_get_device_list(ctx, &devs)) < 0)
437 		return (NULL);
438 
439 	for (j = 0; j < i; j++) {
440 		pdev = (struct libusb20_device *)devs[j]->os_priv;
441 		pdesc = libusb20_dev_get_device_desc(pdev);
442 		if (pdesc->idVendor == vendor_id &&
443 		    pdesc->idProduct == product_id)
444 			if (libusb_open(devs[j], &devh) < 0)
445 				devh = NULL;
446 	}
447 
448 	libusb_free_device_list(devs, 1);
449 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open_device_width_vid_pid leave");
450 	return (devh);
451 }
452 
453 void
454 libusb_close(libusb_device_handle * devh)
455 {
456 	libusb_context *ctx;
457 	struct libusb20_device *pdev;
458 	unsigned char dummy = 1;
459 	int err;
460 
461 	if (devh == NULL)
462 		return ;
463 
464 	ctx = devh->dev->ctx;
465 	pdev = devh->os_priv;
466 
467 	GET_CONTEXT(ctx);
468 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_close enter");
469 
470 	pthread_mutex_lock(&ctx->pollfd_modify_lock);
471 	ctx->pollfd_modify++;
472 	pthread_mutex_unlock(&ctx->pollfd_modify_lock);
473 
474 	err = write(ctx->ctrl_pipe[1], &dummy, sizeof(dummy));
475 
476 	if (err <= 0) {
477 		pthread_mutex_lock(&ctx->open_devs_lock);
478 		LIST_DEL(&devh->list);
479 		pthread_mutex_unlock(&ctx->open_devs_lock);
480 
481 		usb_remove_pollfd(ctx, libusb20_dev_get_fd(pdev));
482 		libusb_unref_device(devh->dev);
483 		libusb20_dev_close(pdev);
484 		free(devh);
485 
486 		pthread_mutex_lock(&ctx->pollfd_modify_lock);
487 		ctx->pollfd_modify--;
488 		pthread_mutex_unlock(&ctx->pollfd_modify_lock);
489 		return ;
490 	}
491 	libusb_lock_events(ctx);
492 
493 	read(ctx->ctrl_pipe[0], &dummy, sizeof(dummy));
494 	pthread_mutex_lock(&ctx->open_devs_lock);
495 	LIST_DEL(&devh->list);
496 	pthread_mutex_unlock(&ctx->open_devs_lock);
497 
498 	usb_remove_pollfd(ctx, libusb20_dev_get_fd(pdev));
499 	libusb_unref_device(devh->dev);
500 	libusb20_dev_close(pdev);
501 	free(devh);
502 
503 	pthread_mutex_lock(&ctx->pollfd_modify_lock);
504 	ctx->pollfd_modify--;
505 	pthread_mutex_unlock(&ctx->pollfd_modify_lock);
506 
507 	libusb_unlock_events(ctx);
508 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_close leave");
509 }
510 
511 libusb_device *
512 libusb_get_device(libusb_device_handle * devh)
513 {
514 	libusb_context *ctx;
515 
516 	ctx = NULL;
517 	GET_CONTEXT(ctx);
518 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device enter");
519 
520 	if (devh == NULL)
521 		return (NULL);
522 
523 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device leave");
524 	return (devh->dev);
525 }
526 
527 int
528 libusb_get_configuration(libusb_device_handle * devh, int *config)
529 {
530 	libusb_context *ctx;
531 
532 	ctx = NULL;
533 	GET_CONTEXT(ctx);
534 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_configuration enter");
535 
536 	if (devh == NULL || config == NULL)
537 		return (LIBUSB_ERROR_INVALID_PARAM);
538 
539 	*config = libusb20_dev_get_config_index((struct libusb20_device *)
540 	    devh->dev->os_priv);
541 
542 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_configuration leave");
543 	return (0);
544 }
545 
546 /*
547  *	XXX this code is wrong. need update.
548  */
549 
550 int
551 libusb_set_configuration(libusb_device_handle * devh, int configuration)
552 {
553 	struct libusb20_device *pdev;
554 	libusb_context *ctx;
555 
556 	ctx = NULL;
557 	GET_CONTEXT(ctx);
558 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_set_configuration enter");
559 
560 	if (devh == NULL)
561 		return (LIBUSB_ERROR_INVALID_PARAM);
562 
563 	pdev = (struct libusb20_device *)devh->dev->os_priv;
564 
565 	libusb20_dev_set_alt_index(pdev, libusb20_dev_get_config_index(pdev),
566 	    configuration);
567 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_set_configuration leave");
568 	return (0);
569 }
570 
571 int
572 libusb_claim_interface(libusb_device_handle * dev, int interface_number)
573 {
574 	libusb_context *ctx;
575 	int ret = 0;
576 
577 	ctx = NULL;
578 	GET_CONTEXT(ctx);
579 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_claim_interface enter");
580 
581 	if (dev == NULL)
582 		return (LIBUSB_ERROR_INVALID_PARAM);
583 
584 	if (interface_number >= sizeof(dev->claimed_interfaces) * 8)
585 		return (LIBUSB_ERROR_INVALID_PARAM);
586 
587 	pthread_mutex_lock(&(dev->lock));
588 	if (dev->claimed_interfaces & (1 << interface_number))
589 		ret = LIBUSB_ERROR_BUSY;
590 
591 	if (!ret)
592 		dev->claimed_interfaces |= (1 << interface_number);
593 	pthread_mutex_unlock(&(dev->lock));
594 
595 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_claim_interface leave");
596 	return (ret);
597 }
598 
599 int
600 libusb_release_interface(libusb_device_handle * dev, int interface_number)
601 {
602 	libusb_context *ctx;
603 	int ret;
604 
605 	ctx = NULL;
606 	GET_CONTEXT(ctx);
607 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_release_interface enter");
608 
609 	ret = 0;
610 	if (dev == NULL)
611 		return (LIBUSB_ERROR_INVALID_PARAM);
612 
613 	if (interface_number >= sizeof(dev->claimed_interfaces) * 8)
614 		return (LIBUSB_ERROR_INVALID_PARAM);
615 
616 	pthread_mutex_lock(&(dev->lock));
617 	if (!(dev->claimed_interfaces & (1 << interface_number)))
618 		ret = LIBUSB_ERROR_NOT_FOUND;
619 
620 	if (!ret)
621 		dev->claimed_interfaces &= ~(1 << interface_number);
622 	pthread_mutex_unlock(&(dev->lock));
623 
624 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_release_interface leave");
625 	return (ret);
626 }
627 
628 int
629 libusb_set_interface_alt_setting(libusb_device_handle * dev,
630     int interface_number, int alternate_setting)
631 {
632 	libusb_context *ctx;
633 	int ret;
634 
635 	ctx = NULL;
636 	GET_CONTEXT(ctx);
637 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_set_interface_alt_setting enter");
638 
639 	if (dev == NULL)
640 		return (LIBUSB_ERROR_INVALID_PARAM);
641 
642 	if (interface_number >= sizeof(dev->claimed_interfaces) *8)
643 		return (LIBUSB_ERROR_INVALID_PARAM);
644 
645 	pthread_mutex_lock(&dev->lock);
646 	if (!(dev->claimed_interfaces & (1 << interface_number))) {
647 		pthread_mutex_unlock(&dev->lock);
648 		return (LIBUSB_ERROR_NOT_FOUND);
649 	}
650 	pthread_mutex_unlock(&dev->lock);
651 
652 	if (libusb20_dev_set_alt_index(dev->os_priv, interface_number,
653 	    alternate_setting) != 0)
654 		return (LIBUSB_ERROR_OTHER);
655 
656 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_set_interface_alt_setting leave");
657 	return (0);
658 }
659 
660 int
661 libusb_clear_halt(libusb_device_handle * devh, unsigned char endpoint)
662 {
663 	struct libusb20_transfer *xfer;
664 	libusb_context *ctx;
665 	int ret;
666 
667 	ctx = NULL;
668 	GET_CONTEXT(ctx);
669 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_clear_halt enter");
670 
671 	GET_XFER(xfer, endpoint, devh->os_priv);
672 
673 	pthread_mutex_lock(&libusb20_lock);
674 	ret = libusb20_tr_open(xfer, 0, 0, endpoint);
675 	if (ret != 0 && ret != LIBUSB20_ERROR_BUSY) {
676 		pthread_mutex_unlock(&libusb20_lock);
677 		return (LIBUSB_ERROR_OTHER);
678 	}
679 
680 	libusb20_tr_clear_stall_sync(xfer);
681 	if (ret == 0) /* check if we have open the device */
682 		libusb20_tr_close(xfer);
683 	pthread_mutex_unlock(&libusb20_lock);
684 
685 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_clear_halt leave");
686 	return (0);
687 }
688 
689 int
690 libusb_reset_device(libusb_device_handle * dev)
691 {
692 	libusb_context *ctx;
693 
694 	ctx = NULL;
695 	GET_CONTEXT(ctx);
696 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_reset_device enter");
697 
698 	if (dev == NULL)
699 		return (LIBUSB20_ERROR_INVALID_PARAM);
700 
701 	libusb20_dev_reset(dev->os_priv);
702 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_reset_device leave");
703 	return (0);
704 }
705 
706 int
707 libusb_kernel_driver_active(libusb_device_handle * devh, int interface)
708 {
709 	libusb_context *ctx;
710 
711 	ctx = NULL;
712 	GET_CONTEXT(ctx);
713 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_kernel_driver_active enter");
714 
715 	if (devh == NULL)
716 		return (LIBUSB_ERROR_INVALID_PARAM);
717 
718 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_kernel_driver_active leave");
719 	return (libusb20_dev_kernel_driver_active(devh->os_priv, interface));
720 }
721 
722 int
723 libusb_detach_kernel_driver(libusb_device_handle * devh, int interface)
724 {
725 	struct libusb20_device *pdev;
726 	libusb_context *ctx;
727 
728 	ctx = NULL;
729 	GET_CONTEXT(ctx);
730 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_detach_kernel_driver enter");
731 
732 	if (devh == NULL)
733 		return (LIBUSB_ERROR_INVALID_PARAM);
734 
735 	pdev = (struct libusb20_device *)devh->dev->os_priv;
736 	if (libusb20_dev_detach_kernel_driver(pdev, interface) == LIBUSB20_ERROR_OTHER)
737 		return (LIBUSB_ERROR_OTHER);
738 
739 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_detach_kernel_driver leave");
740 	return (0);
741 }
742 
743 /*
744  * stub function.
745  * libusb20 doesn't support this feature.
746  */
747 int
748 libusb_attach_kernel_driver(libusb_device_handle * devh, int interface)
749 {
750 	libusb_context *ctx;
751 
752 	ctx = NULL;
753 	GET_CONTEXT(ctx);
754 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_attach_kernel_driver enter");
755 
756 	if (devh == NULL)
757 		return (LIBUSB_ERROR_INVALID_PARAM);
758 
759 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_attach_kernel_driver leave");
760 	return (0);
761 }
762 
763 /* Asynchronous device I/O */
764 
765 struct libusb_transfer *
766 libusb_alloc_transfer(int iso_packets)
767 {
768 	struct libusb_transfer *xfer;
769 	struct usb_transfer *bxfer;
770 	libusb_context *ctx;
771 	int len;
772 
773 	ctx = NULL;
774 	GET_CONTEXT(ctx);
775 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_alloc_transfer enter");
776 
777 	len = sizeof(struct libusb_transfer) +
778 	    sizeof(struct usb_transfer) +
779 	    (iso_packets * sizeof(libusb_iso_packet_descriptor));
780 
781 	bxfer = malloc(len);
782 	if (bxfer == NULL)
783 		return (NULL);
784 
785 	memset(bxfer, 0, len);
786 	bxfer->num_iso_packets = iso_packets;
787 
788 	xfer = (struct libusb_transfer *) ((uint8_t *)bxfer +
789 	    sizeof(struct usb_transfer));
790 
791 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_alloc_transfer leave");
792 	return (xfer);
793 }
794 
795 void
796 libusb_free_transfer(struct libusb_transfer *xfer)
797 {
798 	struct usb_transfer *bxfer;
799 	libusb_context *ctx;
800 
801 	ctx = NULL;
802 	GET_CONTEXT(ctx);
803 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_free_transfer enter");
804 
805 	if (xfer == NULL)
806 		return ;
807 
808 	bxfer = (struct usb_transfer *) ((uint8_t *)xfer -
809 	    sizeof(struct usb_transfer));
810 
811 	free(bxfer);
812 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_free_transfer leave");
813 	return;
814 }
815 
816 static void
817 libusb10_proxy(struct libusb20_transfer *xfer)
818 {
819 	struct usb_transfer *usb_backend;
820 	struct libusb20_device *pdev;
821 	libusb_transfer *usb_xfer;
822 	libusb_context *ctx;
823 	uint8_t status;
824 	uint32_t iso_packets;
825 	int i;
826 
827 	status = libusb20_tr_get_status(xfer);
828 	usb_xfer = libusb20_tr_get_priv_sc0(xfer);
829 	usb_backend = (struct usb_transfer *) ((uint8_t *)usb_xfer -
830 	    sizeof(struct usb_transfer));
831 	pdev = usb_xfer->dev_handle->dev->os_priv;
832 	ctx = usb_xfer->dev_handle->dev->ctx;
833 	GET_CONTEXT(ctx);
834 
835 	switch (status) {
836 	case LIBUSB20_TRANSFER_COMPLETED:
837 		dprintf(ctx, LIBUSB_DEBUG_TRANSFER, "LIBUSB20 SUBMIT");
838 		usb_xfer->actual_length += libusb20_tr_get_actual_length(xfer);
839 		usb_xfer->callback(usb_xfer);
840 
841 		pthread_mutex_lock(&ctx->flying_transfers_lock);
842 		LIST_DEL(&usb_backend->list);
843 		pthread_mutex_unlock(&ctx->flying_transfers_lock);
844 		break ;
845 	case LIBUSB20_TRANSFER_START:
846 		dprintf(ctx, LIBUSB_DEBUG_TRANSFER, "LIBUSB20 START");
847 		usb_xfer->actual_length = 0;
848 		switch (usb_xfer->type) {
849 			case LIBUSB_TRANSFER_TYPE_CONTROL:
850 				dprintf(ctx, LIBUSB_DEBUG_TRANSFER, "TYPE CTR");
851 				libusb20_tr_setup_control(xfer, usb_xfer->buffer,
852 				    (void *)(((uint8_t *) usb_xfer->buffer) +
853 			            sizeof(libusb_control_setup)),
854 				    usb_xfer->timeout);
855 				break ;
856 			case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
857 				dprintf(ctx, LIBUSB_DEBUG_TRANSFER, "TYPE ISO");
858 				iso_packets = libusb20_tr_get_max_frames(xfer);
859 				if (usb_xfer->num_iso_packets > iso_packets)
860 					usb_xfer->num_iso_packets = iso_packets;
861 				for (i = 0 ; i < usb_xfer->num_iso_packets ; i++) {
862 					libusb20_tr_setup_isoc(xfer,
863 					    usb_xfer->buffer, usb_xfer->length, i);
864 				}
865 				libusb20_tr_set_total_frames(xfer, i);
866 				break ;
867 			case LIBUSB_TRANSFER_TYPE_BULK:
868 				dprintf(ctx, LIBUSB_DEBUG_TRANSFER, "TYPE BULK");
869 				libusb20_tr_setup_bulk(xfer, usb_xfer->buffer,
870 				    usb_xfer->length, usb_xfer->timeout);
871 				break ;
872 			case LIBUSB_TRANSFER_TYPE_INTERRUPT:
873 				dprintf(ctx, LIBUSB_DEBUG_TRANSFER, "TYPE INTR");
874 				libusb20_tr_setup_intr(xfer, usb_xfer->buffer,
875 				    usb_xfer->length, usb_xfer->timeout);
876 				break ;
877 		}
878 		libusb20_tr_submit(xfer);
879 		dprintf(ctx, LIBUSB_DEBUG_TRANSFER, "LIBUSB20 SUBMITED");
880 		break ;
881 	default:
882 		if (ctx->debug == LIBUSB_DEBUG_TRANSFER)
883 			printf("LIBUSB TRANSFER DEFAULT 0x%x\n", status);
884 		usb_xfer->actual_length = 0;
885 		usb_xfer->status = LIBUSB_TRANSFER_CANCELLED;
886 
887 		pthread_mutex_lock(&ctx->flying_transfers_lock);
888 		LIST_DEL(&usb_backend->list);
889 		pthread_mutex_unlock(&ctx->flying_transfers_lock);
890 		usb_xfer->callback(usb_xfer);
891 
892 		break ;
893 	}
894 
895 	switch (status) {
896 	case LIBUSB20_TRANSFER_COMPLETED:
897 		dprintf(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS COMPLETED");
898 		usb_xfer->status = LIBUSB_TRANSFER_COMPLETED;
899 		break ;
900 	case LIBUSB20_TRANSFER_OVERFLOW:
901 		dprintf(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS TR OVERFLOW");
902 		usb_xfer->status = LIBUSB_TRANSFER_OVERFLOW;
903 		break ;
904 	case LIBUSB20_TRANSFER_NO_DEVICE:
905 		dprintf(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS TR NO DEVICE");
906 		usb_xfer->status = LIBUSB_TRANSFER_NO_DEVICE;
907 		break ;
908 	case LIBUSB20_TRANSFER_STALL:
909 		dprintf(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS TR STALL");
910 		usb_xfer->status = LIBUSB_TRANSFER_STALL;
911 		break ;
912 	case LIBUSB20_TRANSFER_CANCELLED:
913 		dprintf(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS TR CANCELLED");
914 		usb_xfer->status = LIBUSB_TRANSFER_CANCELLED;
915 		break ;
916 	case LIBUSB20_TRANSFER_TIMED_OUT:
917 		dprintf(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS TR TIMEOUT");
918 		usb_xfer->status = LIBUSB_TRANSFER_TIMED_OUT;
919 		break ;
920 	case LIBUSB20_TRANSFER_ERROR:
921 		dprintf(ctx, LIBUSB_DEBUG_TRANSFER, "ERROR");
922 		usb_xfer->status = LIBUSB_TRANSFER_ERROR;
923 		break ;
924 	}
925 }
926 
927 static int
928 libusb_get_maxframe(struct libusb20_device *pdev, libusb_transfer *xfer)
929 {
930 	int ret;
931 	int usb_speed;
932 
933 	usb_speed = libusb20_dev_get_speed(pdev);
934 
935 	switch (xfer->type) {
936 	case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
937 		switch (usb_speed) {
938 		case LIBUSB20_SPEED_LOW:
939 		case LIBUSB20_SPEED_FULL:
940 			ret = 60 * 1;
941 			break ;
942 		default :
943 			ret = 60 * 8;
944 			break ;
945 		}
946 		break ;
947 	case LIBUSB_TRANSFER_TYPE_CONTROL:
948 		ret = 2;
949 		break ;
950 	default:
951 		ret = 1;
952 		break ;
953 	}
954 
955 	return ret;
956 }
957 
958 static int
959 libusb_get_buffsize(struct libusb20_device *pdev, libusb_transfer *xfer)
960 {
961 	int ret;
962 	int usb_speed;
963 
964 	usb_speed = libusb20_dev_get_speed(pdev);
965 
966 	switch (xfer->type) {
967 	case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
968 		ret = 0;
969 		break ;
970 	case LIBUSB_TRANSFER_TYPE_CONTROL:
971 		switch (usb_speed) {
972 			case LIBUSB20_SPEED_LOW:
973 				ret = 8;
974 				break ;
975 			case LIBUSB20_SPEED_FULL:
976 				ret = 64;
977 				break ;
978 			case LIBUSB20_SPEED_HIGH:
979 				ret = 64;
980 				break ;
981 		}
982 		/*add */
983 		ret += 8;
984 		break ;
985 	default :
986 		switch (usb_speed) {
987 			case LIBUSB20_SPEED_LOW:
988 				ret = 256;
989 				break ;
990 			case LIBUSB20_SPEED_FULL:
991 				ret = 4096;
992 				break ;
993 			default:
994 				ret = 16384;
995 				break ;
996 		}
997 		break ;
998 	}
999 
1000 	return ret;
1001 }
1002 
1003 int
1004 libusb_submit_transfer(struct libusb_transfer *xfer)
1005 {
1006 	struct libusb20_transfer **usb20_xfer;
1007 	struct usb_transfer *usb_backend;
1008 	struct usb_transfer *usb_node;
1009 	struct libusb20_device *pdev;
1010 	struct libusb_context *ctx;
1011 	struct timespec cur_ts;
1012 	struct timeval *cur_tv;
1013 	int maxframe;
1014 	int buffsize;
1015 	int num_frame;
1016 	int ep_idx;
1017 	int ret;
1018 	int i;
1019 
1020 	if (xfer == NULL)
1021 		return (LIBUSB_ERROR_NO_MEM);
1022 
1023 	usb20_xfer = malloc(2 * sizeof(struct libusb20_transfer *));
1024 	if (usb20_xfer == NULL)
1025 		return (LIBUSB_ERROR_NO_MEM);
1026 
1027 	ctx = xfer->dev_handle->dev->ctx;
1028 	pdev = xfer->dev_handle->os_priv;
1029 
1030 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_submit_transfer enter");
1031 
1032 	usb_backend = (struct usb_transfer *) ((uint8_t *)xfer -
1033 	    sizeof(struct usb_transfer));
1034 	usb_backend->transferred = 0;
1035 	usb_backend->flags = 0;
1036 
1037 	if (xfer->timeout != 0) {
1038 		clock_gettime(CLOCK_MONOTONIC, &cur_ts);
1039 		cur_ts.tv_sec += xfer->timeout / 1000;
1040 		cur_ts.tv_nsec += (xfer->timeout % 1000) * 1000000;
1041 
1042 		if (cur_ts.tv_nsec > 1000000000) {
1043 			cur_ts.tv_nsec -= 1000000000;
1044 			cur_ts.tv_sec++;
1045 		}
1046 
1047 		TIMESPEC_TO_TIMEVAL(&usb_backend->timeout, &cur_ts);
1048 	}
1049 
1050 	/*Add to flying list*/
1051 	pthread_mutex_lock(&ctx->flying_transfers_lock);
1052 	if (USB_LIST_EMPTY(&ctx->flying_transfers)) {
1053 		LIST_ADD(&usb_backend->list, &ctx->flying_transfers);
1054 		goto out;
1055 	}
1056 	if (timerisset(&usb_backend->timeout) == 0) {
1057 		LIST_ADD_TAIL(&usb_backend->list, &ctx->flying_transfers);
1058 		goto out;
1059 	}
1060 	LIST_FOREACH_ENTRY(usb_node, &ctx->flying_transfers, list) {
1061 		cur_tv = &usb_node->timeout;
1062 		if (timerisset(cur_tv) == 0 ||
1063 		    (cur_tv->tv_sec > usb_backend->timeout.tv_sec) ||
1064 		    (cur_tv->tv_sec == usb_backend->timeout.tv_sec &&
1065 		    cur_tv->tv_usec > usb_backend->timeout.tv_usec)) {
1066 			LIST_ADD_TAIL(&usb_backend->list, &usb_node->list);
1067 			goto out;
1068 		}
1069 	}
1070 	LIST_ADD_TAIL(&usb_backend->list, &ctx->flying_transfers);
1071 
1072 out:
1073 	pthread_mutex_unlock(&ctx->flying_transfers_lock);
1074 
1075 	usb20_xfer[0] = libusb20_tr_get_pointer(pdev,
1076 	    ((xfer->endpoint / 0x40) | (xfer->endpoint * 4)) % (16 * 4));
1077 	usb20_xfer[1] = libusb20_tr_get_pointer(pdev,
1078 	    (((xfer->endpoint / 0x40) | (xfer->endpoint * 4)) % (16 * 4)) + 1);
1079 
1080 	if (usb20_xfer[0] == NULL)
1081 		return (LIBUSB_ERROR_OTHER);
1082 
1083 	xfer->os_priv = usb20_xfer;
1084 
1085 	pthread_mutex_lock(&libusb20_lock);
1086 
1087 	buffsize = libusb_get_buffsize(pdev, xfer);
1088 	maxframe = libusb_get_maxframe(pdev, xfer);
1089 
1090 	ret = libusb20_tr_open(usb20_xfer[0], buffsize,
1091 	    maxframe, xfer->endpoint);
1092 	if (xfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS)
1093 		ret |= libusb20_tr_open(usb20_xfer[1], buffsize,
1094 		    maxframe, xfer->endpoint);
1095 
1096 	if (ret != 0) {
1097 		pthread_mutex_unlock(&libusb20_lock);
1098 		pthread_mutex_lock(&ctx->flying_transfers_lock);
1099 		LIST_DEL(&usb_backend->list);
1100 		pthread_mutex_unlock(&ctx->flying_transfers_lock);
1101 		return (LIBUSB_ERROR_OTHER);
1102 	}
1103 
1104 	libusb20_tr_set_priv_sc0(usb20_xfer[0], xfer);
1105 	libusb20_tr_set_callback(usb20_xfer[0], libusb10_proxy);
1106 	if (xfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) {
1107 		libusb20_tr_set_priv_sc0(usb20_xfer[1], xfer);
1108 		libusb20_tr_set_callback(usb20_xfer[1], libusb10_proxy);
1109 	}
1110 
1111 	libusb20_tr_start(usb20_xfer[0]);
1112 	if (xfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS)
1113 		libusb20_tr_start(usb20_xfer[1]);
1114 
1115 	pthread_mutex_unlock(&libusb20_lock);
1116 
1117 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_submit_transfer leave");
1118 	return (0);
1119 }
1120 
1121 int
1122 libusb_cancel_transfer(struct libusb_transfer *xfer)
1123 {
1124 	libusb_context *ctx;
1125 
1126 	ctx = NULL;
1127 	GET_CONTEXT(ctx);
1128 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_cancel_transfer enter");
1129 
1130 	if (xfer == NULL)
1131 		return (LIBUSB_ERROR_NO_MEM);
1132 
1133 	pthread_mutex_lock(&libusb20_lock);
1134 	libusb20_tr_stop(xfer->os_priv);
1135 	pthread_mutex_unlock(&libusb20_lock);
1136 
1137 	dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_cancel_transfer leave");
1138 	return (0);
1139 }
1140 
1141