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