libusb10.c revision 213853
1/* $FreeBSD: head/lib/libusb/libusb10.c 213853 2010-10-14 20:50:33Z hselasky $ */
2/*-
3 * Copyright (c) 2009 Sylvestre Gallon. All rights reserved.
4 * Copyright (c) 2009 Hans Petter Selasky. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <sys/fcntl.h>
29#include <sys/ioctl.h>
30#include <sys/queue.h>
31
32#include <assert.h>
33#include <errno.h>
34#include <poll.h>
35#include <pthread.h>
36#include <stdio.h>
37#include <stdlib.h>
38#include <unistd.h>
39
40#define	libusb_device_handle libusb20_device
41
42#include "libusb20.h"
43#include "libusb20_desc.h"
44#include "libusb20_int.h"
45#include "libusb.h"
46#include "libusb10.h"
47
48static pthread_mutex_t default_context_lock = PTHREAD_MUTEX_INITIALIZER;
49struct libusb_context *usbi_default_context = NULL;
50
51/* Prototypes */
52
53static struct libusb20_transfer *libusb10_get_transfer(struct libusb20_device *, uint8_t, uint8_t);
54static int libusb10_get_maxframe(struct libusb20_device *, libusb_transfer *);
55static int libusb10_get_buffsize(struct libusb20_device *, libusb_transfer *);
56static int libusb10_convert_error(uint8_t status);
57static void libusb10_complete_transfer(struct libusb20_transfer *, struct libusb_super_transfer *, int);
58static void libusb10_isoc_proxy(struct libusb20_transfer *);
59static void libusb10_bulk_intr_proxy(struct libusb20_transfer *);
60static void libusb10_ctrl_proxy(struct libusb20_transfer *);
61static void libusb10_submit_transfer_sub(struct libusb20_device *, uint8_t);
62
63/*  Library initialisation / deinitialisation */
64
65void
66libusb_set_debug(libusb_context *ctx, int level)
67{
68	ctx = GET_CONTEXT(ctx);
69	if (ctx)
70		ctx->debug = level;
71}
72
73static void
74libusb_set_nonblocking(int f)
75{
76	int flags;
77
78	/*
79	 * We ignore any failures in this function, hence the
80	 * non-blocking flag is not critical to the operation of
81	 * libUSB. We use F_GETFL and F_SETFL to be compatible with
82	 * Linux.
83	 */
84
85	flags = fcntl(f, F_GETFL, NULL);
86	if (flags == -1)
87		return;
88	flags |= O_NONBLOCK;
89	fcntl(f, F_SETFL, flags);
90}
91
92int
93libusb_init(libusb_context **context)
94{
95	struct libusb_context *ctx;
96	char *debug;
97	int ret;
98
99	ctx = malloc(sizeof(*ctx));
100	if (!ctx)
101		return (LIBUSB_ERROR_INVALID_PARAM);
102
103	memset(ctx, 0, sizeof(*ctx));
104
105	debug = getenv("LIBUSB_DEBUG");
106	if (debug != NULL) {
107		ctx->debug = atoi(debug);
108		if (ctx->debug != 0)
109			ctx->debug_fixed = 1;
110	}
111	TAILQ_INIT(&ctx->pollfds);
112	TAILQ_INIT(&ctx->tr_done);
113
114	pthread_mutex_init(&ctx->ctx_lock, NULL);
115	pthread_cond_init(&ctx->ctx_cond, NULL);
116
117	ctx->ctx_handler = NO_THREAD;
118
119	ret = pipe(ctx->ctrl_pipe);
120	if (ret < 0) {
121		pthread_mutex_destroy(&ctx->ctx_lock);
122		pthread_cond_destroy(&ctx->ctx_cond);
123		free(ctx);
124		return (LIBUSB_ERROR_OTHER);
125	}
126	/* set non-blocking mode on the control pipe to avoid deadlock */
127	libusb_set_nonblocking(ctx->ctrl_pipe[0]);
128	libusb_set_nonblocking(ctx->ctrl_pipe[1]);
129
130	libusb10_add_pollfd(ctx, &ctx->ctx_poll, NULL, ctx->ctrl_pipe[0], POLLIN);
131
132	pthread_mutex_lock(&default_context_lock);
133	if (usbi_default_context == NULL) {
134		usbi_default_context = ctx;
135	}
136	pthread_mutex_unlock(&default_context_lock);
137
138	if (context)
139		*context = ctx;
140
141	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_init complete");
142
143	return (0);
144}
145
146void
147libusb_exit(libusb_context *ctx)
148{
149	ctx = GET_CONTEXT(ctx);
150
151	if (ctx == NULL)
152		return;
153
154	/* XXX cleanup devices */
155
156	libusb10_remove_pollfd(ctx, &ctx->ctx_poll);
157	close(ctx->ctrl_pipe[0]);
158	close(ctx->ctrl_pipe[1]);
159	pthread_mutex_destroy(&ctx->ctx_lock);
160	pthread_cond_destroy(&ctx->ctx_cond);
161
162	pthread_mutex_lock(&default_context_lock);
163	if (ctx == usbi_default_context) {
164		usbi_default_context = NULL;
165	}
166	pthread_mutex_unlock(&default_context_lock);
167
168	free(ctx);
169}
170
171/* Device handling and initialisation. */
172
173ssize_t
174libusb_get_device_list(libusb_context *ctx, libusb_device ***list)
175{
176	struct libusb20_backend *usb_backend;
177	struct libusb20_device *pdev;
178	struct libusb_device *dev;
179	int i;
180
181	ctx = GET_CONTEXT(ctx);
182
183	if (ctx == NULL)
184		return (LIBUSB_ERROR_INVALID_PARAM);
185
186	if (list == NULL)
187		return (LIBUSB_ERROR_INVALID_PARAM);
188
189	usb_backend = libusb20_be_alloc_default();
190	if (usb_backend == NULL)
191		return (LIBUSB_ERROR_NO_MEM);
192
193	/* figure out how many USB devices are present */
194	pdev = NULL;
195	i = 0;
196	while ((pdev = libusb20_be_device_foreach(usb_backend, pdev)))
197		i++;
198
199	/* allocate device pointer list */
200	*list = malloc((i + 1) * sizeof(void *));
201	if (*list == NULL) {
202		libusb20_be_free(usb_backend);
203		return (LIBUSB_ERROR_NO_MEM);
204	}
205	/* create libusb v1.0 compliant devices */
206	i = 0;
207	while ((pdev = libusb20_be_device_foreach(usb_backend, NULL))) {
208
209		dev = malloc(sizeof(*dev));
210		if (dev == NULL) {
211			while (i != 0) {
212				libusb_unref_device((*list)[i - 1]);
213				i--;
214			}
215			free(*list);
216			*list = NULL;
217			libusb20_be_free(usb_backend);
218			return (LIBUSB_ERROR_NO_MEM);
219		}
220
221		/* get device into libUSB v1.0 list */
222		libusb20_be_dequeue_device(usb_backend, pdev);
223
224		memset(dev, 0, sizeof(*dev));
225
226		/* init transfer queues */
227		TAILQ_INIT(&dev->tr_head);
228
229		/* set context we belong to */
230		dev->ctx = ctx;
231
232		/* link together the two structures */
233		dev->os_priv = pdev;
234		pdev->privLuData = dev;
235
236		(*list)[i] = libusb_ref_device(dev);
237		i++;
238	}
239	(*list)[i] = NULL;
240
241	libusb20_be_free(usb_backend);
242	return (i);
243}
244
245void
246libusb_free_device_list(libusb_device **list, int unref_devices)
247{
248	int i;
249
250	if (list == NULL)
251		return;			/* be NULL safe */
252
253	if (unref_devices) {
254		for (i = 0; list[i] != NULL; i++)
255			libusb_unref_device(list[i]);
256	}
257	free(list);
258}
259
260uint8_t
261libusb_get_bus_number(libusb_device *dev)
262{
263	if (dev == NULL)
264		return (0);		/* should not happen */
265	return (libusb20_dev_get_bus_number(dev->os_priv));
266}
267
268uint8_t
269libusb_get_device_address(libusb_device *dev)
270{
271	if (dev == NULL)
272		return (0);		/* should not happen */
273	return (libusb20_dev_get_address(dev->os_priv));
274}
275
276int
277libusb_get_max_packet_size(libusb_device *dev, uint8_t endpoint)
278{
279	struct libusb_config_descriptor *pdconf;
280	struct libusb_interface *pinf;
281	struct libusb_interface_descriptor *pdinf;
282	struct libusb_endpoint_descriptor *pdend;
283	int i;
284	int j;
285	int k;
286	int ret;
287
288	if (dev == NULL)
289		return (LIBUSB_ERROR_NO_DEVICE);
290
291	ret = libusb_get_active_config_descriptor(dev, &pdconf);
292	if (ret < 0)
293		return (ret);
294
295	ret = LIBUSB_ERROR_NOT_FOUND;
296	for (i = 0; i < pdconf->bNumInterfaces; i++) {
297		pinf = &pdconf->interface[i];
298		for (j = 0; j < pinf->num_altsetting; j++) {
299			pdinf = &pinf->altsetting[j];
300			for (k = 0; k < pdinf->bNumEndpoints; k++) {
301				pdend = &pdinf->endpoint[k];
302				if (pdend->bEndpointAddress == endpoint) {
303					ret = pdend->wMaxPacketSize;
304					goto out;
305				}
306			}
307		}
308	}
309
310out:
311	libusb_free_config_descriptor(pdconf);
312	return (ret);
313}
314
315libusb_device *
316libusb_ref_device(libusb_device *dev)
317{
318	if (dev == NULL)
319		return (NULL);		/* be NULL safe */
320
321	CTX_LOCK(dev->ctx);
322	dev->refcnt++;
323	CTX_UNLOCK(dev->ctx);
324
325	return (dev);
326}
327
328void
329libusb_unref_device(libusb_device *dev)
330{
331	if (dev == NULL)
332		return;			/* be NULL safe */
333
334	CTX_LOCK(dev->ctx);
335	dev->refcnt--;
336	CTX_UNLOCK(dev->ctx);
337
338	if (dev->refcnt == 0) {
339		libusb20_dev_free(dev->os_priv);
340		free(dev);
341	}
342}
343
344int
345libusb_open(libusb_device *dev, libusb_device_handle **devh)
346{
347	libusb_context *ctx = dev->ctx;
348	struct libusb20_device *pdev = dev->os_priv;
349	uint8_t dummy;
350	int err;
351
352	if (devh == NULL)
353		return (LIBUSB_ERROR_INVALID_PARAM);
354
355	/* set default device handle value */
356	*devh = NULL;
357
358	dev = libusb_ref_device(dev);
359	if (dev == NULL)
360		return (LIBUSB_ERROR_INVALID_PARAM);
361
362	err = libusb20_dev_open(pdev, 16 * 4 /* number of endpoints */ );
363	if (err) {
364		libusb_unref_device(dev);
365		return (LIBUSB_ERROR_NO_MEM);
366	}
367	libusb10_add_pollfd(ctx, &dev->dev_poll, pdev, libusb20_dev_get_fd(pdev), POLLIN |
368	    POLLOUT | POLLRDNORM | POLLWRNORM);
369
370	/* make sure our event loop detects the new device */
371	dummy = 0;
372	err = write(ctx->ctrl_pipe[1], &dummy, sizeof(dummy));
373	if (err < (int)sizeof(dummy)) {
374		/* ignore error, if any */
375		DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open write failed!");
376	}
377	*devh = pdev;
378
379	return (0);
380}
381
382libusb_device_handle *
383libusb_open_device_with_vid_pid(libusb_context *ctx, uint16_t vendor_id,
384    uint16_t product_id)
385{
386	struct libusb_device **devs;
387	struct libusb20_device *pdev;
388	struct LIBUSB20_DEVICE_DESC_DECODED *pdesc;
389	int i;
390	int j;
391
392	ctx = GET_CONTEXT(ctx);
393	if (ctx == NULL)
394		return (NULL);		/* be NULL safe */
395
396	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open_device_width_vid_pid enter");
397
398	if ((i = libusb_get_device_list(ctx, &devs)) < 0)
399		return (NULL);
400
401	for (j = 0; j < i; j++) {
402		pdev = devs[j]->os_priv;
403		pdesc = libusb20_dev_get_device_desc(pdev);
404		/*
405		 * NOTE: The USB library will automatically swap the
406		 * fields in the device descriptor to be of host
407		 * endian type!
408		 */
409		if (pdesc->idVendor == vendor_id &&
410		    pdesc->idProduct == product_id) {
411			if (libusb_open(devs[j], &pdev) < 0)
412				pdev = NULL;
413			break;
414		}
415	}
416	if (j == i)
417		pdev = NULL;
418
419	libusb_free_device_list(devs, 1);
420	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open_device_width_vid_pid leave");
421	return (pdev);
422}
423
424void
425libusb_close(struct libusb20_device *pdev)
426{
427	libusb_context *ctx;
428	struct libusb_device *dev;
429	uint8_t dummy;
430	int err;
431
432	if (pdev == NULL)
433		return;			/* be NULL safe */
434
435	dev = libusb_get_device(pdev);
436	ctx = dev->ctx;
437
438	libusb10_remove_pollfd(ctx, &dev->dev_poll);
439
440	libusb20_dev_close(pdev);
441
442	/* unref will free the "pdev" when the refcount reaches zero */
443	libusb_unref_device(dev);
444
445	/* make sure our event loop detects the closed device */
446	dummy = 0;
447	err = write(ctx->ctrl_pipe[1], &dummy, sizeof(dummy));
448	if (err < (int)sizeof(dummy)) {
449		/* ignore error, if any */
450		DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_close write failed!");
451	}
452}
453
454libusb_device *
455libusb_get_device(struct libusb20_device *pdev)
456{
457	if (pdev == NULL)
458		return (NULL);
459	return ((libusb_device *)pdev->privLuData);
460}
461
462int
463libusb_get_configuration(struct libusb20_device *pdev, int *config)
464{
465	struct libusb20_config *pconf;
466
467	if (pdev == NULL || config == NULL)
468		return (LIBUSB_ERROR_INVALID_PARAM);
469
470	pconf = libusb20_dev_alloc_config(pdev, libusb20_dev_get_config_index(pdev));
471	if (pconf == NULL)
472		return (LIBUSB_ERROR_NO_MEM);
473
474	*config = pconf->desc.bConfigurationValue;
475
476	free(pconf);
477
478	return (0);
479}
480
481int
482libusb_set_configuration(struct libusb20_device *pdev, int configuration)
483{
484	struct libusb20_config *pconf;
485	struct libusb_device *dev;
486	int err;
487	uint8_t i;
488
489	dev = libusb_get_device(pdev);
490	if (dev == NULL)
491		return (LIBUSB_ERROR_INVALID_PARAM);
492
493	if (configuration < 1) {
494		/* unconfigure */
495		i = 255;
496	} else {
497		for (i = 0; i != 255; i++) {
498			uint8_t found;
499
500			pconf = libusb20_dev_alloc_config(pdev, i);
501			if (pconf == NULL)
502				return (LIBUSB_ERROR_INVALID_PARAM);
503			found = (pconf->desc.bConfigurationValue
504			    == configuration);
505			free(pconf);
506
507			if (found)
508				goto set_config;
509		}
510		return (LIBUSB_ERROR_INVALID_PARAM);
511	}
512
513set_config:
514
515	libusb10_cancel_all_transfer(dev);
516
517	libusb10_remove_pollfd(dev->ctx, &dev->dev_poll);
518
519	err = libusb20_dev_set_config_index(pdev, i);
520
521	libusb10_add_pollfd(dev->ctx, &dev->dev_poll, pdev, libusb20_dev_get_fd(pdev), POLLIN |
522	    POLLOUT | POLLRDNORM | POLLWRNORM);
523
524	return (err ? LIBUSB_ERROR_INVALID_PARAM : 0);
525}
526
527int
528libusb_claim_interface(struct libusb20_device *pdev, int interface_number)
529{
530	libusb_device *dev;
531	int err = 0;
532
533	dev = libusb_get_device(pdev);
534	if (dev == NULL)
535		return (LIBUSB_ERROR_INVALID_PARAM);
536
537	if (interface_number < 0 || interface_number > 31)
538		return (LIBUSB_ERROR_INVALID_PARAM);
539
540	CTX_LOCK(dev->ctx);
541	if (dev->claimed_interfaces & (1 << interface_number))
542		err = LIBUSB_ERROR_BUSY;
543
544	if (!err)
545		dev->claimed_interfaces |= (1 << interface_number);
546	CTX_UNLOCK(dev->ctx);
547	return (err);
548}
549
550int
551libusb_release_interface(struct libusb20_device *pdev, int interface_number)
552{
553	libusb_device *dev;
554	int err = 0;
555
556	dev = libusb_get_device(pdev);
557	if (dev == NULL)
558		return (LIBUSB_ERROR_INVALID_PARAM);
559
560	if (interface_number < 0 || interface_number > 31)
561		return (LIBUSB_ERROR_INVALID_PARAM);
562
563	CTX_LOCK(dev->ctx);
564	if (!(dev->claimed_interfaces & (1 << interface_number)))
565		err = LIBUSB_ERROR_NOT_FOUND;
566
567	if (!err)
568		dev->claimed_interfaces &= ~(1 << interface_number);
569	CTX_UNLOCK(dev->ctx);
570	return (err);
571}
572
573int
574libusb_set_interface_alt_setting(struct libusb20_device *pdev,
575    int interface_number, int alternate_setting)
576{
577	libusb_device *dev;
578	int err = 0;
579
580	dev = libusb_get_device(pdev);
581	if (dev == NULL)
582		return (LIBUSB_ERROR_INVALID_PARAM);
583
584	if (interface_number < 0 || interface_number > 31)
585		return (LIBUSB_ERROR_INVALID_PARAM);
586
587	CTX_LOCK(dev->ctx);
588	if (!(dev->claimed_interfaces & (1 << interface_number)))
589		err = LIBUSB_ERROR_NOT_FOUND;
590	CTX_UNLOCK(dev->ctx);
591
592	if (err)
593		return (err);
594
595	libusb10_cancel_all_transfer(dev);
596
597	libusb10_remove_pollfd(dev->ctx, &dev->dev_poll);
598
599	err = libusb20_dev_set_alt_index(pdev,
600	    interface_number, alternate_setting);
601
602	libusb10_add_pollfd(dev->ctx, &dev->dev_poll,
603	    pdev, libusb20_dev_get_fd(pdev),
604	    POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM);
605
606	return (err ? LIBUSB_ERROR_OTHER : 0);
607}
608
609static struct libusb20_transfer *
610libusb10_get_transfer(struct libusb20_device *pdev,
611    uint8_t endpoint, uint8_t index)
612{
613	index &= 1;			/* double buffering */
614
615	index |= (endpoint & LIBUSB20_ENDPOINT_ADDRESS_MASK) * 4;
616
617	if (endpoint & LIBUSB20_ENDPOINT_DIR_MASK) {
618		/* this is an IN endpoint */
619		index |= 2;
620	}
621	return (libusb20_tr_get_pointer(pdev, index));
622}
623
624int
625libusb_clear_halt(struct libusb20_device *pdev, uint8_t endpoint)
626{
627	struct libusb20_transfer *xfer;
628	struct libusb_device *dev;
629	int err;
630
631	xfer = libusb10_get_transfer(pdev, endpoint, 0);
632	if (xfer == NULL)
633		return (LIBUSB_ERROR_INVALID_PARAM);
634
635	dev = libusb_get_device(pdev);
636	if (dev == NULL)
637		return (LIBUSB_ERROR_INVALID_PARAM);
638
639	CTX_LOCK(dev->ctx);
640	err = libusb20_tr_open(xfer, 0, 0, endpoint);
641	CTX_UNLOCK(dev->ctx);
642
643	if (err != 0 && err != LIBUSB20_ERROR_BUSY)
644		return (LIBUSB_ERROR_OTHER);
645
646	libusb20_tr_clear_stall_sync(xfer);
647
648	/* check if we opened the transfer */
649	if (err == 0) {
650		CTX_LOCK(dev->ctx);
651		libusb20_tr_close(xfer);
652		CTX_UNLOCK(dev->ctx);
653	}
654	return (0);			/* success */
655}
656
657int
658libusb_reset_device(struct libusb20_device *pdev)
659{
660	libusb_device *dev;
661	int err;
662
663	dev = libusb_get_device(pdev);
664	if (dev == NULL)
665		return (LIBUSB_ERROR_INVALID_PARAM);
666
667	libusb10_cancel_all_transfer(dev);
668
669	libusb10_remove_pollfd(dev->ctx, &dev->dev_poll);
670
671	err = libusb20_dev_reset(pdev);
672
673	libusb10_add_pollfd(dev->ctx, &dev->dev_poll,
674	    pdev, libusb20_dev_get_fd(pdev),
675	    POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM);
676
677	return (err ? LIBUSB_ERROR_OTHER : 0);
678}
679
680int
681libusb_check_connected(struct libusb20_device *pdev)
682{
683	libusb_device *dev;
684	int err;
685
686	dev = libusb_get_device(pdev);
687	if (dev == NULL)
688		return (LIBUSB_ERROR_INVALID_PARAM);
689
690	err = libusb20_dev_check_connected(pdev);
691
692	return (err ? LIBUSB_ERROR_NO_DEVICE : 0);
693}
694
695int
696libusb_kernel_driver_active(struct libusb20_device *pdev, int interface)
697{
698	if (pdev == NULL)
699		return (LIBUSB_ERROR_INVALID_PARAM);
700
701	return (libusb20_dev_kernel_driver_active(
702	    pdev, interface));
703}
704
705int
706libusb_get_driver_np(struct libusb20_device *pdev, int interface,
707    char *name, int namelen)
708{
709	return (libusb_get_driver(pdev, interface, name, namelen));
710}
711
712int
713libusb_get_driver(struct libusb20_device *pdev, int interface,
714    char *name, int namelen)
715{
716	char *ptr;
717	int err;
718
719	if (pdev == NULL)
720		return (LIBUSB_ERROR_INVALID_PARAM);
721	if (namelen < 1)
722		return (LIBUSB_ERROR_INVALID_PARAM);
723
724	err = libusb20_dev_get_iface_desc(
725	    pdev, interface, name, namelen);
726
727	if (err != 0)
728		return (LIBUSB_ERROR_OTHER);
729
730	/* we only want the driver name */
731	ptr = strstr(name, ":");
732	if (ptr != NULL)
733		*ptr = 0;
734
735	return (0);
736}
737
738int
739libusb_detach_kernel_driver_np(struct libusb20_device *pdev, int interface)
740{
741	return (libusb_detach_kernel_driver(pdev, interface));
742}
743
744int
745libusb_detach_kernel_driver(struct libusb20_device *pdev, int interface)
746{
747	int err;
748
749	if (pdev == NULL)
750		return (LIBUSB_ERROR_INVALID_PARAM);
751
752	err = libusb20_dev_detach_kernel_driver(
753	    pdev, interface);
754
755	return (err ? LIBUSB_ERROR_OTHER : 0);
756}
757
758int
759libusb_attach_kernel_driver(struct libusb20_device *pdev, int interface)
760{
761	if (pdev == NULL)
762		return (LIBUSB_ERROR_INVALID_PARAM);
763	/* stub - currently not supported by libusb20 */
764	return (0);
765}
766
767/* Asynchronous device I/O */
768
769struct libusb_transfer *
770libusb_alloc_transfer(int iso_packets)
771{
772	struct libusb_transfer *uxfer;
773	struct libusb_super_transfer *sxfer;
774	int len;
775
776	len = sizeof(struct libusb_transfer) +
777	    sizeof(struct libusb_super_transfer) +
778	    (iso_packets * sizeof(libusb_iso_packet_descriptor));
779
780	sxfer = malloc(len);
781	if (sxfer == NULL)
782		return (NULL);
783
784	memset(sxfer, 0, len);
785
786	uxfer = (struct libusb_transfer *)(
787	    ((uint8_t *)sxfer) + sizeof(*sxfer));
788
789	/* set default value */
790	uxfer->num_iso_packets = iso_packets;
791
792	return (uxfer);
793}
794
795void
796libusb_free_transfer(struct libusb_transfer *uxfer)
797{
798	struct libusb_super_transfer *sxfer;
799
800	if (uxfer == NULL)
801		return;			/* be NULL safe */
802
803	sxfer = (struct libusb_super_transfer *)(
804	    (uint8_t *)uxfer - sizeof(*sxfer));
805
806	free(sxfer);
807}
808
809static int
810libusb10_get_maxframe(struct libusb20_device *pdev, libusb_transfer *xfer)
811{
812	int ret;
813	int usb_speed;
814
815	usb_speed = libusb20_dev_get_speed(pdev);
816
817	switch (xfer->type) {
818	case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
819		switch (usb_speed) {
820		case LIBUSB20_SPEED_LOW:
821		case LIBUSB20_SPEED_FULL:
822			ret = 60 * 1;
823			break;
824		default:
825			ret = 60 * 8;
826			break;
827		}
828		break;
829	case LIBUSB_TRANSFER_TYPE_CONTROL:
830		ret = 2;
831		break;
832	default:
833		ret = 1;
834		break;
835	}
836	return (ret);
837}
838
839static int
840libusb10_get_buffsize(struct libusb20_device *pdev, libusb_transfer *xfer)
841{
842	int ret;
843	int usb_speed;
844
845	usb_speed = libusb20_dev_get_speed(pdev);
846
847	switch (xfer->type) {
848	case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
849		ret = 0;		/* kernel will auto-select */
850		break;
851	case LIBUSB_TRANSFER_TYPE_CONTROL:
852		ret = 1024;
853		break;
854	default:
855		switch (usb_speed) {
856		case LIBUSB20_SPEED_LOW:
857			ret = 256;
858			break;
859		case LIBUSB20_SPEED_FULL:
860			ret = 4096;
861			break;
862		default:
863			ret = 16384;
864			break;
865		}
866		break;
867	}
868	return (ret);
869}
870
871static int
872libusb10_convert_error(uint8_t status)
873{
874	;				/* indent fix */
875
876	switch (status) {
877	case LIBUSB20_TRANSFER_START:
878	case LIBUSB20_TRANSFER_COMPLETED:
879		return (LIBUSB_TRANSFER_COMPLETED);
880	case LIBUSB20_TRANSFER_OVERFLOW:
881		return (LIBUSB_TRANSFER_OVERFLOW);
882	case LIBUSB20_TRANSFER_NO_DEVICE:
883		return (LIBUSB_TRANSFER_NO_DEVICE);
884	case LIBUSB20_TRANSFER_STALL:
885		return (LIBUSB_TRANSFER_STALL);
886	case LIBUSB20_TRANSFER_CANCELLED:
887		return (LIBUSB_TRANSFER_CANCELLED);
888	case LIBUSB20_TRANSFER_TIMED_OUT:
889		return (LIBUSB_TRANSFER_TIMED_OUT);
890	default:
891		return (LIBUSB_TRANSFER_ERROR);
892	}
893}
894
895/* This function must be called locked */
896
897static void
898libusb10_complete_transfer(struct libusb20_transfer *pxfer,
899    struct libusb_super_transfer *sxfer, int status)
900{
901	struct libusb_transfer *uxfer;
902	struct libusb_device *dev;
903
904	uxfer = (struct libusb_transfer *)(
905	    ((uint8_t *)sxfer) + sizeof(*sxfer));
906
907	if (pxfer != NULL)
908		libusb20_tr_set_priv_sc1(pxfer, NULL);
909
910	/* set transfer status */
911	uxfer->status = status;
912
913	/* update super transfer state */
914	sxfer->state = LIBUSB_SUPER_XFER_ST_NONE;
915
916	dev = libusb_get_device(uxfer->dev_handle);
917
918	TAILQ_INSERT_TAIL(&dev->ctx->tr_done, sxfer, entry);
919}
920
921/* This function must be called locked */
922
923static void
924libusb10_isoc_proxy(struct libusb20_transfer *pxfer)
925{
926	struct libusb_super_transfer *sxfer;
927	struct libusb_transfer *uxfer;
928	uint32_t actlen;
929	uint16_t iso_packets;
930	uint16_t i;
931	uint8_t status;
932	uint8_t flags;
933
934	status = libusb20_tr_get_status(pxfer);
935	sxfer = libusb20_tr_get_priv_sc1(pxfer);
936	actlen = libusb20_tr_get_actual_length(pxfer);
937	iso_packets = libusb20_tr_get_max_frames(pxfer);
938
939	if (sxfer == NULL)
940		return;			/* cancelled - nothing to do */
941
942	uxfer = (struct libusb_transfer *)(
943	    ((uint8_t *)sxfer) + sizeof(*sxfer));
944
945	if (iso_packets > uxfer->num_iso_packets)
946		iso_packets = uxfer->num_iso_packets;
947
948	if (iso_packets == 0)
949		return;			/* nothing to do */
950
951	/* make sure that the number of ISOCHRONOUS packets is valid */
952	uxfer->num_iso_packets = iso_packets;
953
954	flags = uxfer->flags;
955
956	switch (status) {
957	case LIBUSB20_TRANSFER_COMPLETED:
958
959		/* update actual length */
960		uxfer->actual_length = actlen;
961		for (i = 0; i != iso_packets; i++) {
962			uxfer->iso_packet_desc[i].actual_length =
963			    libusb20_tr_get_length(pxfer, i);
964		}
965		libusb10_complete_transfer(pxfer, sxfer, LIBUSB_TRANSFER_COMPLETED);
966		break;
967
968	case LIBUSB20_TRANSFER_START:
969
970		/* setup length(s) */
971		actlen = 0;
972		for (i = 0; i != iso_packets; i++) {
973			libusb20_tr_setup_isoc(pxfer,
974			    &uxfer->buffer[actlen],
975			    uxfer->iso_packet_desc[i].length, i);
976			actlen += uxfer->iso_packet_desc[i].length;
977		}
978
979		/* no remainder */
980		sxfer->rem_len = 0;
981
982		libusb20_tr_set_total_frames(pxfer, iso_packets);
983		libusb20_tr_submit(pxfer);
984
985		/* fork another USB transfer, if any */
986		libusb10_submit_transfer_sub(libusb20_tr_get_priv_sc0(pxfer), uxfer->endpoint);
987		break;
988
989	default:
990		libusb10_complete_transfer(pxfer, sxfer, libusb10_convert_error(status));
991		break;
992	}
993}
994
995/* This function must be called locked */
996
997static void
998libusb10_bulk_intr_proxy(struct libusb20_transfer *pxfer)
999{
1000	struct libusb_super_transfer *sxfer;
1001	struct libusb_transfer *uxfer;
1002	uint32_t max_bulk;
1003	uint32_t actlen;
1004	uint8_t status;
1005	uint8_t flags;
1006
1007	status = libusb20_tr_get_status(pxfer);
1008	sxfer = libusb20_tr_get_priv_sc1(pxfer);
1009	max_bulk = libusb20_tr_get_max_total_length(pxfer);
1010	actlen = libusb20_tr_get_actual_length(pxfer);
1011
1012	if (sxfer == NULL)
1013		return;			/* cancelled - nothing to do */
1014
1015	uxfer = (struct libusb_transfer *)(
1016	    ((uint8_t *)sxfer) + sizeof(*sxfer));
1017
1018	flags = uxfer->flags;
1019
1020	switch (status) {
1021	case LIBUSB20_TRANSFER_COMPLETED:
1022
1023		uxfer->actual_length += actlen;
1024
1025		/* check for short packet */
1026		if (sxfer->last_len != actlen) {
1027			if (flags & LIBUSB_TRANSFER_SHORT_NOT_OK) {
1028				libusb10_complete_transfer(pxfer, sxfer, LIBUSB_TRANSFER_ERROR);
1029			} else {
1030				libusb10_complete_transfer(pxfer, sxfer, LIBUSB_TRANSFER_COMPLETED);
1031			}
1032			break;
1033		}
1034		/* check for end of data */
1035		if (sxfer->rem_len == 0) {
1036			libusb10_complete_transfer(pxfer, sxfer, LIBUSB_TRANSFER_COMPLETED);
1037			break;
1038		}
1039		/* FALLTHROUGH */
1040
1041	case LIBUSB20_TRANSFER_START:
1042		if (max_bulk > sxfer->rem_len) {
1043			max_bulk = sxfer->rem_len;
1044		}
1045		/* setup new BULK or INTERRUPT transaction */
1046		libusb20_tr_setup_bulk(pxfer,
1047		    sxfer->curr_data, max_bulk, uxfer->timeout);
1048
1049		/* update counters */
1050		sxfer->last_len = max_bulk;
1051		sxfer->curr_data += max_bulk;
1052		sxfer->rem_len -= max_bulk;
1053
1054		libusb20_tr_submit(pxfer);
1055
1056		/* check if we can fork another USB transfer */
1057		if (sxfer->rem_len == 0)
1058			libusb10_submit_transfer_sub(libusb20_tr_get_priv_sc0(pxfer), uxfer->endpoint);
1059		break;
1060
1061	default:
1062		libusb10_complete_transfer(pxfer, sxfer, libusb10_convert_error(status));
1063		break;
1064	}
1065}
1066
1067/* This function must be called locked */
1068
1069static void
1070libusb10_ctrl_proxy(struct libusb20_transfer *pxfer)
1071{
1072	struct libusb_super_transfer *sxfer;
1073	struct libusb_transfer *uxfer;
1074	uint32_t max_bulk;
1075	uint32_t actlen;
1076	uint8_t status;
1077	uint8_t flags;
1078
1079	status = libusb20_tr_get_status(pxfer);
1080	sxfer = libusb20_tr_get_priv_sc1(pxfer);
1081	max_bulk = libusb20_tr_get_max_total_length(pxfer);
1082	actlen = libusb20_tr_get_actual_length(pxfer);
1083
1084	if (sxfer == NULL)
1085		return;			/* cancelled - nothing to do */
1086
1087	uxfer = (struct libusb_transfer *)(
1088	    ((uint8_t *)sxfer) + sizeof(*sxfer));
1089
1090	flags = uxfer->flags;
1091
1092	switch (status) {
1093	case LIBUSB20_TRANSFER_COMPLETED:
1094
1095		uxfer->actual_length += actlen;
1096
1097		/* subtract length of SETUP packet, if any */
1098		actlen -= libusb20_tr_get_length(pxfer, 0);
1099
1100		/* check for short packet */
1101		if (sxfer->last_len != actlen) {
1102			if (flags & LIBUSB_TRANSFER_SHORT_NOT_OK) {
1103				libusb10_complete_transfer(pxfer, sxfer, LIBUSB_TRANSFER_ERROR);
1104			} else {
1105				libusb10_complete_transfer(pxfer, sxfer, LIBUSB_TRANSFER_COMPLETED);
1106			}
1107			break;
1108		}
1109		/* check for end of data */
1110		if (sxfer->rem_len == 0) {
1111			libusb10_complete_transfer(pxfer, sxfer, LIBUSB_TRANSFER_COMPLETED);
1112			break;
1113		}
1114		/* FALLTHROUGH */
1115
1116	case LIBUSB20_TRANSFER_START:
1117		if (max_bulk > sxfer->rem_len) {
1118			max_bulk = sxfer->rem_len;
1119		}
1120		/* setup new CONTROL transaction */
1121		if (status == LIBUSB20_TRANSFER_COMPLETED) {
1122			/* next fragment - don't send SETUP packet */
1123			libusb20_tr_set_length(pxfer, 0, 0);
1124		} else {
1125			/* first fragment - send SETUP packet */
1126			libusb20_tr_set_length(pxfer, 8, 0);
1127			libusb20_tr_set_buffer(pxfer, uxfer->buffer, 0);
1128		}
1129
1130		if (max_bulk != 0) {
1131			libusb20_tr_set_length(pxfer, max_bulk, 1);
1132			libusb20_tr_set_buffer(pxfer, sxfer->curr_data, 1);
1133			libusb20_tr_set_total_frames(pxfer, 2);
1134		} else {
1135			libusb20_tr_set_total_frames(pxfer, 1);
1136		}
1137
1138		/* update counters */
1139		sxfer->last_len = max_bulk;
1140		sxfer->curr_data += max_bulk;
1141		sxfer->rem_len -= max_bulk;
1142
1143		libusb20_tr_submit(pxfer);
1144
1145		/* check if we can fork another USB transfer */
1146		if (sxfer->rem_len == 0)
1147			libusb10_submit_transfer_sub(libusb20_tr_get_priv_sc0(pxfer), uxfer->endpoint);
1148		break;
1149
1150	default:
1151		libusb10_complete_transfer(pxfer, sxfer, libusb10_convert_error(status));
1152		break;
1153	}
1154}
1155
1156/* The following function must be called locked */
1157
1158static void
1159libusb10_submit_transfer_sub(struct libusb20_device *pdev, uint8_t endpoint)
1160{
1161	struct libusb20_transfer *pxfer0;
1162	struct libusb20_transfer *pxfer1;
1163	struct libusb_super_transfer *sxfer;
1164	struct libusb_transfer *uxfer;
1165	struct libusb_device *dev;
1166	int err;
1167	int buffsize;
1168	int maxframe;
1169	int temp;
1170	uint8_t dummy;
1171
1172	dev = libusb_get_device(pdev);
1173
1174	pxfer0 = libusb10_get_transfer(pdev, endpoint, 0);
1175	pxfer1 = libusb10_get_transfer(pdev, endpoint, 1);
1176
1177	if (pxfer0 == NULL || pxfer1 == NULL)
1178		return;			/* shouldn't happen */
1179
1180	temp = 0;
1181	if (libusb20_tr_pending(pxfer0))
1182		temp |= 1;
1183	if (libusb20_tr_pending(pxfer1))
1184		temp |= 2;
1185
1186	switch (temp) {
1187	case 3:
1188		/* wait till one of the transfers complete */
1189		return;
1190	case 2:
1191		sxfer = libusb20_tr_get_priv_sc1(pxfer1);
1192		if (sxfer == NULL)
1193			return;		/* cancelling */
1194		if (sxfer->rem_len)
1195			return;		/* cannot queue another one */
1196		/* swap transfers */
1197		pxfer1 = pxfer0;
1198		break;
1199	case 1:
1200		sxfer = libusb20_tr_get_priv_sc1(pxfer0);
1201		if (sxfer == NULL)
1202			return;		/* cancelling */
1203		if (sxfer->rem_len)
1204			return;		/* cannot queue another one */
1205		/* swap transfers */
1206		pxfer0 = pxfer1;
1207		break;
1208	default:
1209		break;
1210	}
1211
1212	/* find next transfer on same endpoint */
1213	TAILQ_FOREACH(sxfer, &dev->tr_head, entry) {
1214
1215		uxfer = (struct libusb_transfer *)(
1216		    ((uint8_t *)sxfer) + sizeof(*sxfer));
1217
1218		if (uxfer->endpoint == endpoint) {
1219			TAILQ_REMOVE(&dev->tr_head, sxfer, entry);
1220			sxfer->entry.tqe_prev = NULL;
1221			goto found;
1222		}
1223	}
1224	return;				/* success */
1225
1226found:
1227
1228	libusb20_tr_set_priv_sc0(pxfer0, pdev);
1229	libusb20_tr_set_priv_sc1(pxfer0, sxfer);
1230
1231	/* reset super transfer state */
1232	sxfer->rem_len = uxfer->length;
1233	sxfer->curr_data = uxfer->buffer;
1234	uxfer->actual_length = 0;
1235
1236	switch (uxfer->type) {
1237	case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
1238		libusb20_tr_set_callback(pxfer0, libusb10_isoc_proxy);
1239		break;
1240	case LIBUSB_TRANSFER_TYPE_BULK:
1241	case LIBUSB_TRANSFER_TYPE_INTERRUPT:
1242		libusb20_tr_set_callback(pxfer0, libusb10_bulk_intr_proxy);
1243		break;
1244	case LIBUSB_TRANSFER_TYPE_CONTROL:
1245		libusb20_tr_set_callback(pxfer0, libusb10_ctrl_proxy);
1246		if (sxfer->rem_len < 8)
1247			goto failure;
1248
1249		/* remove SETUP packet from data */
1250		sxfer->rem_len -= 8;
1251		sxfer->curr_data += 8;
1252		break;
1253	default:
1254		goto failure;
1255	}
1256
1257	buffsize = libusb10_get_buffsize(pdev, uxfer);
1258	maxframe = libusb10_get_maxframe(pdev, uxfer);
1259
1260	/* make sure the transfer is opened */
1261	err = libusb20_tr_open(pxfer0, buffsize, maxframe, endpoint);
1262	if (err && (err != LIBUSB20_ERROR_BUSY)) {
1263		goto failure;
1264	}
1265	libusb20_tr_start(pxfer0);
1266	return;
1267
1268failure:
1269	libusb10_complete_transfer(pxfer0, sxfer, LIBUSB_TRANSFER_ERROR);
1270
1271	/* make sure our event loop spins the done handler */
1272	dummy = 0;
1273	write(dev->ctx->ctrl_pipe[1], &dummy, sizeof(dummy));
1274}
1275
1276/* The following function must be called unlocked */
1277
1278int
1279libusb_submit_transfer(struct libusb_transfer *uxfer)
1280{
1281	struct libusb20_transfer *pxfer0;
1282	struct libusb20_transfer *pxfer1;
1283	struct libusb_super_transfer *sxfer;
1284	struct libusb_device *dev;
1285	uint32_t endpoint;
1286	int err;
1287
1288	if (uxfer == NULL)
1289		return (LIBUSB_ERROR_INVALID_PARAM);
1290
1291	if (uxfer->dev_handle == NULL)
1292		return (LIBUSB_ERROR_INVALID_PARAM);
1293
1294	endpoint = uxfer->endpoint;
1295
1296	if (endpoint > 255)
1297		return (LIBUSB_ERROR_INVALID_PARAM);
1298
1299	dev = libusb_get_device(uxfer->dev_handle);
1300
1301	DPRINTF(dev->ctx, LIBUSB_DEBUG_FUNCTION, "libusb_submit_transfer enter");
1302
1303	sxfer = (struct libusb_super_transfer *)(
1304	    (uint8_t *)uxfer - sizeof(*sxfer));
1305
1306	CTX_LOCK(dev->ctx);
1307
1308	pxfer0 = libusb10_get_transfer(uxfer->dev_handle, endpoint, 0);
1309	pxfer1 = libusb10_get_transfer(uxfer->dev_handle, endpoint, 1);
1310
1311	if (pxfer0 == NULL || pxfer1 == NULL) {
1312		err = LIBUSB_ERROR_OTHER;
1313	} else if ((sxfer->entry.tqe_prev != NULL) ||
1314	    (libusb20_tr_get_priv_sc1(pxfer0) == sxfer) ||
1315	    (libusb20_tr_get_priv_sc1(pxfer1) == sxfer)) {
1316		err = LIBUSB_ERROR_BUSY;
1317	} else {
1318
1319		/* set pending state */
1320		sxfer->state = LIBUSB_SUPER_XFER_ST_PEND;
1321
1322		/* insert transfer into transfer head list */
1323		TAILQ_INSERT_TAIL(&dev->tr_head, sxfer, entry);
1324
1325		/* start work transfers */
1326		libusb10_submit_transfer_sub(
1327		    uxfer->dev_handle, endpoint);
1328
1329		err = 0;		/* success */
1330	}
1331
1332	CTX_UNLOCK(dev->ctx);
1333
1334	DPRINTF(dev->ctx, LIBUSB_DEBUG_FUNCTION, "libusb_submit_transfer leave %d", err);
1335
1336	return (err);
1337}
1338
1339/* Asynchronous transfer cancel */
1340
1341int
1342libusb_cancel_transfer(struct libusb_transfer *uxfer)
1343{
1344	struct libusb20_transfer *pxfer0;
1345	struct libusb20_transfer *pxfer1;
1346	struct libusb_super_transfer *sxfer;
1347	struct libusb_device *dev;
1348	uint32_t endpoint;
1349	int retval;
1350
1351	if (uxfer == NULL)
1352		return (LIBUSB_ERROR_INVALID_PARAM);
1353
1354	/* check if not initialised */
1355	if (uxfer->dev_handle == NULL)
1356		return (LIBUSB_ERROR_NOT_FOUND);
1357
1358	endpoint = uxfer->endpoint;
1359
1360	if (endpoint > 255)
1361		return (LIBUSB_ERROR_INVALID_PARAM);
1362
1363	dev = libusb_get_device(uxfer->dev_handle);
1364
1365	DPRINTF(dev->ctx, LIBUSB_DEBUG_FUNCTION, "libusb_cancel_transfer enter");
1366
1367	sxfer = (struct libusb_super_transfer *)(
1368	    (uint8_t *)uxfer - sizeof(*sxfer));
1369
1370	retval = 0;
1371
1372	CTX_LOCK(dev->ctx);
1373
1374	pxfer0 = libusb10_get_transfer(uxfer->dev_handle, endpoint, 0);
1375	pxfer1 = libusb10_get_transfer(uxfer->dev_handle, endpoint, 1);
1376
1377	if (sxfer->state != LIBUSB_SUPER_XFER_ST_PEND) {
1378		/* only update the transfer status */
1379		uxfer->status = LIBUSB_TRANSFER_CANCELLED;
1380		retval = LIBUSB_ERROR_NOT_FOUND;
1381	} else if (sxfer->entry.tqe_prev != NULL) {
1382		/* we are lucky - transfer is on a queue */
1383		TAILQ_REMOVE(&dev->tr_head, sxfer, entry);
1384		sxfer->entry.tqe_prev = NULL;
1385		libusb10_complete_transfer(NULL,
1386		    sxfer, LIBUSB_TRANSFER_CANCELLED);
1387	} else if (pxfer0 == NULL || pxfer1 == NULL) {
1388		/* not started */
1389		retval = LIBUSB_ERROR_NOT_FOUND;
1390	} else if (libusb20_tr_get_priv_sc1(pxfer0) == sxfer) {
1391		libusb10_complete_transfer(pxfer0,
1392		    sxfer, LIBUSB_TRANSFER_CANCELLED);
1393		libusb20_tr_stop(pxfer0);
1394		/* make sure the queue doesn't stall */
1395		libusb10_submit_transfer_sub(
1396		    uxfer->dev_handle, endpoint);
1397	} else if (libusb20_tr_get_priv_sc1(pxfer1) == sxfer) {
1398		libusb10_complete_transfer(pxfer1,
1399		    sxfer, LIBUSB_TRANSFER_CANCELLED);
1400		libusb20_tr_stop(pxfer1);
1401		/* make sure the queue doesn't stall */
1402		libusb10_submit_transfer_sub(
1403		    uxfer->dev_handle, endpoint);
1404	} else {
1405		/* not started */
1406		retval = LIBUSB_ERROR_NOT_FOUND;
1407	}
1408
1409	CTX_UNLOCK(dev->ctx);
1410
1411	DPRINTF(dev->ctx, LIBUSB_DEBUG_FUNCTION, "libusb_cancel_transfer leave");
1412
1413	return (retval);
1414}
1415
1416UNEXPORTED void
1417libusb10_cancel_all_transfer(libusb_device *dev)
1418{
1419	/* TODO */
1420}
1421
1422uint16_t
1423libusb_cpu_to_le16(uint16_t x)
1424{
1425	return (htole16(x));
1426}
1427
1428uint16_t
1429libusb_le16_to_cpu(uint16_t x)
1430{
1431	return (le16toh(x));
1432}
1433
1434const char *
1435libusb_strerror(int code)
1436{
1437	/* TODO */
1438	return ("Unknown error");
1439}
1440