]> CyberLeo.Net >> Repos - FreeBSD/releng/8.0.git/blob - lib/libusb/libusb10_io.c
Adjust to reflect 8.0-RELEASE.
[FreeBSD/releng/8.0.git] / lib / libusb / libusb10_io.c
1 /* $FreeBSD$ */
2 /*-
3  * Copyright (c) 2009 Sylvestre Gallon. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26
27 #include <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
42 UNEXPORTED void
43 libusb10_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
67 UNEXPORTED void
68 libusb10_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
87 static int
88 libusb10_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 (fds[i].revents == 0)
152                         continue;
153                 if (ppdev[i] != NULL) {
154                         dev = libusb_get_device(ppdev[i]);
155
156                         err = libusb20_dev_process(ppdev[i]);
157                         if (err) {
158                                 /* cancel all transfers - device is gone */
159                                 libusb10_cancel_all_transfer(dev);
160                                 /*
161                                  * make sure we don't go into an infinite
162                                  * loop
163                                  */
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
182 do_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
220 int
221 libusb_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
242 void
243 libusb_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
251 void
252 libusb_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
262 int
263 libusb_event_handling_ok(libusb_context *ctx)
264 {
265         ctx = GET_CONTEXT(ctx);
266         return (ctx->ctx_handler == pthread_self());
267 }
268
269 int
270 libusb_event_handler_active(libusb_context *ctx)
271 {
272         ctx = GET_CONTEXT(ctx);
273         return (ctx->ctx_handler != NO_THREAD);
274 }
275
276 void
277 libusb_lock_event_waiters(libusb_context *ctx)
278 {
279         ctx = GET_CONTEXT(ctx);
280         CTX_LOCK(ctx);
281 }
282
283 void
284 libusb_unlock_event_waiters(libusb_context *ctx)
285 {
286         ctx = GET_CONTEXT(ctx);
287         CTX_UNLOCK(ctx);
288 }
289
290 int
291 libusb_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
323 int
324 libusb_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
343 int
344 libusb_handle_events(libusb_context *ctx)
345 {
346         return (libusb_handle_events_timeout(ctx, NULL));
347 }
348
349 int
350 libusb_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
365 int
366 libusb_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
373 void
374 libusb_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
385 struct libusb_pollfd **
386 libusb_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
409 done:
410         CTX_UNLOCK(ctx);
411         return (ret);
412 }
413
414
415 /* Synchronous device I/O */
416
417 int
418 libusb_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
453 static void
454 libusb10_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  */
471 static int
472 libusb10_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
541 int
542 libusb_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
559 int
560 libusb_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 }