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