libusb10_io.c revision 213849
1/* $FreeBSD: head/lib/libusb/libusb10_io.c 213849 2010-10-14 20:18:39Z hselasky $ */
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
29#include <errno.h>
30#include <poll.h>
31#include <pthread.h>
32#include <stdio.h>
33#include <stdlib.h>
34#include <time.h>
35#include <unistd.h>
36
37#define	libusb_device_handle libusb20_device
38
39#include "libusb20.h"
40#include "libusb20_desc.h"
41#include "libusb20_int.h"
42#include "libusb.h"
43#include "libusb10.h"
44
45UNEXPORTED void
46libusb10_add_pollfd(libusb_context *ctx, struct libusb_super_pollfd *pollfd,
47    struct libusb20_device *pdev, int fd, short events)
48{
49	if (ctx == NULL)
50		return;			/* invalid */
51
52	if (pollfd->entry.tqe_prev != NULL)
53		return;			/* already queued */
54
55	if (fd < 0)
56		return;			/* invalid */
57
58	pollfd->pdev = pdev;
59	pollfd->pollfd.fd = fd;
60	pollfd->pollfd.events = events;
61
62	CTX_LOCK(ctx);
63	TAILQ_INSERT_TAIL(&ctx->pollfds, pollfd, entry);
64	CTX_UNLOCK(ctx);
65
66	if (ctx->fd_added_cb)
67		ctx->fd_added_cb(fd, events, ctx->fd_cb_user_data);
68}
69
70UNEXPORTED void
71libusb10_remove_pollfd(libusb_context *ctx, struct libusb_super_pollfd *pollfd)
72{
73	if (ctx == NULL)
74		return;			/* invalid */
75
76	if (pollfd->entry.tqe_prev == NULL)
77		return;			/* already dequeued */
78
79	CTX_LOCK(ctx);
80	TAILQ_REMOVE(&ctx->pollfds, pollfd, entry);
81	pollfd->entry.tqe_prev = NULL;
82	CTX_UNLOCK(ctx);
83
84	if (ctx->fd_removed_cb)
85		ctx->fd_removed_cb(pollfd->pollfd.fd, ctx->fd_cb_user_data);
86}
87
88/* This function must be called locked */
89
90static int
91libusb10_handle_events_sub(struct libusb_context *ctx, struct timeval *tv)
92{
93	struct libusb_device *dev;
94	struct libusb20_device **ppdev;
95	struct libusb_super_pollfd *pfd;
96	struct pollfd *fds;
97	struct libusb_super_transfer *sxfer;
98	struct libusb_transfer *uxfer;
99	nfds_t nfds;
100	int timeout;
101	int i;
102	int err;
103
104	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb10_handle_events_sub enter");
105
106	nfds = 0;
107	i = 0;
108	TAILQ_FOREACH(pfd, &ctx->pollfds, entry)
109	    nfds++;
110
111	fds = alloca(sizeof(*fds) * nfds);
112	if (fds == NULL)
113		return (LIBUSB_ERROR_NO_MEM);
114
115	ppdev = alloca(sizeof(*ppdev) * nfds);
116	if (ppdev == NULL)
117		return (LIBUSB_ERROR_NO_MEM);
118
119	TAILQ_FOREACH(pfd, &ctx->pollfds, entry) {
120		fds[i].fd = pfd->pollfd.fd;
121		fds[i].events = pfd->pollfd.events;
122		fds[i].revents = 0;
123		ppdev[i] = pfd->pdev;
124		if (pfd->pdev != NULL)
125			libusb_get_device(pfd->pdev)->refcnt++;
126		i++;
127	}
128
129	if (tv == NULL)
130		timeout = -1;
131	else
132		timeout = (tv->tv_sec * 1000) + ((tv->tv_usec + 999) / 1000);
133
134	CTX_UNLOCK(ctx);
135	err = poll(fds, nfds, timeout);
136	CTX_LOCK(ctx);
137
138	if ((err == -1) && (errno == EINTR))
139		err = LIBUSB_ERROR_INTERRUPTED;
140	else if (err < 0)
141		err = LIBUSB_ERROR_IO;
142
143	if (err < 1) {
144		for (i = 0; i != (int)nfds; i++) {
145			if (ppdev[i] != NULL) {
146				CTX_UNLOCK(ctx);
147				libusb_unref_device(libusb_get_device(ppdev[i]));
148				CTX_LOCK(ctx);
149			}
150		}
151		goto do_done;
152	}
153	for (i = 0; i != (int)nfds; i++) {
154		if (ppdev[i] != NULL) {
155			dev = libusb_get_device(ppdev[i]);
156
157			if (fds[i].revents == 0)
158				err = 0;	/* nothing to do */
159			else
160				err = libusb20_dev_process(ppdev[i]);
161
162			if (err) {
163				/* cancel all transfers - device is gone */
164				libusb10_cancel_all_transfer(dev);
165
166				/* remove USB device from polling loop */
167				libusb10_remove_pollfd(dev->ctx, &dev->dev_poll);
168			}
169			CTX_UNLOCK(ctx);
170			libusb_unref_device(dev);
171			CTX_LOCK(ctx);
172
173		} else {
174			uint8_t dummy;
175
176			while (1) {
177				if (read(fds[i].fd, &dummy, 1) != 1)
178					break;
179			}
180		}
181	}
182
183	err = 0;
184
185do_done:
186
187	/* Do all done callbacks */
188
189	while ((sxfer = TAILQ_FIRST(&ctx->tr_done))) {
190		TAILQ_REMOVE(&ctx->tr_done, sxfer, entry);
191		sxfer->entry.tqe_prev = NULL;
192
193		ctx->tr_done_ref++;
194
195		CTX_UNLOCK(ctx);
196
197		uxfer = (struct libusb_transfer *)(
198		    ((uint8_t *)sxfer) + sizeof(*sxfer));
199
200		if (uxfer->callback != NULL)
201			(uxfer->callback) (uxfer);
202
203		if (uxfer->flags & LIBUSB_TRANSFER_FREE_BUFFER)
204			free(uxfer->buffer);
205
206		if (uxfer->flags & LIBUSB_TRANSFER_FREE_TRANSFER)
207			libusb_free_transfer(uxfer);
208
209		CTX_LOCK(ctx);
210
211		ctx->tr_done_ref--;
212		ctx->tr_done_gen++;
213	}
214
215	/* Wakeup other waiters */
216	pthread_cond_broadcast(&ctx->ctx_cond);
217
218	return (err);
219}
220
221/* Polling and timing */
222
223int
224libusb_try_lock_events(libusb_context *ctx)
225{
226	int err;
227
228	ctx = GET_CONTEXT(ctx);
229	if (ctx == NULL)
230		return (1);
231
232	err = CTX_TRYLOCK(ctx);
233	if (err)
234		return (1);
235
236	err = (ctx->ctx_handler != NO_THREAD);
237	if (err)
238		CTX_UNLOCK(ctx);
239	else
240		ctx->ctx_handler = pthread_self();
241
242	return (err);
243}
244
245void
246libusb_lock_events(libusb_context *ctx)
247{
248	ctx = GET_CONTEXT(ctx);
249	CTX_LOCK(ctx);
250	if (ctx->ctx_handler == NO_THREAD)
251		ctx->ctx_handler = pthread_self();
252}
253
254void
255libusb_unlock_events(libusb_context *ctx)
256{
257	ctx = GET_CONTEXT(ctx);
258	if (ctx->ctx_handler == pthread_self()) {
259		ctx->ctx_handler = NO_THREAD;
260		pthread_cond_broadcast(&ctx->ctx_cond);
261	}
262	CTX_UNLOCK(ctx);
263}
264
265int
266libusb_event_handling_ok(libusb_context *ctx)
267{
268	ctx = GET_CONTEXT(ctx);
269	return (ctx->ctx_handler == pthread_self());
270}
271
272int
273libusb_event_handler_active(libusb_context *ctx)
274{
275	ctx = GET_CONTEXT(ctx);
276	return (ctx->ctx_handler != NO_THREAD);
277}
278
279void
280libusb_lock_event_waiters(libusb_context *ctx)
281{
282	ctx = GET_CONTEXT(ctx);
283	CTX_LOCK(ctx);
284}
285
286void
287libusb_unlock_event_waiters(libusb_context *ctx)
288{
289	ctx = GET_CONTEXT(ctx);
290	CTX_UNLOCK(ctx);
291}
292
293int
294libusb_wait_for_event(libusb_context *ctx, struct timeval *tv)
295{
296	struct timespec ts;
297	int err;
298
299	ctx = GET_CONTEXT(ctx);
300	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_wait_for_event enter");
301
302	if (tv == NULL) {
303		pthread_cond_wait(&ctx->ctx_cond,
304		    &ctx->ctx_lock);
305		return (0);
306	}
307	err = clock_gettime(CLOCK_REALTIME, &ts);
308	if (err < 0)
309		return (LIBUSB_ERROR_OTHER);
310
311	ts.tv_sec = tv->tv_sec;
312	ts.tv_nsec = tv->tv_usec * 1000;
313	if (ts.tv_nsec >= 1000000000) {
314		ts.tv_nsec -= 1000000000;
315		ts.tv_sec++;
316	}
317	err = pthread_cond_timedwait(&ctx->ctx_cond,
318	    &ctx->ctx_lock, &ts);
319
320	if (err == ETIMEDOUT)
321		return (1);
322
323	return (0);
324}
325
326int
327libusb_handle_events_timeout(libusb_context *ctx, struct timeval *tv)
328{
329	int err;
330
331	ctx = GET_CONTEXT(ctx);
332
333	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_handle_events_timeout enter");
334
335	libusb_lock_events(ctx);
336
337	err = libusb_handle_events_locked(ctx, tv);
338
339	libusb_unlock_events(ctx);
340
341	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_handle_events_timeout leave");
342
343	return (err);
344}
345
346int
347libusb_handle_events(libusb_context *ctx)
348{
349	return (libusb_handle_events_timeout(ctx, NULL));
350}
351
352int
353libusb_handle_events_locked(libusb_context *ctx, struct timeval *tv)
354{
355	int err;
356
357	ctx = GET_CONTEXT(ctx);
358
359	if (libusb_event_handling_ok(ctx)) {
360		err = libusb10_handle_events_sub(ctx, tv);
361	} else {
362		libusb_wait_for_event(ctx, tv);
363		err = 0;
364	}
365	return (err);
366}
367
368int
369libusb_get_next_timeout(libusb_context *ctx, struct timeval *tv)
370{
371	/* all timeouts are currently being done by the kernel */
372	timerclear(tv);
373	return (0);
374}
375
376void
377libusb_set_pollfd_notifiers(libusb_context *ctx,
378    libusb_pollfd_added_cb added_cb, libusb_pollfd_removed_cb removed_cb,
379    void *user_data)
380{
381	ctx = GET_CONTEXT(ctx);
382
383	ctx->fd_added_cb = added_cb;
384	ctx->fd_removed_cb = removed_cb;
385	ctx->fd_cb_user_data = user_data;
386}
387
388struct libusb_pollfd **
389libusb_get_pollfds(libusb_context *ctx)
390{
391	struct libusb_super_pollfd *pollfd;
392	libusb_pollfd **ret;
393	int i;
394
395	ctx = GET_CONTEXT(ctx);
396
397	CTX_LOCK(ctx);
398
399	i = 0;
400	TAILQ_FOREACH(pollfd, &ctx->pollfds, entry)
401	    i++;
402
403	ret = calloc(i + 1, sizeof(struct libusb_pollfd *));
404	if (ret == NULL)
405		goto done;
406
407	i = 0;
408	TAILQ_FOREACH(pollfd, &ctx->pollfds, entry)
409	    ret[i++] = &pollfd->pollfd;
410	ret[i] = NULL;
411
412done:
413	CTX_UNLOCK(ctx);
414	return (ret);
415}
416
417
418/* Synchronous device I/O */
419
420int
421libusb_control_transfer(libusb_device_handle *devh,
422    uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex,
423    uint8_t *data, uint16_t wLength, unsigned int timeout)
424{
425	struct LIBUSB20_CONTROL_SETUP_DECODED req;
426	int err;
427	uint16_t actlen;
428
429	if (devh == NULL)
430		return (LIBUSB_ERROR_INVALID_PARAM);
431
432	if ((wLength != 0) && (data == NULL))
433		return (LIBUSB_ERROR_INVALID_PARAM);
434
435	LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &req);
436
437	req.bmRequestType = bmRequestType;
438	req.bRequest = bRequest;
439	req.wValue = wValue;
440	req.wIndex = wIndex;
441	req.wLength = wLength;
442
443	err = libusb20_dev_request_sync(devh, &req, data,
444	    &actlen, timeout, 0);
445
446	if (err == LIBUSB20_ERROR_PIPE)
447		return (LIBUSB_ERROR_PIPE);
448	else if (err == LIBUSB20_ERROR_TIMEOUT)
449		return (LIBUSB_ERROR_TIMEOUT);
450	else if (err)
451		return (LIBUSB_ERROR_NO_DEVICE);
452
453	return (actlen);
454}
455
456static void
457libusb10_do_transfer_cb(struct libusb_transfer *transfer)
458{
459	libusb_context *ctx;
460	int *pdone;
461
462	ctx = GET_CONTEXT(NULL);
463
464	DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "sync I/O done");
465
466	pdone = transfer->user_data;
467	*pdone = 1;
468}
469
470/*
471 * TODO: Replace the following function. Allocating and freeing on a
472 * per-transfer basis is slow.  --HPS
473 */
474static int
475libusb10_do_transfer(libusb_device_handle *devh,
476    uint8_t endpoint, uint8_t *data, int length,
477    int *transferred, unsigned int timeout, int type)
478{
479	libusb_context *ctx;
480	struct libusb_transfer *xfer;
481	volatile int complet;
482	int ret;
483
484	if (devh == NULL)
485		return (LIBUSB_ERROR_INVALID_PARAM);
486
487	if ((length != 0) && (data == NULL))
488		return (LIBUSB_ERROR_INVALID_PARAM);
489
490	xfer = libusb_alloc_transfer(0);
491	if (xfer == NULL)
492		return (LIBUSB_ERROR_NO_MEM);
493
494	ctx = libusb_get_device(devh)->ctx;
495
496	xfer->dev_handle = devh;
497	xfer->endpoint = endpoint;
498	xfer->type = type;
499	xfer->timeout = timeout;
500	xfer->buffer = data;
501	xfer->length = length;
502	xfer->user_data = (void *)&complet;
503	xfer->callback = libusb10_do_transfer_cb;
504	complet = 0;
505
506	if ((ret = libusb_submit_transfer(xfer)) < 0) {
507		libusb_free_transfer(xfer);
508		return (ret);
509	}
510	while (complet == 0) {
511		if ((ret = libusb_handle_events(ctx)) < 0) {
512			libusb_cancel_transfer(xfer);
513			usleep(1000);	/* nice it */
514		}
515	}
516
517	*transferred = xfer->actual_length;
518
519	switch (xfer->status) {
520	case LIBUSB_TRANSFER_COMPLETED:
521		ret = 0;
522		break;
523	case LIBUSB_TRANSFER_TIMED_OUT:
524		ret = LIBUSB_ERROR_TIMEOUT;
525		break;
526	case LIBUSB_TRANSFER_OVERFLOW:
527		ret = LIBUSB_ERROR_OVERFLOW;
528		break;
529	case LIBUSB_TRANSFER_STALL:
530		ret = LIBUSB_ERROR_PIPE;
531		break;
532	case LIBUSB_TRANSFER_NO_DEVICE:
533		ret = LIBUSB_ERROR_NO_DEVICE;
534		break;
535	default:
536		ret = LIBUSB_ERROR_OTHER;
537		break;
538	}
539
540	libusb_free_transfer(xfer);
541	return (ret);
542}
543
544int
545libusb_bulk_transfer(libusb_device_handle *devh,
546    uint8_t endpoint, uint8_t *data, int length,
547    int *transferred, unsigned int timeout)
548{
549	libusb_context *ctx;
550	int ret;
551
552	ctx = GET_CONTEXT(NULL);
553	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_bulk_transfer enter");
554
555	ret = libusb10_do_transfer(devh, endpoint, data, length, transferred,
556	    timeout, LIBUSB_TRANSFER_TYPE_BULK);
557
558	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_bulk_transfer leave");
559	return (ret);
560}
561
562int
563libusb_interrupt_transfer(libusb_device_handle *devh,
564    uint8_t endpoint, uint8_t *data, int length,
565    int *transferred, unsigned int timeout)
566{
567	libusb_context *ctx;
568	int ret;
569
570	ctx = GET_CONTEXT(NULL);
571	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_interrupt_transfer enter");
572
573	ret = libusb10_do_transfer(devh, endpoint, data, length, transferred,
574	    timeout, LIBUSB_TRANSFER_TYPE_INTERRUPT);
575
576	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_interrupt_transfer leave");
577	return (ret);
578}
579
580uint8_t *
581libusb_get_iso_packet_buffer(struct libusb_transfer *transfer, uint32_t index)
582{
583	uint8_t *ptr;
584	uint32_t n;
585
586	if (transfer->num_iso_packets < 0)
587		return (NULL);
588
589	if (index >= (uint32_t)transfer->num_iso_packets)
590		return (NULL);
591
592	ptr = transfer->buffer;
593	if (ptr == NULL)
594		return (NULL);
595
596	for (n = 0; n != index; n++) {
597		ptr += transfer->iso_packet_desc[n].length;
598	}
599	return (ptr);
600}
601
602uint8_t *
603libusb_get_iso_packet_buffer_simple(struct libusb_transfer *transfer, uint32_t index)
604{
605	uint8_t *ptr;
606
607	if (transfer->num_iso_packets < 0)
608		return (NULL);
609
610	if (index >= (uint32_t)transfer->num_iso_packets)
611		return (NULL);
612
613	ptr = transfer->buffer;
614	if (ptr == NULL)
615		return (NULL);
616
617	ptr += transfer->iso_packet_desc[0].length * index;
618
619	return (ptr);
620}
621
622void
623libusb_set_iso_packet_lengths(struct libusb_transfer *transfer, uint32_t length)
624{
625	int n;
626
627	if (transfer->num_iso_packets < 0)
628		return;
629
630	for (n = 0; n != transfer->num_iso_packets; n++)
631		transfer->iso_packet_desc[n].length = length;
632}
633
634uint8_t *
635libusb_control_transfer_get_data(struct libusb_transfer *transfer)
636{
637	if (transfer->buffer == NULL)
638		return (NULL);
639
640	return (transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE);
641}
642
643struct libusb_control_setup *
644libusb_control_transfer_get_setup(struct libusb_transfer *transfer)
645{
646	return ((struct libusb_control_setup *)transfer->buffer);
647}
648
649void
650libusb_fill_control_setup(uint8_t *buf, uint8_t bmRequestType,
651    uint8_t bRequest, uint16_t wValue,
652    uint16_t wIndex, uint16_t wLength)
653{
654	struct libusb_control_setup *req = (struct libusb_control_setup *)buf;
655
656	/* The alignment is OK for all fields below. */
657	req->bmRequestType = bmRequestType;
658	req->bRequest = bRequest;
659	req->wValue = htole16(wValue);
660	req->wIndex = htole16(wIndex);
661	req->wLength = htole16(wLength);
662}
663
664void
665libusb_fill_control_transfer(struct libusb_transfer *transfer,
666    libusb_device_handle *devh, uint8_t *buf,
667    libusb_transfer_cb_fn callback, void *user_data,
668    uint32_t timeout)
669{
670	struct libusb_control_setup *setup = (struct libusb_control_setup *)buf;
671
672	transfer->dev_handle = devh;
673	transfer->endpoint = 0;
674	transfer->type = LIBUSB_TRANSFER_TYPE_CONTROL;
675	transfer->timeout = timeout;
676	transfer->buffer = buf;
677	if (setup != NULL)
678		transfer->length = LIBUSB_CONTROL_SETUP_SIZE
679			+ le16toh(setup->wLength);
680	else
681		transfer->length = 0;
682	transfer->user_data = user_data;
683	transfer->callback = callback;
684
685}
686
687void
688libusb_fill_bulk_transfer(struct libusb_transfer *transfer,
689    libusb_device_handle *devh, uint8_t endpoint, uint8_t *buf,
690    int length, libusb_transfer_cb_fn callback, void *user_data,
691    uint32_t timeout)
692{
693	transfer->dev_handle = devh;
694	transfer->endpoint = endpoint;
695	transfer->type = LIBUSB_TRANSFER_TYPE_BULK;
696	transfer->timeout = timeout;
697	transfer->buffer = buf;
698	transfer->length = length;
699	transfer->user_data = user_data;
700	transfer->callback = callback;
701}
702
703void
704libusb_fill_interrupt_transfer(struct libusb_transfer *transfer,
705    libusb_device_handle *devh, uint8_t endpoint, uint8_t *buf,
706    int length, libusb_transfer_cb_fn callback, void *user_data,
707    uint32_t timeout)
708{
709	transfer->dev_handle = devh;
710	transfer->endpoint = endpoint;
711	transfer->type = LIBUSB_TRANSFER_TYPE_INTERRUPT;
712	transfer->timeout = timeout;
713	transfer->buffer = buf;
714	transfer->length = length;
715	transfer->user_data = user_data;
716	transfer->callback = callback;
717}
718
719void
720libusb_fill_iso_transfer(struct libusb_transfer *transfer,
721    libusb_device_handle *devh, uint8_t endpoint, uint8_t *buf,
722    int length, int npacket, libusb_transfer_cb_fn callback,
723    void *user_data, uint32_t timeout)
724{
725	transfer->dev_handle = devh;
726	transfer->endpoint = endpoint;
727	transfer->type = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS;
728	transfer->timeout = timeout;
729	transfer->buffer = buf;
730	transfer->length = length;
731	transfer->num_iso_packets = npacket;
732	transfer->user_data = user_data;
733	transfer->callback = callback;
734}
735
736