]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libusb/libusb10.c
Update less to v436. This is considered as a bugfix release from vendor.
[FreeBSD/FreeBSD.git] / lib / libusb / libusb10.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 <sys/queue.h>
28 #include <stdlib.h>
29 #include <unistd.h>
30 #include <stdio.h>
31 #include <poll.h>
32 #include <pthread.h>
33 #include <time.h>
34 #include <errno.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 static pthread_mutex_t default_context_lock = PTHREAD_MUTEX_INITIALIZER;
43 struct libusb_context *usbi_default_context = NULL;
44 pthread_mutex_t libusb20_lock = PTHREAD_MUTEX_INITIALIZER;
45
46 /*  Library initialisation / deinitialisation */
47
48 void
49 libusb_set_debug(libusb_context * ctx, int level)
50 {
51         GET_CONTEXT(ctx);
52         if (ctx)
53                 ctx->debug = level;
54 }
55
56 int
57 libusb_init(libusb_context ** context)
58 {
59         struct libusb_context *ctx;
60         char * debug;
61         int ret;
62
63         ctx = malloc(sizeof(*ctx));
64         if (!ctx)
65                 return (LIBUSB_ERROR_INVALID_PARAM);
66
67         memset(ctx, 0, sizeof(*ctx));
68
69         debug = getenv("LIBUSB_DEBUG");
70         if (debug != NULL) {
71                 ctx->debug = atoi(debug);
72                 if (ctx->debug != 0)
73                         ctx->debug_fixed = 1;
74         }
75
76         pthread_mutex_init(&ctx->usb_devs_lock, NULL);
77         pthread_mutex_init(&ctx->open_devs_lock, NULL);
78         TAILQ_INIT(&ctx->usb_devs);
79         TAILQ_INIT(&ctx->open_devs);
80
81         pthread_mutex_init(&ctx->flying_transfers_lock, NULL);
82         pthread_mutex_init(&ctx->pollfds_lock, NULL);
83         pthread_mutex_init(&ctx->pollfd_modify_lock, NULL);
84         pthread_mutex_init(&ctx->events_lock, NULL);
85         pthread_mutex_init(&ctx->event_waiters_lock, NULL);
86         pthread_cond_init(&ctx->event_waiters_cond, NULL);
87
88         TAILQ_INIT(&ctx->flying_transfers);
89         TAILQ_INIT(&ctx->pollfds);
90
91         ret = pipe(ctx->ctrl_pipe);
92         if (ret < 0) {
93                 usb_remove_pollfd(ctx, ctx->ctrl_pipe[0]);
94                 close(ctx->ctrl_pipe[0]);
95                 close(ctx->ctrl_pipe[1]);
96                 free(ctx);
97                 return (LIBUSB_ERROR_OTHER);
98         }
99
100         ret = usb_add_pollfd(ctx, ctx->ctrl_pipe[0], POLLIN);
101         if (ret < 0) {
102                 usb_remove_pollfd(ctx, ctx->ctrl_pipe[0]);
103                 close(ctx->ctrl_pipe[0]);
104                 close(ctx->ctrl_pipe[1]);
105                 free(ctx);
106                 return ret;
107         }
108
109         pthread_mutex_lock(&default_context_lock);
110         if (usbi_default_context == NULL) {
111                 usbi_default_context = ctx;
112         }
113         pthread_mutex_unlock(&default_context_lock);
114
115         if (context)
116                 *context = ctx;
117
118         return (0);
119 }
120
121 void
122 libusb_exit(libusb_context * ctx)
123 {
124         GET_CONTEXT(ctx);
125
126         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_exit enter");
127         usb_remove_pollfd(ctx, ctx->ctrl_pipe[0]);
128         close(ctx->ctrl_pipe[0]);
129         close(ctx->ctrl_pipe[1]);
130
131         pthread_mutex_lock(&default_context_lock);
132         if (ctx == usbi_default_context) {
133                 usbi_default_context = NULL;
134         }
135         pthread_mutex_unlock(&default_context_lock);
136
137         free(ctx);
138         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_exit leave");
139 }
140
141 /* Device handling and initialisation. */
142
143 ssize_t
144 libusb_get_device_list(libusb_context * ctx, libusb_device *** list)
145 {
146         struct libusb20_device *pdev;
147         struct LIBUSB20_DEVICE_DESC_DECODED *ddesc;
148         struct libusb_device *dev;
149         struct libusb20_backend *usb_backend;
150         int i;
151
152         GET_CONTEXT(ctx);
153         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device_list enter");
154
155         usb_backend = libusb20_be_alloc_default();
156         if (usb_backend == NULL)
157                 return (-1);
158
159         pdev = NULL;
160         i = 0;
161         while ((pdev = libusb20_be_device_foreach(usb_backend, pdev)))
162                 i++;
163
164         if (list == NULL) {
165                 libusb20_be_free(usb_backend);
166                 return (LIBUSB_ERROR_INVALID_PARAM);
167         }
168         *list = malloc((i + 1) * sizeof(void *));
169         if (*list == NULL) {
170                 libusb20_be_free(usb_backend);
171                 return (LIBUSB_ERROR_NO_MEM);
172         }
173         i = 0;
174         while ((pdev = libusb20_be_device_foreach(usb_backend, NULL))) {
175                 /* get device into libUSB v1.0 list */
176                 libusb20_be_dequeue_device(usb_backend, pdev);
177
178                 ddesc = libusb20_dev_get_device_desc(pdev);
179                 dev = malloc(sizeof(*dev));
180                 if (dev == NULL) {
181                         while (i != 0) {
182                                 libusb_unref_device((*list)[i - 1]);
183                                 i--;
184                         }
185                         free(*list);
186                         libusb20_be_free(usb_backend);
187                         return (LIBUSB_ERROR_NO_MEM);
188                 }
189                 memset(dev, 0, sizeof(*dev));
190
191                 pthread_mutex_init(&dev->lock, NULL);
192                 dev->ctx = ctx;
193                 dev->bus_number = pdev->bus_number;
194                 dev->device_address = pdev->device_address;
195                 dev->num_configurations = ddesc->bNumConfigurations;
196
197                 /* link together the two structures */
198                 dev->os_priv = pdev;
199
200                 pthread_mutex_lock(&ctx->usb_devs_lock);
201                 TAILQ_INSERT_HEAD(&ctx->usb_devs, dev, list);
202                 pthread_mutex_unlock(&ctx->usb_devs_lock);
203
204                 (*list)[i] = libusb_ref_device(dev);
205                 i++;
206         }
207         (*list)[i] = NULL;
208
209         libusb20_be_free(usb_backend);
210         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device_list leave");
211         return (i);
212 }
213
214 /*
215  * In this function we cant free all the device contained into list because
216  * open_with_pid_vid use some node of list after the free_device_list.
217  */
218 void
219 libusb_free_device_list(libusb_device **list, int unref_devices)
220 {
221         int i;
222         libusb_context *ctx;
223
224         ctx = NULL;
225         GET_CONTEXT(ctx);
226         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_free_device_list enter");
227
228         if (list == NULL)
229                 return ;
230
231         if (unref_devices) {
232                 for (i = 0; list[i] != NULL; i++)
233                         libusb_unref_device(list[i]);
234         }
235         free(list);
236         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_free_device_list leave");
237 }
238
239 uint8_t
240 libusb_get_bus_number(libusb_device * dev)
241 {
242         libusb_context *ctx;
243
244         ctx = NULL;
245         GET_CONTEXT(ctx);
246         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_bus_number enter");
247
248         if (dev == NULL)
249                 return (LIBUSB_ERROR_NO_DEVICE);
250         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_bus_number leave");
251         return (dev->bus_number);
252 }
253
254 uint8_t
255 libusb_get_device_address(libusb_device * dev)
256 {
257         libusb_context *ctx;
258
259         ctx = NULL;
260         GET_CONTEXT(ctx);
261         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device_address enter");
262
263         if (dev == NULL)
264                 return (LIBUSB_ERROR_NO_DEVICE);
265         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device_address leave");
266         return (dev->device_address);
267 }
268
269 int
270 libusb_get_max_packet_size(libusb_device *dev, unsigned char endpoint)
271 {
272         struct libusb_config_descriptor *pdconf;
273         struct libusb_interface *pinf;
274         struct libusb_interface_descriptor *pdinf;
275         struct libusb_endpoint_descriptor *pdend;
276         libusb_context *ctx;
277         int i, j, k, ret;
278
279         ctx = NULL;
280         GET_CONTEXT(ctx);
281         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_max_packet_size enter");
282
283         if (dev == NULL)
284                 return (LIBUSB_ERROR_NO_DEVICE);
285
286         if (libusb_get_active_config_descriptor(dev, &pdconf) < 0) 
287                 return (LIBUSB_ERROR_OTHER);
288  
289         ret = LIBUSB_ERROR_NOT_FOUND;
290         for (i = 0 ; i < pdconf->bNumInterfaces ; i++) {
291                 pinf = &pdconf->interface[i];
292                 for (j = 0 ; j < pinf->num_altsetting ; j++) {
293                         pdinf = &pinf->altsetting[j];
294                         for (k = 0 ; k < pdinf->bNumEndpoints ; k++) {
295                                 pdend = &pdinf->endpoint[k];
296                                 if (pdend->bEndpointAddress == endpoint) {
297                                         ret = pdend->wMaxPacketSize;
298                                         goto out;
299                                 }
300                         }
301                 }
302         }
303
304 out:
305         libusb_free_config_descriptor(pdconf);
306         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_max_packet_size leave");
307         return (ret);
308 }
309
310 libusb_device *
311 libusb_ref_device(libusb_device * dev)
312 {
313         libusb_context *ctx;
314
315         ctx = NULL;
316         GET_CONTEXT(ctx);
317         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_ref_device enter");
318
319         if (dev == NULL)
320                 return (NULL);
321
322         pthread_mutex_lock(&dev->lock);
323         dev->refcnt++;
324         pthread_mutex_unlock(&dev->lock);
325
326         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_ref_device leave");
327         return (dev);
328 }
329
330 void
331 libusb_unref_device(libusb_device * dev)
332 {
333         libusb_context *ctx;
334
335         ctx = NULL;
336         GET_CONTEXT(ctx);
337         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_unref_device enter");
338
339         if (dev == NULL)
340                 return;
341
342         pthread_mutex_lock(&dev->lock);
343         dev->refcnt--;
344         pthread_mutex_unlock(&dev->lock);
345
346         if (dev->refcnt == 0) {
347                 pthread_mutex_lock(&dev->ctx->usb_devs_lock);
348                 TAILQ_REMOVE(&ctx->usb_devs, dev, list);
349                 pthread_mutex_unlock(&dev->ctx->usb_devs_lock);
350
351                 libusb20_dev_free(dev->os_priv);
352                 free(dev);
353         }
354         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_unref_device leave");
355 }
356
357 int
358 libusb_open(libusb_device * dev, libusb_device_handle **devh)
359 {
360         libusb_context *ctx = dev->ctx;
361         struct libusb20_device *pdev = dev->os_priv;
362         libusb_device_handle *hdl;
363         unsigned char dummy;
364         int err;
365
366         GET_CONTEXT(ctx);
367         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open enter");
368
369         dummy = 1;
370         if (devh == NULL)
371                 return (LIBUSB_ERROR_INVALID_PARAM);
372
373         hdl = malloc(sizeof(*hdl));
374         if (hdl == NULL)
375                 return (LIBUSB_ERROR_NO_MEM);
376
377         err = libusb20_dev_open(pdev, 16 * 4 /* number of endpoints */ );
378         if (err) {
379                 free(hdl);
380                 return (LIBUSB_ERROR_NO_MEM);
381         }
382         memset(hdl, 0, sizeof(*hdl));
383         pthread_mutex_init(&hdl->lock, NULL);
384
385         TAILQ_INIT(&hdl->ep_list);
386         hdl->dev = libusb_ref_device(dev);
387         hdl->claimed_interfaces = 0;
388         hdl->os_priv = dev->os_priv;
389         err = usb_add_pollfd(ctx, libusb20_dev_get_fd(pdev), POLLIN |
390             POLLOUT | POLLRDNORM | POLLWRNORM);
391         if (err < 0) {
392                 libusb_unref_device(dev);
393                 free(hdl);
394                 return (err);
395         }
396
397         pthread_mutex_lock(&ctx->open_devs_lock);
398         TAILQ_INSERT_HEAD(&ctx->open_devs, hdl, list);
399         pthread_mutex_unlock(&ctx->open_devs_lock);
400
401         *devh = hdl;
402
403         pthread_mutex_lock(&ctx->pollfd_modify_lock);
404         ctx->pollfd_modify++;
405         pthread_mutex_unlock(&ctx->pollfd_modify_lock); 
406
407         err = write(ctx->ctrl_pipe[1], &dummy, sizeof(dummy));
408         if (err <= 0) {
409                 pthread_mutex_lock(&ctx->pollfd_modify_lock);
410                 ctx->pollfd_modify--;
411                 pthread_mutex_unlock(&ctx->pollfd_modify_lock);
412                 return 0;
413         }
414
415         libusb_lock_events(ctx);
416         read(ctx->ctrl_pipe[0], &dummy, sizeof(dummy));
417         pthread_mutex_lock(&ctx->pollfd_modify_lock);
418         ctx->pollfd_modify--;
419         pthread_mutex_unlock(&ctx->pollfd_modify_lock);
420         libusb_unlock_events(ctx);
421
422         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open leave");
423         return (0);
424 }
425
426 libusb_device_handle *
427 libusb_open_device_with_vid_pid(libusb_context * ctx, uint16_t vendor_id,
428     uint16_t product_id)
429 {
430         struct libusb_device **devs;
431         struct libusb_device_handle *devh;
432         struct libusb20_device *pdev;
433         struct LIBUSB20_DEVICE_DESC_DECODED *pdesc;
434         int i, j;
435
436         GET_CONTEXT(ctx);
437         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open_device_width_vid_pid enter");
438
439         devh = NULL;
440
441         if ((i = libusb_get_device_list(ctx, &devs)) < 0)
442                 return (NULL);
443
444         for (j = 0; j < i; j++) {
445                 pdev = (struct libusb20_device *)devs[j]->os_priv;
446                 pdesc = libusb20_dev_get_device_desc(pdev);
447                 if (pdesc->idVendor == vendor_id &&
448                     pdesc->idProduct == product_id) {
449                         if (libusb_open(devs[j], &devh) < 0)
450                                 devh = NULL;
451                         break ;
452                 }
453         }
454
455         libusb_free_device_list(devs, 1);
456         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open_device_width_vid_pid leave");
457         return (devh);
458 }
459
460 void
461 libusb_close(libusb_device_handle * devh)
462 {
463         libusb_context *ctx;
464         struct libusb20_device *pdev;
465         struct usb_ep_tr *eptr;
466         unsigned char dummy = 1;
467         int err;
468
469         if (devh == NULL)
470                 return ;
471
472         ctx = devh->dev->ctx;
473         pdev = devh->os_priv;
474
475         GET_CONTEXT(ctx);
476         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_close enter");
477
478         pthread_mutex_lock(&ctx->pollfd_modify_lock);
479         ctx->pollfd_modify++;
480         pthread_mutex_unlock(&ctx->pollfd_modify_lock);
481
482         err = write(ctx->ctrl_pipe[1], &dummy, sizeof(dummy));
483         
484         if (err <= 0) {
485                 pthread_mutex_lock(&ctx->open_devs_lock);
486                 TAILQ_REMOVE(&ctx->open_devs, devh, list);
487                 pthread_mutex_unlock(&ctx->open_devs_lock);
488
489                 usb_remove_pollfd(ctx, libusb20_dev_get_fd(pdev));
490                 libusb20_dev_close(pdev);
491                 libusb_unref_device(devh->dev);
492                 TAILQ_FOREACH(eptr, &devh->ep_list, list) {
493                         TAILQ_REMOVE(&devh->ep_list, eptr, list);
494                         libusb20_tr_close(((struct libusb20_transfer **)
495                             eptr->os_priv)[0]);
496                         if (eptr->flags)
497                                 libusb20_tr_close(((struct libusb20_transfer **)
498                                     eptr->os_priv)[1]);
499                         free((struct libusb20_transfer **)eptr->os_priv);
500                 }
501                 free(devh);
502
503                 pthread_mutex_lock(&ctx->pollfd_modify_lock);
504                 ctx->pollfd_modify--;
505                 pthread_mutex_unlock(&ctx->pollfd_modify_lock);
506                 return ;
507         }
508         libusb_lock_events(ctx);
509
510         read(ctx->ctrl_pipe[0], &dummy, sizeof(dummy));
511         pthread_mutex_lock(&ctx->open_devs_lock);
512         TAILQ_REMOVE(&ctx->open_devs, devh, list);
513         pthread_mutex_unlock(&ctx->open_devs_lock);
514
515         usb_remove_pollfd(ctx, libusb20_dev_get_fd(pdev));
516         libusb20_dev_close(pdev);
517         libusb_unref_device(devh->dev);
518         TAILQ_FOREACH(eptr, &devh->ep_list, list) {
519                 TAILQ_REMOVE(&devh->ep_list, eptr, list);
520                 libusb20_tr_close(((struct libusb20_transfer **)
521                     eptr->os_priv)[0]);
522                 if (eptr->flags)
523                         libusb20_tr_close(((struct libusb20_transfer **)
524                             eptr->os_priv)[1]);
525                 free((struct libusb20_transfer **)eptr->os_priv);
526         }
527         free(devh);
528
529         pthread_mutex_lock(&ctx->pollfd_modify_lock);
530         ctx->pollfd_modify--;
531         pthread_mutex_unlock(&ctx->pollfd_modify_lock);
532
533         libusb_unlock_events(ctx);
534         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_close leave");
535 }
536
537 libusb_device *
538 libusb_get_device(libusb_device_handle * devh)
539 {
540         libusb_context *ctx;
541
542         ctx = NULL;
543         GET_CONTEXT(ctx);
544         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device enter");
545
546         if (devh == NULL)
547                 return (NULL);
548
549         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device leave");
550         return (devh->dev);
551 }
552
553 int
554 libusb_get_configuration(libusb_device_handle * devh, int *config)
555 {
556         libusb_context *ctx;
557
558         ctx = NULL;
559         GET_CONTEXT(ctx);
560         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_configuration enter");
561
562         if (devh == NULL || config == NULL)
563                 return (LIBUSB_ERROR_INVALID_PARAM);
564
565         *config = libusb20_dev_get_config_index((struct libusb20_device *)
566             devh->dev->os_priv);
567
568         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_configuration leave");
569         return (0);
570 }
571
572 int
573 libusb_set_configuration(libusb_device_handle * devh, int configuration)
574 {
575         struct libusb20_device *pdev;
576         libusb_context *ctx;
577
578         ctx = NULL;
579         GET_CONTEXT(ctx);
580         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_set_configuration enter");
581
582         if (devh == NULL)
583                 return (LIBUSB_ERROR_INVALID_PARAM);
584
585         pdev = (struct libusb20_device *)devh->dev->os_priv;
586
587         libusb20_dev_set_config_index(pdev, configuration);
588         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_set_configuration leave");
589         return (0);
590 }
591
592 int
593 libusb_claim_interface(libusb_device_handle * dev, int interface_number)
594 {
595         libusb_context *ctx;
596         int ret = 0;
597
598         ctx = NULL;
599         GET_CONTEXT(ctx);
600         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_claim_interface enter");
601
602         if (dev == NULL)
603                 return (LIBUSB_ERROR_INVALID_PARAM);
604
605         if (interface_number >= sizeof(dev->claimed_interfaces) * 8)
606                 return (LIBUSB_ERROR_INVALID_PARAM);
607
608         pthread_mutex_lock(&(dev->lock));
609         if (dev->claimed_interfaces & (1 << interface_number))
610                 ret = LIBUSB_ERROR_BUSY;
611
612         if (!ret)
613                 dev->claimed_interfaces |= (1 << interface_number);
614         pthread_mutex_unlock(&(dev->lock));
615
616         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_claim_interface leave");
617         return (ret);
618 }
619
620 int
621 libusb_release_interface(libusb_device_handle * dev, int interface_number)
622 {
623         libusb_context *ctx;
624         int ret;
625
626         ctx = NULL;
627         GET_CONTEXT(ctx);
628         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_release_interface enter");
629
630         ret = 0;
631         if (dev == NULL)
632                 return (LIBUSB_ERROR_INVALID_PARAM);
633
634         if (interface_number >= sizeof(dev->claimed_interfaces) * 8)
635                 return (LIBUSB_ERROR_INVALID_PARAM);
636
637         pthread_mutex_lock(&(dev->lock));
638         if (!(dev->claimed_interfaces & (1 << interface_number)))
639                 ret = LIBUSB_ERROR_NOT_FOUND;
640
641         if (!ret)
642                 dev->claimed_interfaces &= ~(1 << interface_number);
643         pthread_mutex_unlock(&(dev->lock));
644
645         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_release_interface leave");
646         return (ret);
647 }
648
649 int
650 libusb_set_interface_alt_setting(libusb_device_handle * dev,
651     int interface_number, int alternate_setting)
652 {
653         libusb_context *ctx;
654
655         ctx = NULL;
656         GET_CONTEXT(ctx);
657         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_set_interface_alt_setting enter");
658
659         if (dev == NULL)
660                 return (LIBUSB_ERROR_INVALID_PARAM);
661
662         if (interface_number >= sizeof(dev->claimed_interfaces) *8)
663                 return (LIBUSB_ERROR_INVALID_PARAM);
664
665         pthread_mutex_lock(&dev->lock);
666         if (!(dev->claimed_interfaces & (1 << interface_number))) {
667                 pthread_mutex_unlock(&dev->lock);
668                 return (LIBUSB_ERROR_NOT_FOUND);
669         }
670         pthread_mutex_unlock(&dev->lock);
671
672         if (libusb20_dev_set_alt_index(dev->os_priv, interface_number,
673             alternate_setting) != 0)
674                 return (LIBUSB_ERROR_OTHER);
675         
676         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_set_interface_alt_setting leave");
677         return (0);
678 }
679
680 int
681 libusb_clear_halt(libusb_device_handle * devh, unsigned char endpoint)
682 {
683         struct libusb20_transfer *xfer;
684         struct libusb20_device *pdev;
685         libusb_context *ctx;
686         int ret; 
687
688         ctx = NULL;
689         GET_CONTEXT(ctx);
690         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_clear_halt enter");
691         
692         pdev = devh->os_priv;
693         xfer = libusb20_tr_get_pointer(pdev, 
694             ((endpoint / 0x40) | (endpoint * 4)) % (16 * 4));
695         if (xfer == NULL)
696                 return (LIBUSB_ERROR_NO_MEM);
697
698         pthread_mutex_lock(&libusb20_lock);
699         ret = libusb20_tr_open(xfer, 0, 0, endpoint);
700         if (ret != 0 && ret != LIBUSB20_ERROR_BUSY) {
701                 pthread_mutex_unlock(&libusb20_lock);
702                 return (LIBUSB_ERROR_OTHER);
703         }
704
705         libusb20_tr_clear_stall_sync(xfer);
706         if (ret == 0) /* check if we have open the device */
707                 libusb20_tr_close(xfer);
708         pthread_mutex_unlock(&libusb20_lock);
709
710         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_clear_halt leave");
711         return (0);
712 }
713
714 int
715 libusb_reset_device(libusb_device_handle * dev)
716 {
717         libusb_context *ctx;
718
719         ctx = NULL;
720         GET_CONTEXT(ctx);
721         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_reset_device enter");
722
723         if (dev == NULL)
724                 return (LIBUSB20_ERROR_INVALID_PARAM);
725
726         libusb20_dev_reset(dev->os_priv);
727         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_reset_device leave");
728         return (0);
729 }
730
731 int
732 libusb_kernel_driver_active(libusb_device_handle * devh, int interface)
733 {
734         libusb_context *ctx;
735
736         ctx = NULL;
737         GET_CONTEXT(ctx);
738         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_kernel_driver_active enter");
739
740         if (devh == NULL)
741                 return (LIBUSB_ERROR_INVALID_PARAM);
742
743         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_kernel_driver_active leave");
744         return (libusb20_dev_kernel_driver_active(devh->os_priv, interface));
745 }
746
747 int
748 libusb_detach_kernel_driver(libusb_device_handle * devh, int interface)
749 {
750         struct libusb20_device *pdev;
751         libusb_context *ctx;
752
753         ctx = NULL;
754         GET_CONTEXT(ctx);
755         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_detach_kernel_driver enter");
756
757         if (devh == NULL)
758                 return (LIBUSB_ERROR_INVALID_PARAM);
759
760         pdev = (struct libusb20_device *)devh->dev->os_priv;
761         if (libusb20_dev_detach_kernel_driver(pdev, interface) == LIBUSB20_ERROR_OTHER)
762                 return (LIBUSB_ERROR_OTHER);
763
764         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_detach_kernel_driver leave");
765         return (0);
766 }
767
768 /* 
769  * stub function.
770  * libusb20 doesn't support this feature.
771  */
772 int
773 libusb_attach_kernel_driver(libusb_device_handle * devh, int interface)
774 {
775         libusb_context *ctx;
776
777         ctx = NULL;
778         GET_CONTEXT(ctx);
779         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_attach_kernel_driver enter");
780
781         if (devh == NULL)
782                 return (LIBUSB_ERROR_INVALID_PARAM);
783
784         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_attach_kernel_driver leave");
785         return (0);
786 }
787
788 /* Asynchronous device I/O */
789
790 struct libusb_transfer *
791 libusb_alloc_transfer(int iso_packets)
792 {
793         struct libusb_transfer *xfer;
794         struct usb_transfer *bxfer;
795         libusb_context *ctx;
796         int len;
797
798         ctx = NULL;
799         GET_CONTEXT(ctx);
800         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_alloc_transfer enter");
801
802         len = sizeof(struct libusb_transfer) +
803             sizeof(struct usb_transfer) +
804             (iso_packets * sizeof(libusb_iso_packet_descriptor));
805
806         bxfer = malloc(len);
807         if (bxfer == NULL)
808                 return (NULL);
809
810         memset(bxfer, 0, len);
811         bxfer->num_iso_packets = iso_packets;
812
813         xfer = (struct libusb_transfer *) ((uint8_t *)bxfer + 
814             sizeof(struct usb_transfer));
815
816         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_alloc_transfer leave");
817         return (xfer);
818 }
819
820 void
821 libusb_free_transfer(struct libusb_transfer *xfer)
822 {
823         struct usb_transfer *bxfer;
824         libusb_context *ctx;
825
826         ctx = NULL;
827         GET_CONTEXT(ctx);
828         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_free_transfer enter");
829
830         if (xfer == NULL)
831                 return ;
832
833         bxfer = (struct usb_transfer *) ((uint8_t *)xfer - 
834             sizeof(struct usb_transfer));
835
836         free(bxfer);
837         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_free_transfer leave");
838         return;
839 }
840
841 static int
842 libusb_get_maxframe(struct libusb20_device *pdev, libusb_transfer *xfer)
843 {
844         int ret;
845         int usb_speed;
846
847         usb_speed = libusb20_dev_get_speed(pdev);
848
849         switch (xfer->type) {
850         case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
851                 switch (usb_speed) {
852                 case LIBUSB20_SPEED_LOW:
853                 case LIBUSB20_SPEED_FULL:
854                         ret = 60 * 1;
855                         break ;
856                 default :
857                         ret = 60 * 8;
858                         break ;
859                 }
860                 break ;
861         case LIBUSB_TRANSFER_TYPE_CONTROL:
862                 ret = 2;
863                 break ;
864         default:
865                 ret = 1;
866                 break ;
867         }
868
869         return ret;
870 }
871
872 static int
873 libusb_get_buffsize(struct libusb20_device *pdev, libusb_transfer *xfer)
874 {
875         int ret;
876         int usb_speed;
877
878         usb_speed = libusb20_dev_get_speed(pdev);
879
880         switch (xfer->type) {
881         case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
882                 ret = 0;
883                 break ;
884         case LIBUSB_TRANSFER_TYPE_CONTROL:
885                 switch (usb_speed) {
886                         case LIBUSB20_SPEED_LOW:
887                                 ret = 8;
888                                 break ;
889                         case LIBUSB20_SPEED_FULL:
890                                 ret = 64;
891                                 break ;
892                         default:
893                                 ret = 64;
894                                 break ;
895                 }
896                 ret += 8;
897                 break ;
898         default :
899                 switch (usb_speed) {
900                         case LIBUSB20_SPEED_LOW:
901                                 ret = 256;
902                                 break ;
903                         case LIBUSB20_SPEED_FULL:
904                                 ret = 4096;
905                                 break ;
906                         default:
907                                 ret = 16384;
908                                 break ;
909                 }
910                 break ;
911         }
912         
913         return ret;
914 }
915
916 static void
917 libusb10_proxy(struct libusb20_transfer *xfer)
918 {
919         struct usb_transfer *usb_backend;
920         struct libusb20_device *pdev;
921         libusb_transfer *usb_xfer;
922         libusb_context *ctx;
923         uint32_t pos;
924         uint32_t max;
925         uint32_t size;
926         uint8_t status;
927         uint32_t iso_packets;
928         int i;
929
930         status = libusb20_tr_get_status(xfer);
931         usb_xfer = libusb20_tr_get_priv_sc0(xfer);
932         usb_backend = (struct usb_transfer *) ((uint8_t *)usb_xfer - 
933             sizeof(struct usb_transfer));
934         pdev = usb_xfer->dev_handle->dev->os_priv;
935         ctx = usb_xfer->dev_handle->dev->ctx;
936         GET_CONTEXT(ctx);
937
938         switch (status) {
939         case LIBUSB20_TRANSFER_COMPLETED:
940                 usb_backend->transferred += libusb20_tr_get_actual_length(xfer);
941                 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "LIBUSB20 TRANSFER %i bytes",
942                     usb_backend->transferred);
943                 if (usb_backend->transferred != usb_xfer->length)
944                         goto tr_start;
945
946                 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "LIBUSB20 TRANSFER COMPLETE");
947                 usb_handle_transfer_completion(usb_backend, LIBUSB_TRANSFER_COMPLETED);
948
949                 break ;
950         case LIBUSB20_TRANSFER_START:
951 tr_start:
952                 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "LIBUSB20 START");
953                 max = libusb_get_buffsize(pdev, usb_xfer);
954                 pos = usb_backend->transferred;
955                 size = (usb_xfer->length - pos);
956                 size = (size > max) ? max : size;
957                 usb_xfer->actual_length = 0;
958                 switch (usb_xfer->type) {
959                         case LIBUSB_TRANSFER_TYPE_CONTROL:
960                                 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "TYPE CTR");
961                                 libusb20_tr_setup_control(xfer, usb_xfer->buffer,
962                                     (void *)(((uint8_t *) &usb_xfer->buffer[pos]) + 
963                                     sizeof(libusb_control_setup)), 
964                                     usb_xfer->timeout);
965                                 break ;
966                         case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
967                                 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "TYPE ISO");
968                                 iso_packets = libusb20_tr_get_max_frames(xfer);
969                                 if (usb_xfer->num_iso_packets > iso_packets)
970                                         usb_xfer->num_iso_packets = iso_packets;
971                                 for (i = 0 ; i < usb_xfer->num_iso_packets ; i++) {
972                                         libusb20_tr_setup_isoc(xfer, 
973                                             &usb_xfer->buffer[pos], size, i);
974                                 }
975                                 libusb20_tr_set_total_frames(xfer, i);
976                                 break ;
977                         case LIBUSB_TRANSFER_TYPE_BULK:
978                                 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "TYPE BULK");
979                                 libusb20_tr_setup_bulk(xfer, &usb_xfer->buffer[pos],
980                                     size, usb_xfer->timeout);
981                                 break ;
982                         case LIBUSB_TRANSFER_TYPE_INTERRUPT:
983                                 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "TYPE INTR");
984                                 libusb20_tr_setup_intr(xfer, &usb_xfer->buffer[pos],
985                                     size, usb_xfer->timeout);
986                                 break ;
987                 }
988                 libusb20_tr_submit(xfer);
989                 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "LIBUSB20 SUBMITED");
990                 break ;
991         default:
992                 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "TRANSFER DEFAULT 0x%x\n", 
993                     status);
994                 usb_backend->transferred = 0;
995                 usb_handle_transfer_completion(usb_backend, LIBUSB_TRANSFER_CANCELLED);
996                 break ;
997         }
998
999         switch (status) {
1000         case LIBUSB20_TRANSFER_COMPLETED:
1001                 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS COMPLETED");
1002                 usb_xfer->status = LIBUSB_TRANSFER_COMPLETED;
1003                 break ;
1004         case LIBUSB20_TRANSFER_OVERFLOW:
1005                 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS TR OVERFLOW");
1006                 usb_xfer->status = LIBUSB_TRANSFER_OVERFLOW;
1007                 break ;
1008         case LIBUSB20_TRANSFER_NO_DEVICE:
1009                 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS TR NO DEVICE");
1010                 usb_xfer->status = LIBUSB_TRANSFER_NO_DEVICE;
1011                 break ;
1012         case LIBUSB20_TRANSFER_STALL:
1013                 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS TR STALL");
1014                 usb_xfer->status = LIBUSB_TRANSFER_STALL;
1015                 break ;
1016         case LIBUSB20_TRANSFER_CANCELLED:
1017                 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS TR CANCELLED");
1018                 usb_xfer->status = LIBUSB_TRANSFER_CANCELLED;
1019                 break ;
1020         case LIBUSB20_TRANSFER_TIMED_OUT:
1021                 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS TR TIMEOUT");
1022                 usb_xfer->status = LIBUSB_TRANSFER_TIMED_OUT;
1023                 break ;
1024         case LIBUSB20_TRANSFER_ERROR:
1025                 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "ERROR");
1026                 usb_xfer->status = LIBUSB_TRANSFER_ERROR;
1027                 break ;
1028         }
1029 }
1030
1031 int
1032 libusb_submit_transfer(struct libusb_transfer *xfer)
1033 {
1034         struct libusb20_transfer **usb20_xfer;
1035         struct usb_transfer *usb_backend;
1036         struct usb_transfer *usb_node;
1037         struct libusb20_device *pdev;
1038         struct usb_ep_tr *eptr;
1039         struct timespec cur_ts;
1040         struct timeval *cur_tv;
1041         libusb_device_handle *devh;
1042         libusb_context *ctx;
1043         int maxframe;
1044         int buffsize;
1045         int ep_idx;
1046         int ret;
1047
1048         if (xfer == NULL)
1049                 return (LIBUSB_ERROR_NO_MEM);
1050
1051         usb20_xfer = malloc(2 * sizeof(struct libusb20_transfer *));
1052         if (usb20_xfer == NULL)
1053                 return (LIBUSB_ERROR_NO_MEM);
1054
1055         ctx = xfer->dev_handle->dev->ctx;
1056         pdev = xfer->dev_handle->os_priv;
1057         devh = xfer->dev_handle;
1058
1059         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_submit_transfer enter");
1060
1061         usb_backend = (struct usb_transfer *) ((uint8_t *)xfer - 
1062             sizeof(struct usb_transfer));
1063         usb_backend->transferred = 0;
1064         usb_backend->flags = 0;
1065
1066         if (xfer->timeout != 0) {
1067                 clock_gettime(CLOCK_MONOTONIC, &cur_ts);
1068                 cur_ts.tv_sec += xfer->timeout / 1000;
1069                 cur_ts.tv_nsec += (xfer->timeout % 1000) * 1000000;
1070                 
1071                 if (cur_ts.tv_nsec > 1000000000) {
1072                         cur_ts.tv_nsec -= 1000000000;
1073                         cur_ts.tv_sec++;
1074                 }
1075                 
1076                 TIMESPEC_TO_TIMEVAL(&usb_backend->timeout, &cur_ts);
1077         } 
1078
1079         /*Add to flying list*/
1080         pthread_mutex_lock(&ctx->flying_transfers_lock);
1081         if (TAILQ_EMPTY(&ctx->flying_transfers)) {
1082                 TAILQ_INSERT_HEAD(&ctx->flying_transfers, usb_backend, list);
1083                 goto out;
1084         }
1085         if (timerisset(&usb_backend->timeout) == 0) {
1086                 TAILQ_INSERT_HEAD(&ctx->flying_transfers, usb_backend, list);
1087                 goto out;
1088         }
1089         TAILQ_FOREACH(usb_node, &ctx->flying_transfers, list) {
1090                 cur_tv = &usb_node->timeout;
1091                 if (timerisset(cur_tv) == 0 || 
1092                     (cur_tv->tv_sec > usb_backend->timeout.tv_sec) ||
1093                     (cur_tv->tv_sec == usb_backend->timeout.tv_sec &&
1094                     cur_tv->tv_usec > usb_backend->timeout.tv_usec)) {
1095                         TAILQ_INSERT_TAIL(&ctx->flying_transfers, usb_backend, list);
1096                         goto out;
1097                 }
1098         }       
1099         TAILQ_INSERT_TAIL(&ctx->flying_transfers, usb_backend, list);
1100
1101 out:
1102         pthread_mutex_unlock(&ctx->flying_transfers_lock);
1103
1104         ep_idx = (xfer->endpoint / 0x40) | (xfer->endpoint * 4) % (16 * 4);
1105         usb20_xfer[0] = libusb20_tr_get_pointer(pdev, ep_idx);
1106         usb20_xfer[1] = libusb20_tr_get_pointer(pdev, ep_idx + 1);
1107         
1108         if (usb20_xfer[0] == NULL)
1109                 return (LIBUSB_ERROR_OTHER);
1110
1111         xfer->os_priv = usb20_xfer;
1112
1113         pthread_mutex_lock(&libusb20_lock);
1114
1115         buffsize = libusb_get_buffsize(pdev, xfer);
1116         maxframe = libusb_get_maxframe(pdev, xfer);
1117         
1118         ret = 0;
1119         TAILQ_FOREACH(eptr, &devh->ep_list, list) {
1120                 if (xfer->endpoint == eptr->addr)
1121                         ret++;
1122         }
1123         if (ret == 0) {
1124                 eptr = malloc(sizeof(struct usb_ep_tr));
1125                 eptr->addr = xfer->endpoint;
1126                 eptr->idx = ep_idx;
1127                 eptr->os_priv = usb20_xfer;
1128                 eptr->flags = (xfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS)?1:0; 
1129                 TAILQ_INSERT_HEAD(&devh->ep_list, eptr, list);
1130                 ret = libusb20_tr_open(usb20_xfer[0], buffsize, 
1131                         maxframe, xfer->endpoint);
1132                 if (xfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS)
1133                         ret |= libusb20_tr_open(usb20_xfer[1], buffsize,
1134                         maxframe, xfer->endpoint);
1135        
1136                 if (ret != 0) {
1137                         pthread_mutex_unlock(&libusb20_lock);
1138                         pthread_mutex_lock(&ctx->flying_transfers_lock);
1139                         TAILQ_REMOVE(&ctx->flying_transfers, usb_backend, list);
1140                         pthread_mutex_unlock(&ctx->flying_transfers_lock);
1141                         return (LIBUSB_ERROR_OTHER);
1142                 }
1143         }
1144
1145         libusb20_tr_set_priv_sc0(usb20_xfer[0], xfer);
1146         libusb20_tr_set_callback(usb20_xfer[0], libusb10_proxy);
1147         if (xfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) {
1148                 libusb20_tr_set_priv_sc0(usb20_xfer[1], xfer);
1149                 libusb20_tr_set_callback(usb20_xfer[1], libusb10_proxy);
1150         }       
1151
1152         DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "LIBUSB20_TR_START");
1153         libusb20_tr_start(usb20_xfer[0]);
1154         if (xfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) 
1155                 libusb20_tr_start(usb20_xfer[1]);
1156
1157         pthread_mutex_unlock(&libusb20_lock);
1158
1159         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_submit_transfer leave");
1160         return (0);
1161 }
1162
1163 int
1164 libusb_cancel_transfer(struct libusb_transfer *xfer)
1165 {
1166         libusb_context *ctx;
1167
1168         ctx = NULL;
1169         GET_CONTEXT(ctx);
1170         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_cancel_transfer enter");
1171
1172         if (xfer == NULL)
1173                 return (LIBUSB_ERROR_NO_MEM);
1174
1175         pthread_mutex_lock(&libusb20_lock);
1176         libusb20_tr_stop(xfer->os_priv);
1177         pthread_mutex_unlock(&libusb20_lock);
1178
1179         DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_cancel_transfer leave");
1180         return (0);
1181 }
1182