xref: /freebsd/lib/libusb/libusb10.c (revision 5861f9665471e98e544f6fa3ce73c4912229ff82)
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 	TAILQ_INIT(&ctx->usb_devs);
79 	TAILQ_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 	TAILQ_INIT(&ctx->flying_transfers);
89 	TAILQ_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 			while (i != 0) {
182 				libusb_unref_device((*list)[i - 1]);
183 				i--;
184 			}
185 			free(*list);
186 			libusb20_be_free(usb_backend);
187 			return (LIBUSB_ERROR_NO_MEM);
188 		}
189 		memset(dev, 0, sizeof(*dev));
190 
191 		pthread_mutex_init(&dev->lock, NULL);
192 		dev->ctx = ctx;
193 		dev->bus_number = pdev->bus_number;
194 		dev->device_address = pdev->device_address;
195 		dev->num_configurations = ddesc->bNumConfigurations;
196 
197 		/* link together the two structures */
198 		dev->os_priv = pdev;
199 
200 		pthread_mutex_lock(&ctx->usb_devs_lock);
201 		TAILQ_INSERT_HEAD(&ctx->usb_devs, dev, list);
202 		pthread_mutex_unlock(&ctx->usb_devs_lock);
203 
204 		(*list)[i] = libusb_ref_device(dev);
205 		i++;
206 	}
207 	(*list)[i] = NULL;
208 
209 	libusb20_be_free(usb_backend);
210 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device_list leave");
211 	return (i);
212 }
213 
214 /*
215  * In this function we cant free all the device contained into list because
216  * open_with_pid_vid use some node of list after the free_device_list.
217  */
218 void
219 libusb_free_device_list(libusb_device **list, int unref_devices)
220 {
221 	int i;
222 	libusb_context *ctx;
223 
224 	ctx = NULL;
225 	GET_CONTEXT(ctx);
226 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_free_device_list enter");
227 
228 	if (list == NULL)
229 		return ;
230 
231 	if (unref_devices) {
232 		for (i = 0; list[i] != NULL; i++)
233 			libusb_unref_device(list[i]);
234 	}
235 	free(list);
236 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_free_device_list leave");
237 }
238 
239 uint8_t
240 libusb_get_bus_number(libusb_device * dev)
241 {
242 	libusb_context *ctx;
243 
244 	ctx = NULL;
245 	GET_CONTEXT(ctx);
246 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_bus_number enter");
247 
248 	if (dev == NULL)
249 		return (LIBUSB_ERROR_NO_DEVICE);
250 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_bus_number leave");
251 	return (dev->bus_number);
252 }
253 
254 uint8_t
255 libusb_get_device_address(libusb_device * dev)
256 {
257 	libusb_context *ctx;
258 
259 	ctx = NULL;
260 	GET_CONTEXT(ctx);
261 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device_address enter");
262 
263 	if (dev == NULL)
264 		return (LIBUSB_ERROR_NO_DEVICE);
265 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device_address leave");
266 	return (dev->device_address);
267 }
268 
269 int
270 libusb_get_max_packet_size(libusb_device *dev, unsigned char endpoint)
271 {
272 	struct libusb_config_descriptor *pdconf;
273 	struct libusb_interface *pinf;
274 	struct libusb_interface_descriptor *pdinf;
275 	struct libusb_endpoint_descriptor *pdend;
276 	libusb_context *ctx;
277 	int i, j, k, ret;
278 
279 	ctx = NULL;
280 	GET_CONTEXT(ctx);
281 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_max_packet_size enter");
282 
283 	if (dev == NULL)
284 		return (LIBUSB_ERROR_NO_DEVICE);
285 
286 	if (libusb_get_active_config_descriptor(dev, &pdconf) < 0)
287 		return (LIBUSB_ERROR_OTHER);
288 
289 	ret = LIBUSB_ERROR_NOT_FOUND;
290 	for (i = 0 ; i < pdconf->bNumInterfaces ; i++) {
291 		pinf = &pdconf->interface[i];
292 		for (j = 0 ; j < pinf->num_altsetting ; j++) {
293 			pdinf = &pinf->altsetting[j];
294 			for (k = 0 ; k < pdinf->bNumEndpoints ; k++) {
295 				pdend = &pdinf->endpoint[k];
296 				if (pdend->bEndpointAddress == endpoint) {
297 					ret = pdend->wMaxPacketSize;
298 					goto out;
299 				}
300 			}
301 		}
302 	}
303 
304 out:
305 	libusb_free_config_descriptor(pdconf);
306 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_max_packet_size leave");
307 	return (ret);
308 }
309 
310 libusb_device *
311 libusb_ref_device(libusb_device * dev)
312 {
313 	libusb_context *ctx;
314 
315 	ctx = NULL;
316 	GET_CONTEXT(ctx);
317 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_ref_device enter");
318 
319 	if (dev == NULL)
320 		return (NULL);
321 
322 	pthread_mutex_lock(&dev->lock);
323 	dev->refcnt++;
324 	pthread_mutex_unlock(&dev->lock);
325 
326 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_ref_device leave");
327 	return (dev);
328 }
329 
330 void
331 libusb_unref_device(libusb_device * dev)
332 {
333 	libusb_context *ctx;
334 
335 	ctx = NULL;
336 	GET_CONTEXT(ctx);
337 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_unref_device enter");
338 
339 	if (dev == NULL)
340 		return;
341 
342 	pthread_mutex_lock(&dev->lock);
343 	dev->refcnt--;
344 	pthread_mutex_unlock(&dev->lock);
345 
346 	if (dev->refcnt == 0) {
347 		pthread_mutex_lock(&dev->ctx->usb_devs_lock);
348 		TAILQ_REMOVE(&ctx->usb_devs, dev, list);
349 		pthread_mutex_unlock(&dev->ctx->usb_devs_lock);
350 
351 		libusb20_dev_free(dev->os_priv);
352 		free(dev);
353 	}
354 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_unref_device leave");
355 }
356 
357 int
358 libusb_open(libusb_device * dev, libusb_device_handle **devh)
359 {
360 	libusb_context *ctx = dev->ctx;
361 	struct libusb20_device *pdev = dev->os_priv;
362 	libusb_device_handle *hdl;
363 	unsigned char dummy;
364 	int err;
365 
366 	GET_CONTEXT(ctx);
367 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open enter");
368 
369 	dummy = 1;
370 	if (devh == NULL)
371 		return (LIBUSB_ERROR_INVALID_PARAM);
372 
373 	hdl = malloc(sizeof(*hdl));
374 	if (hdl == NULL)
375 		return (LIBUSB_ERROR_NO_MEM);
376 
377 	err = libusb20_dev_open(pdev, 16 * 4 /* number of endpoints */ );
378 	if (err) {
379 		free(hdl);
380 		return (LIBUSB_ERROR_NO_MEM);
381 	}
382 	memset(hdl, 0, sizeof(*hdl));
383 	pthread_mutex_init(&hdl->lock, NULL);
384 
385 	TAILQ_INIT(&hdl->ep_list);
386 	hdl->dev = libusb_ref_device(dev);
387 	hdl->claimed_interfaces = 0;
388 	hdl->os_priv = dev->os_priv;
389 	err = usb_add_pollfd(ctx, libusb20_dev_get_fd(pdev), POLLIN |
390 	    POLLOUT | POLLRDNORM | POLLWRNORM);
391 	if (err < 0) {
392 		libusb_unref_device(dev);
393 		free(hdl);
394 		return (err);
395 	}
396 
397 	pthread_mutex_lock(&ctx->open_devs_lock);
398 	TAILQ_INSERT_HEAD(&ctx->open_devs, hdl, list);
399 	pthread_mutex_unlock(&ctx->open_devs_lock);
400 
401 	*devh = hdl;
402 
403 	pthread_mutex_lock(&ctx->pollfd_modify_lock);
404 	ctx->pollfd_modify++;
405 	pthread_mutex_unlock(&ctx->pollfd_modify_lock);
406 
407 	err = write(ctx->ctrl_pipe[1], &dummy, sizeof(dummy));
408 	if (err <= 0) {
409 		pthread_mutex_lock(&ctx->pollfd_modify_lock);
410 		ctx->pollfd_modify--;
411 		pthread_mutex_unlock(&ctx->pollfd_modify_lock);
412 		return 0;
413 	}
414 
415 	libusb_lock_events(ctx);
416 	read(ctx->ctrl_pipe[0], &dummy, sizeof(dummy));
417 	pthread_mutex_lock(&ctx->pollfd_modify_lock);
418 	ctx->pollfd_modify--;
419 	pthread_mutex_unlock(&ctx->pollfd_modify_lock);
420 	libusb_unlock_events(ctx);
421 
422 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open leave");
423 	return (0);
424 }
425 
426 libusb_device_handle *
427 libusb_open_device_with_vid_pid(libusb_context * ctx, uint16_t vendor_id,
428     uint16_t product_id)
429 {
430 	struct libusb_device **devs;
431 	struct libusb_device_handle *devh;
432 	struct libusb20_device *pdev;
433 	struct LIBUSB20_DEVICE_DESC_DECODED *pdesc;
434 	int i, j;
435 
436 	GET_CONTEXT(ctx);
437 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open_device_width_vid_pid enter");
438 
439 	devh = NULL;
440 
441 	if ((i = libusb_get_device_list(ctx, &devs)) < 0)
442 		return (NULL);
443 
444 	for (j = 0; j < i; j++) {
445 		pdev = (struct libusb20_device *)devs[j]->os_priv;
446 		pdesc = libusb20_dev_get_device_desc(pdev);
447 		if (pdesc->idVendor == vendor_id &&
448 		    pdesc->idProduct == product_id) {
449 			if (libusb_open(devs[j], &devh) < 0)
450 				devh = NULL;
451 			break ;
452 		}
453 	}
454 
455 	libusb_free_device_list(devs, 1);
456 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open_device_width_vid_pid leave");
457 	return (devh);
458 }
459 
460 void
461 libusb_close(libusb_device_handle * devh)
462 {
463 	libusb_context *ctx;
464 	struct libusb20_device *pdev;
465 	struct usb_ep_tr *eptr;
466 	unsigned char dummy = 1;
467 	int err;
468 
469 	if (devh == NULL)
470 		return ;
471 
472 	ctx = devh->dev->ctx;
473 	pdev = devh->os_priv;
474 
475 	GET_CONTEXT(ctx);
476 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_close enter");
477 
478 	pthread_mutex_lock(&ctx->pollfd_modify_lock);
479 	ctx->pollfd_modify++;
480 	pthread_mutex_unlock(&ctx->pollfd_modify_lock);
481 
482 	err = write(ctx->ctrl_pipe[1], &dummy, sizeof(dummy));
483 
484 	if (err <= 0) {
485 		pthread_mutex_lock(&ctx->open_devs_lock);
486 		TAILQ_REMOVE(&ctx->open_devs, devh, list);
487 		pthread_mutex_unlock(&ctx->open_devs_lock);
488 
489 		usb_remove_pollfd(ctx, libusb20_dev_get_fd(pdev));
490 		libusb20_dev_close(pdev);
491 		libusb_unref_device(devh->dev);
492 		TAILQ_FOREACH(eptr, &devh->ep_list, list) {
493 			TAILQ_REMOVE(&devh->ep_list, eptr, list);
494 			libusb20_tr_close(((struct libusb20_transfer **)
495 			    eptr->os_priv)[0]);
496 			if (eptr->flags)
497 				libusb20_tr_close(((struct libusb20_transfer **)
498 			            eptr->os_priv)[1]);
499 			free((struct libusb20_transfer **)eptr->os_priv);
500 		}
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 		return ;
507 	}
508 	libusb_lock_events(ctx);
509 
510 	read(ctx->ctrl_pipe[0], &dummy, sizeof(dummy));
511 	pthread_mutex_lock(&ctx->open_devs_lock);
512 	TAILQ_REMOVE(&ctx->open_devs, devh, list);
513 	pthread_mutex_unlock(&ctx->open_devs_lock);
514 
515 	usb_remove_pollfd(ctx, libusb20_dev_get_fd(pdev));
516 	libusb20_dev_close(pdev);
517 	libusb_unref_device(devh->dev);
518 	TAILQ_FOREACH(eptr, &devh->ep_list, list) {
519 		TAILQ_REMOVE(&devh->ep_list, eptr, list);
520 		libusb20_tr_close(((struct libusb20_transfer **)
521 		    eptr->os_priv)[0]);
522 		if (eptr->flags)
523 			libusb20_tr_close(((struct libusb20_transfer **)
524 			    eptr->os_priv)[1]);
525 		free((struct libusb20_transfer **)eptr->os_priv);
526 	}
527 	free(devh);
528 
529 	pthread_mutex_lock(&ctx->pollfd_modify_lock);
530 	ctx->pollfd_modify--;
531 	pthread_mutex_unlock(&ctx->pollfd_modify_lock);
532 
533 	libusb_unlock_events(ctx);
534 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_close leave");
535 }
536 
537 libusb_device *
538 libusb_get_device(libusb_device_handle * devh)
539 {
540 	libusb_context *ctx;
541 
542 	ctx = NULL;
543 	GET_CONTEXT(ctx);
544 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device enter");
545 
546 	if (devh == NULL)
547 		return (NULL);
548 
549 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device leave");
550 	return (devh->dev);
551 }
552 
553 int
554 libusb_get_configuration(libusb_device_handle * devh, int *config)
555 {
556 	libusb_context *ctx;
557 
558 	ctx = NULL;
559 	GET_CONTEXT(ctx);
560 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_configuration enter");
561 
562 	if (devh == NULL || config == NULL)
563 		return (LIBUSB_ERROR_INVALID_PARAM);
564 
565 	*config = libusb20_dev_get_config_index((struct libusb20_device *)
566 	    devh->dev->os_priv);
567 
568 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_configuration leave");
569 	return (0);
570 }
571 
572 int
573 libusb_set_configuration(libusb_device_handle * devh, int configuration)
574 {
575 	struct libusb20_device *pdev;
576 	libusb_context *ctx;
577 
578 	ctx = NULL;
579 	GET_CONTEXT(ctx);
580 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_set_configuration enter");
581 
582 	if (devh == NULL)
583 		return (LIBUSB_ERROR_INVALID_PARAM);
584 
585 	pdev = (struct libusb20_device *)devh->dev->os_priv;
586 
587 	libusb20_dev_set_config_index(pdev, configuration);
588 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_set_configuration leave");
589 	return (0);
590 }
591 
592 int
593 libusb_claim_interface(libusb_device_handle * dev, int interface_number)
594 {
595 	libusb_context *ctx;
596 	int ret = 0;
597 
598 	ctx = NULL;
599 	GET_CONTEXT(ctx);
600 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_claim_interface enter");
601 
602 	if (dev == NULL)
603 		return (LIBUSB_ERROR_INVALID_PARAM);
604 
605 	if (interface_number >= sizeof(dev->claimed_interfaces) * 8)
606 		return (LIBUSB_ERROR_INVALID_PARAM);
607 
608 	pthread_mutex_lock(&(dev->lock));
609 	if (dev->claimed_interfaces & (1 << interface_number))
610 		ret = LIBUSB_ERROR_BUSY;
611 
612 	if (!ret)
613 		dev->claimed_interfaces |= (1 << interface_number);
614 	pthread_mutex_unlock(&(dev->lock));
615 
616 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_claim_interface leave");
617 	return (ret);
618 }
619 
620 int
621 libusb_release_interface(libusb_device_handle * dev, int interface_number)
622 {
623 	libusb_context *ctx;
624 	int ret;
625 
626 	ctx = NULL;
627 	GET_CONTEXT(ctx);
628 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_release_interface enter");
629 
630 	ret = 0;
631 	if (dev == NULL)
632 		return (LIBUSB_ERROR_INVALID_PARAM);
633 
634 	if (interface_number >= sizeof(dev->claimed_interfaces) * 8)
635 		return (LIBUSB_ERROR_INVALID_PARAM);
636 
637 	pthread_mutex_lock(&(dev->lock));
638 	if (!(dev->claimed_interfaces & (1 << interface_number)))
639 		ret = LIBUSB_ERROR_NOT_FOUND;
640 
641 	if (!ret)
642 		dev->claimed_interfaces &= ~(1 << interface_number);
643 	pthread_mutex_unlock(&(dev->lock));
644 
645 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_release_interface leave");
646 	return (ret);
647 }
648 
649 int
650 libusb_set_interface_alt_setting(libusb_device_handle * dev,
651     int interface_number, int alternate_setting)
652 {
653 	libusb_context *ctx;
654 
655 	ctx = NULL;
656 	GET_CONTEXT(ctx);
657 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_set_interface_alt_setting enter");
658 
659 	if (dev == NULL)
660 		return (LIBUSB_ERROR_INVALID_PARAM);
661 
662 	if (interface_number >= sizeof(dev->claimed_interfaces) *8)
663 		return (LIBUSB_ERROR_INVALID_PARAM);
664 
665 	pthread_mutex_lock(&dev->lock);
666 	if (!(dev->claimed_interfaces & (1 << interface_number))) {
667 		pthread_mutex_unlock(&dev->lock);
668 		return (LIBUSB_ERROR_NOT_FOUND);
669 	}
670 	pthread_mutex_unlock(&dev->lock);
671 
672 	if (libusb20_dev_set_alt_index(dev->os_priv, interface_number,
673 	    alternate_setting) != 0)
674 		return (LIBUSB_ERROR_OTHER);
675 
676 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_set_interface_alt_setting leave");
677 	return (0);
678 }
679 
680 int
681 libusb_clear_halt(libusb_device_handle * devh, unsigned char endpoint)
682 {
683 	struct libusb20_transfer *xfer;
684 	struct libusb20_device *pdev;
685 	libusb_context *ctx;
686 	int ret;
687 
688 	ctx = NULL;
689 	GET_CONTEXT(ctx);
690 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_clear_halt enter");
691 
692 	pdev = devh->os_priv;
693 	xfer = libusb20_tr_get_pointer(pdev,
694 	    ((endpoint / 0x40) | (endpoint * 4)) % (16 * 4));
695 	if (xfer == NULL)
696 		return (LIBUSB_ERROR_NO_MEM);
697 
698 	pthread_mutex_lock(&libusb20_lock);
699 	ret = libusb20_tr_open(xfer, 0, 0, endpoint);
700 	if (ret != 0 && ret != LIBUSB20_ERROR_BUSY) {
701 		pthread_mutex_unlock(&libusb20_lock);
702 		return (LIBUSB_ERROR_OTHER);
703 	}
704 
705 	libusb20_tr_clear_stall_sync(xfer);
706 	if (ret == 0) /* check if we have open the device */
707 		libusb20_tr_close(xfer);
708 	pthread_mutex_unlock(&libusb20_lock);
709 
710 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_clear_halt leave");
711 	return (0);
712 }
713 
714 int
715 libusb_reset_device(libusb_device_handle * dev)
716 {
717 	libusb_context *ctx;
718 
719 	ctx = NULL;
720 	GET_CONTEXT(ctx);
721 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_reset_device enter");
722 
723 	if (dev == NULL)
724 		return (LIBUSB20_ERROR_INVALID_PARAM);
725 
726 	libusb20_dev_reset(dev->os_priv);
727 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_reset_device leave");
728 	return (0);
729 }
730 
731 int
732 libusb_kernel_driver_active(libusb_device_handle * devh, int interface)
733 {
734 	libusb_context *ctx;
735 
736 	ctx = NULL;
737 	GET_CONTEXT(ctx);
738 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_kernel_driver_active enter");
739 
740 	if (devh == NULL)
741 		return (LIBUSB_ERROR_INVALID_PARAM);
742 
743 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_kernel_driver_active leave");
744 	return (libusb20_dev_kernel_driver_active(devh->os_priv, interface));
745 }
746 
747 int
748 libusb_detach_kernel_driver(libusb_device_handle * devh, int interface)
749 {
750 	struct libusb20_device *pdev;
751 	libusb_context *ctx;
752 
753 	ctx = NULL;
754 	GET_CONTEXT(ctx);
755 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_detach_kernel_driver enter");
756 
757 	if (devh == NULL)
758 		return (LIBUSB_ERROR_INVALID_PARAM);
759 
760 	pdev = (struct libusb20_device *)devh->dev->os_priv;
761 	if (libusb20_dev_detach_kernel_driver(pdev, interface) == LIBUSB20_ERROR_OTHER)
762 		return (LIBUSB_ERROR_OTHER);
763 
764 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_detach_kernel_driver leave");
765 	return (0);
766 }
767 
768 /*
769  * stub function.
770  * libusb20 doesn't support this feature.
771  */
772 int
773 libusb_attach_kernel_driver(libusb_device_handle * devh, int interface)
774 {
775 	libusb_context *ctx;
776 
777 	ctx = NULL;
778 	GET_CONTEXT(ctx);
779 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_attach_kernel_driver enter");
780 
781 	if (devh == NULL)
782 		return (LIBUSB_ERROR_INVALID_PARAM);
783 
784 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_attach_kernel_driver leave");
785 	return (0);
786 }
787 
788 /* Asynchronous device I/O */
789 
790 struct libusb_transfer *
791 libusb_alloc_transfer(int iso_packets)
792 {
793 	struct libusb_transfer *xfer;
794 	struct usb_transfer *bxfer;
795 	libusb_context *ctx;
796 	int len;
797 
798 	ctx = NULL;
799 	GET_CONTEXT(ctx);
800 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_alloc_transfer enter");
801 
802 	len = sizeof(struct libusb_transfer) +
803 	    sizeof(struct usb_transfer) +
804 	    (iso_packets * sizeof(libusb_iso_packet_descriptor));
805 
806 	bxfer = malloc(len);
807 	if (bxfer == NULL)
808 		return (NULL);
809 
810 	memset(bxfer, 0, len);
811 	bxfer->num_iso_packets = iso_packets;
812 
813 	xfer = (struct libusb_transfer *) ((uint8_t *)bxfer +
814 	    sizeof(struct usb_transfer));
815 
816 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_alloc_transfer leave");
817 	return (xfer);
818 }
819 
820 void
821 libusb_free_transfer(struct libusb_transfer *xfer)
822 {
823 	struct usb_transfer *bxfer;
824 	libusb_context *ctx;
825 
826 	ctx = NULL;
827 	GET_CONTEXT(ctx);
828 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_free_transfer enter");
829 
830 	if (xfer == NULL)
831 		return ;
832 
833 	bxfer = (struct usb_transfer *) ((uint8_t *)xfer -
834 	    sizeof(struct usb_transfer));
835 
836 	free(bxfer);
837 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_free_transfer leave");
838 	return;
839 }
840 
841 static int
842 libusb_get_maxframe(struct libusb20_device *pdev, libusb_transfer *xfer)
843 {
844 	int ret;
845 	int usb_speed;
846 
847 	usb_speed = libusb20_dev_get_speed(pdev);
848 
849 	switch (xfer->type) {
850 	case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
851 		switch (usb_speed) {
852 		case LIBUSB20_SPEED_LOW:
853 		case LIBUSB20_SPEED_FULL:
854 			ret = 60 * 1;
855 			break ;
856 		default :
857 			ret = 60 * 8;
858 			break ;
859 		}
860 		break ;
861 	case LIBUSB_TRANSFER_TYPE_CONTROL:
862 		ret = 2;
863 		break ;
864 	default:
865 		ret = 1;
866 		break ;
867 	}
868 
869 	return ret;
870 }
871 
872 static int
873 libusb_get_buffsize(struct libusb20_device *pdev, libusb_transfer *xfer)
874 {
875 	int ret;
876 	int usb_speed;
877 
878 	usb_speed = libusb20_dev_get_speed(pdev);
879 
880 	switch (xfer->type) {
881 	case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
882 		ret = 0;
883 		break ;
884 	case LIBUSB_TRANSFER_TYPE_CONTROL:
885 		switch (usb_speed) {
886 			case LIBUSB20_SPEED_LOW:
887 				ret = 8;
888 				break ;
889 			case LIBUSB20_SPEED_FULL:
890 				ret = 64;
891 				break ;
892 			default:
893 				ret = 64;
894 				break ;
895 		}
896 		ret += 8;
897 		break ;
898 	default :
899 		switch (usb_speed) {
900 			case LIBUSB20_SPEED_LOW:
901 				ret = 256;
902 				break ;
903 			case LIBUSB20_SPEED_FULL:
904 				ret = 4096;
905 				break ;
906 			default:
907 				ret = 16384;
908 				break ;
909 		}
910 		break ;
911 	}
912 
913 	return ret;
914 }
915 
916 static void
917 libusb10_proxy(struct libusb20_transfer *xfer)
918 {
919 	struct usb_transfer *usb_backend;
920 	struct libusb20_device *pdev;
921 	libusb_transfer *usb_xfer;
922 	libusb_context *ctx;
923 	uint32_t pos;
924 	uint32_t max;
925 	uint32_t size;
926 	uint8_t status;
927 	uint32_t iso_packets;
928 	int i;
929 
930 	status = libusb20_tr_get_status(xfer);
931 	usb_xfer = libusb20_tr_get_priv_sc0(xfer);
932 	usb_backend = (struct usb_transfer *) ((uint8_t *)usb_xfer -
933 	    sizeof(struct usb_transfer));
934 	pdev = usb_xfer->dev_handle->dev->os_priv;
935 	ctx = usb_xfer->dev_handle->dev->ctx;
936 	GET_CONTEXT(ctx);
937 
938 	switch (status) {
939 	case LIBUSB20_TRANSFER_COMPLETED:
940 		usb_backend->transferred += libusb20_tr_get_actual_length(xfer);
941 		DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "LIBUSB20 TRANSFER %i bytes",
942 		    usb_backend->transferred);
943 		if (usb_backend->transferred != usb_xfer->length)
944 			goto tr_start;
945 
946 		DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "LIBUSB20 TRANSFER COMPLETE");
947 		usb_handle_transfer_completion(usb_backend, LIBUSB_TRANSFER_COMPLETED);
948 
949 		break ;
950 	case LIBUSB20_TRANSFER_START:
951 tr_start:
952 		DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "LIBUSB20 START");
953 		max = libusb_get_buffsize(pdev, usb_xfer);
954 		pos = usb_backend->transferred;
955 		size = (usb_xfer->length - pos);
956 		size = (size > max) ? max : size;
957 		usb_xfer->actual_length = 0;
958 		switch (usb_xfer->type) {
959 			case LIBUSB_TRANSFER_TYPE_CONTROL:
960 				DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "TYPE CTR");
961 				libusb20_tr_setup_control(xfer, usb_xfer->buffer,
962 				    (void *)(((uint8_t *) &usb_xfer->buffer[pos]) +
963 			            sizeof(libusb_control_setup)),
964 				    usb_xfer->timeout);
965 				break ;
966 			case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
967 				DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "TYPE ISO");
968 				iso_packets = libusb20_tr_get_max_frames(xfer);
969 				if (usb_xfer->num_iso_packets > iso_packets)
970 					usb_xfer->num_iso_packets = iso_packets;
971 				for (i = 0 ; i < usb_xfer->num_iso_packets ; i++) {
972 					libusb20_tr_setup_isoc(xfer,
973 					    &usb_xfer->buffer[pos], size, i);
974 				}
975 				libusb20_tr_set_total_frames(xfer, i);
976 				break ;
977 			case LIBUSB_TRANSFER_TYPE_BULK:
978 				DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "TYPE BULK");
979 				libusb20_tr_setup_bulk(xfer, &usb_xfer->buffer[pos],
980 				    size, usb_xfer->timeout);
981 				break ;
982 			case LIBUSB_TRANSFER_TYPE_INTERRUPT:
983 				DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "TYPE INTR");
984 				libusb20_tr_setup_intr(xfer, &usb_xfer->buffer[pos],
985 				    size, usb_xfer->timeout);
986 				break ;
987 		}
988 		libusb20_tr_submit(xfer);
989 		DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "LIBUSB20 SUBMITED");
990 		break ;
991 	default:
992 		DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "TRANSFER DEFAULT 0x%x\n",
993 		    status);
994 		usb_backend->transferred = 0;
995 		usb_handle_transfer_completion(usb_backend, LIBUSB_TRANSFER_CANCELLED);
996 		break ;
997 	}
998 
999 	switch (status) {
1000 	case LIBUSB20_TRANSFER_COMPLETED:
1001 		DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS COMPLETED");
1002 		usb_xfer->status = LIBUSB_TRANSFER_COMPLETED;
1003 		break ;
1004 	case LIBUSB20_TRANSFER_OVERFLOW:
1005 		DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS TR OVERFLOW");
1006 		usb_xfer->status = LIBUSB_TRANSFER_OVERFLOW;
1007 		break ;
1008 	case LIBUSB20_TRANSFER_NO_DEVICE:
1009 		DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS TR NO DEVICE");
1010 		usb_xfer->status = LIBUSB_TRANSFER_NO_DEVICE;
1011 		break ;
1012 	case LIBUSB20_TRANSFER_STALL:
1013 		DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS TR STALL");
1014 		usb_xfer->status = LIBUSB_TRANSFER_STALL;
1015 		break ;
1016 	case LIBUSB20_TRANSFER_CANCELLED:
1017 		DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS TR CANCELLED");
1018 		usb_xfer->status = LIBUSB_TRANSFER_CANCELLED;
1019 		break ;
1020 	case LIBUSB20_TRANSFER_TIMED_OUT:
1021 		DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS TR TIMEOUT");
1022 		usb_xfer->status = LIBUSB_TRANSFER_TIMED_OUT;
1023 		break ;
1024 	case LIBUSB20_TRANSFER_ERROR:
1025 		DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "ERROR");
1026 		usb_xfer->status = LIBUSB_TRANSFER_ERROR;
1027 		break ;
1028 	}
1029 }
1030 
1031 int
1032 libusb_submit_transfer(struct libusb_transfer *xfer)
1033 {
1034 	struct libusb20_transfer **usb20_xfer;
1035 	struct usb_transfer *usb_backend;
1036 	struct usb_transfer *usb_node;
1037 	struct libusb20_device *pdev;
1038 	struct usb_ep_tr *eptr;
1039 	struct timespec cur_ts;
1040 	struct timeval *cur_tv;
1041 	libusb_device_handle *devh;
1042 	libusb_context *ctx;
1043 	int maxframe;
1044 	int buffsize;
1045 	int ep_idx;
1046 	int ret;
1047 
1048 	if (xfer == NULL)
1049 		return (LIBUSB_ERROR_NO_MEM);
1050 
1051 	usb20_xfer = malloc(2 * sizeof(struct libusb20_transfer *));
1052 	if (usb20_xfer == NULL)
1053 		return (LIBUSB_ERROR_NO_MEM);
1054 
1055 	ctx = xfer->dev_handle->dev->ctx;
1056 	pdev = xfer->dev_handle->os_priv;
1057 	devh = xfer->dev_handle;
1058 
1059 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_submit_transfer enter");
1060 
1061 	usb_backend = (struct usb_transfer *) ((uint8_t *)xfer -
1062 	    sizeof(struct usb_transfer));
1063 	usb_backend->transferred = 0;
1064 	usb_backend->flags = 0;
1065 
1066 	if (xfer->timeout != 0) {
1067 		clock_gettime(CLOCK_MONOTONIC, &cur_ts);
1068 		cur_ts.tv_sec += xfer->timeout / 1000;
1069 		cur_ts.tv_nsec += (xfer->timeout % 1000) * 1000000;
1070 
1071 		if (cur_ts.tv_nsec > 1000000000) {
1072 			cur_ts.tv_nsec -= 1000000000;
1073 			cur_ts.tv_sec++;
1074 		}
1075 
1076 		TIMESPEC_TO_TIMEVAL(&usb_backend->timeout, &cur_ts);
1077 	}
1078 
1079 	/*Add to flying list*/
1080 	pthread_mutex_lock(&ctx->flying_transfers_lock);
1081 	if (TAILQ_EMPTY(&ctx->flying_transfers)) {
1082 		TAILQ_INSERT_HEAD(&ctx->flying_transfers, usb_backend, list);
1083 		goto out;
1084 	}
1085 	if (timerisset(&usb_backend->timeout) == 0) {
1086 		TAILQ_INSERT_HEAD(&ctx->flying_transfers, usb_backend, list);
1087 		goto out;
1088 	}
1089 	TAILQ_FOREACH(usb_node, &ctx->flying_transfers, list) {
1090 		cur_tv = &usb_node->timeout;
1091 		if (timerisset(cur_tv) == 0 ||
1092 		    (cur_tv->tv_sec > usb_backend->timeout.tv_sec) ||
1093 		    (cur_tv->tv_sec == usb_backend->timeout.tv_sec &&
1094 		    cur_tv->tv_usec > usb_backend->timeout.tv_usec)) {
1095 			TAILQ_INSERT_TAIL(&ctx->flying_transfers, usb_backend, list);
1096 			goto out;
1097 		}
1098 	}
1099 	TAILQ_INSERT_TAIL(&ctx->flying_transfers, usb_backend, list);
1100 
1101 out:
1102 	pthread_mutex_unlock(&ctx->flying_transfers_lock);
1103 
1104 	ep_idx = (xfer->endpoint / 0x40) | (xfer->endpoint * 4) % (16 * 4);
1105 	usb20_xfer[0] = libusb20_tr_get_pointer(pdev, ep_idx);
1106 	usb20_xfer[1] = libusb20_tr_get_pointer(pdev, ep_idx + 1);
1107 
1108 	if (usb20_xfer[0] == NULL)
1109 		return (LIBUSB_ERROR_OTHER);
1110 
1111 	xfer->os_priv = usb20_xfer;
1112 
1113 	pthread_mutex_lock(&libusb20_lock);
1114 
1115 	buffsize = libusb_get_buffsize(pdev, xfer);
1116 	maxframe = libusb_get_maxframe(pdev, xfer);
1117 
1118 	ret = 0;
1119 	TAILQ_FOREACH(eptr, &devh->ep_list, list) {
1120 		if (xfer->endpoint == eptr->addr)
1121 			ret++;
1122 	}
1123 	if (ret == 0) {
1124 		eptr = malloc(sizeof(struct usb_ep_tr));
1125 		eptr->addr = xfer->endpoint;
1126 		eptr->idx = ep_idx;
1127 		eptr->os_priv = usb20_xfer;
1128 		eptr->flags = (xfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS)?1:0;
1129 		TAILQ_INSERT_HEAD(&devh->ep_list, eptr, list);
1130 		ret = libusb20_tr_open(usb20_xfer[0], buffsize,
1131 	    		maxframe, xfer->endpoint);
1132 		if (xfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS)
1133 			ret |= libusb20_tr_open(usb20_xfer[1], buffsize,
1134 		    	maxframe, xfer->endpoint);
1135 
1136 		if (ret != 0) {
1137 			pthread_mutex_unlock(&libusb20_lock);
1138 			pthread_mutex_lock(&ctx->flying_transfers_lock);
1139 			TAILQ_REMOVE(&ctx->flying_transfers, usb_backend, list);
1140 			pthread_mutex_unlock(&ctx->flying_transfers_lock);
1141 			return (LIBUSB_ERROR_OTHER);
1142 		}
1143 	}
1144 
1145 	libusb20_tr_set_priv_sc0(usb20_xfer[0], xfer);
1146 	libusb20_tr_set_callback(usb20_xfer[0], libusb10_proxy);
1147 	if (xfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) {
1148 		libusb20_tr_set_priv_sc0(usb20_xfer[1], xfer);
1149 		libusb20_tr_set_callback(usb20_xfer[1], libusb10_proxy);
1150 	}
1151 
1152 	DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "LIBUSB20_TR_START");
1153 	libusb20_tr_start(usb20_xfer[0]);
1154 	if (xfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS)
1155 		libusb20_tr_start(usb20_xfer[1]);
1156 
1157 	pthread_mutex_unlock(&libusb20_lock);
1158 
1159 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_submit_transfer leave");
1160 	return (0);
1161 }
1162 
1163 int
1164 libusb_cancel_transfer(struct libusb_transfer *xfer)
1165 {
1166 	libusb_context *ctx;
1167 
1168 	ctx = NULL;
1169 	GET_CONTEXT(ctx);
1170 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_cancel_transfer enter");
1171 
1172 	if (xfer == NULL)
1173 		return (LIBUSB_ERROR_NO_MEM);
1174 
1175 	pthread_mutex_lock(&libusb20_lock);
1176 	libusb20_tr_stop(xfer->os_priv);
1177 	pthread_mutex_unlock(&libusb20_lock);
1178 
1179 	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_cancel_transfer leave");
1180 	return (0);
1181 }
1182 
1183