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