1/* $FreeBSD: stable/11/lib/libusb/libusb10_io.c 339189 2018-10-05 07:49:01Z 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 50UNEXPORTED void 51libusb10_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 75UNEXPORTED void 76libusb10_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 95static int 96libusb10_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 = libusb20_dev_process(ppdev[i]); 164 165 if (err) { 166 /* set device is gone */ 167 dev->device_is_gone = 1; 168 169 /* remove USB device from polling loop */ 170 libusb10_remove_pollfd(dev->ctx, &dev->dev_poll); 171 172 /* cancel all pending transfers */ 173 libusb10_cancel_all_transfer_locked(ppdev[i], dev); 174 } 175 } 176 CTX_UNLOCK(ctx); 177 libusb_unref_device(dev); 178 CTX_LOCK(ctx); 179 180 } else { 181 uint8_t dummy; 182 183 while (read(fds[i].fd, &dummy, 1) == 1) 184 ; 185 } 186 } 187 188 err = 0; 189 190do_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 231int 232libusb_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 253void 254libusb_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 262void 263libusb_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 273int 274libusb_event_handling_ok(libusb_context *ctx) 275{ 276 ctx = GET_CONTEXT(ctx); 277 return (ctx->ctx_handler == pthread_self()); 278} 279 280int 281libusb_event_handler_active(libusb_context *ctx) 282{ 283 ctx = GET_CONTEXT(ctx); 284 return (ctx->ctx_handler != NO_THREAD); 285} 286 287void 288libusb_lock_event_waiters(libusb_context *ctx) 289{ 290 ctx = GET_CONTEXT(ctx); 291 CTX_LOCK(ctx); 292} 293 294void 295libusb_unlock_event_waiters(libusb_context *ctx) 296{ 297 ctx = GET_CONTEXT(ctx); 298 CTX_UNLOCK(ctx); 299} 300 301int 302libusb_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 /* try to grab polling of actual events, if any */ 314 if (ctx->ctx_handler == NO_THREAD) 315 ctx->ctx_handler = pthread_self(); 316 return (0); 317 } 318 err = clock_gettime(CLOCK_MONOTONIC, &ts); 319 if (err < 0) 320 return (LIBUSB_ERROR_OTHER); 321 322 /* 323 * The "tv" arguments points to a relative time structure and 324 * not an absolute time structure. 325 */ 326 ts.tv_sec += tv->tv_sec; 327 ts.tv_nsec += tv->tv_usec * 1000; 328 if (ts.tv_nsec >= 1000000000) { 329 ts.tv_nsec -= 1000000000; 330 ts.tv_sec++; 331 } 332 err = pthread_cond_timedwait(&ctx->ctx_cond, 333 &ctx->ctx_lock, &ts); 334 /* try to grab polling of actual events, if any */ 335 if (ctx->ctx_handler == NO_THREAD) 336 ctx->ctx_handler = pthread_self(); 337 338 if (err == ETIMEDOUT) 339 return (1); 340 341 return (0); 342} 343 344int 345libusb_handle_events_timeout_completed(libusb_context *ctx, 346 struct timeval *tv, int *completed) 347{ 348 int err = 0; 349 350 ctx = GET_CONTEXT(ctx); 351 352 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_handle_events_timeout_completed enter"); 353 354 libusb_lock_events(ctx); 355 356 while (1) { 357 if (completed != NULL) { 358 if (*completed != 0 || err != 0) 359 break; 360 } 361 err = libusb_handle_events_locked(ctx, tv); 362 if (completed == NULL) 363 break; 364 } 365 366 libusb_unlock_events(ctx); 367 368 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_handle_events_timeout_completed exit"); 369 370 return (err); 371} 372 373int 374libusb_handle_events_completed(libusb_context *ctx, int *completed) 375{ 376 return (libusb_handle_events_timeout_completed(ctx, NULL, completed)); 377} 378 379int 380libusb_handle_events_timeout(libusb_context *ctx, struct timeval *tv) 381{ 382 return (libusb_handle_events_timeout_completed(ctx, tv, NULL)); 383} 384 385int 386libusb_handle_events(libusb_context *ctx) 387{ 388 return (libusb_handle_events_timeout_completed(ctx, NULL, NULL)); 389} 390 391int 392libusb_handle_events_locked(libusb_context *ctx, struct timeval *tv) 393{ 394 int err; 395 396 ctx = GET_CONTEXT(ctx); 397 398 if (libusb_event_handling_ok(ctx)) { 399 err = libusb10_handle_events_sub(ctx, tv); 400 } else { 401 err = libusb_wait_for_event(ctx, tv); 402 if (err != 0) 403 err = LIBUSB_ERROR_TIMEOUT; 404 } 405 return (err); 406} 407 408int 409libusb_get_next_timeout(libusb_context *ctx, struct timeval *tv) 410{ 411 /* all timeouts are currently being done by the kernel */ 412 timerclear(tv); 413 return (0); 414} 415 416void 417libusb_set_pollfd_notifiers(libusb_context *ctx, 418 libusb_pollfd_added_cb added_cb, libusb_pollfd_removed_cb removed_cb, 419 void *user_data) 420{ 421 ctx = GET_CONTEXT(ctx); 422 423 ctx->fd_added_cb = added_cb; 424 ctx->fd_removed_cb = removed_cb; 425 ctx->fd_cb_user_data = user_data; 426} 427 428const struct libusb_pollfd ** 429libusb_get_pollfds(libusb_context *ctx) 430{ 431 struct libusb_super_pollfd *pollfd; 432 libusb_pollfd **ret; 433 int i; 434 435 ctx = GET_CONTEXT(ctx); 436 437 CTX_LOCK(ctx); 438 439 i = 0; 440 TAILQ_FOREACH(pollfd, &ctx->pollfds, entry) 441 i++; 442 443 ret = calloc(i + 1, sizeof(struct libusb_pollfd *)); 444 if (ret == NULL) 445 goto done; 446 447 i = 0; 448 TAILQ_FOREACH(pollfd, &ctx->pollfds, entry) 449 ret[i++] = &pollfd->pollfd; 450 ret[i] = NULL; 451 452done: 453 CTX_UNLOCK(ctx); 454 return ((const struct libusb_pollfd **)ret); 455} 456 457 458/* Synchronous device I/O */ 459 460int 461libusb_control_transfer(libusb_device_handle *devh, 462 uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, 463 uint8_t *data, uint16_t wLength, unsigned int timeout) 464{ 465 struct LIBUSB20_CONTROL_SETUP_DECODED req; 466 int err; 467 uint16_t actlen; 468 469 if (devh == NULL) 470 return (LIBUSB_ERROR_INVALID_PARAM); 471 472 if ((wLength != 0) && (data == NULL)) 473 return (LIBUSB_ERROR_INVALID_PARAM); 474 475 LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &req); 476 477 req.bmRequestType = bmRequestType; 478 req.bRequest = bRequest; 479 req.wValue = wValue; 480 req.wIndex = wIndex; 481 req.wLength = wLength; 482 483 err = libusb20_dev_request_sync(devh, &req, data, 484 &actlen, timeout, 0); 485 486 if (err == LIBUSB20_ERROR_PIPE) 487 return (LIBUSB_ERROR_PIPE); 488 else if (err == LIBUSB20_ERROR_TIMEOUT) 489 return (LIBUSB_ERROR_TIMEOUT); 490 else if (err) 491 return (LIBUSB_ERROR_NO_DEVICE); 492 493 return (actlen); 494} 495 496static libusb_context * 497libusb10_get_context_by_device_handle(libusb_device_handle *devh) 498{ 499 libusb_context *ctx; 500 501 if (devh != NULL) 502 ctx = libusb_get_device(devh)->ctx; 503 else 504 ctx = NULL; 505 506 return (GET_CONTEXT(ctx)); 507} 508 509static void 510libusb10_do_transfer_cb(struct libusb_transfer *transfer) 511{ 512 libusb_context *ctx; 513 int *pdone; 514 515 ctx = libusb10_get_context_by_device_handle(transfer->dev_handle); 516 517 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "sync I/O done"); 518 519 pdone = transfer->user_data; 520 *pdone = 1; 521} 522 523/* 524 * TODO: Replace the following function. Allocating and freeing on a 525 * per-transfer basis is slow. --HPS 526 */ 527static int 528libusb10_do_transfer(libusb_device_handle *devh, 529 uint8_t endpoint, uint8_t *data, int length, 530 int *transferred, unsigned int timeout, int type) 531{ 532 libusb_context *ctx; 533 struct libusb_transfer *xfer; 534 int done; 535 int ret; 536 537 if (devh == NULL) 538 return (LIBUSB_ERROR_INVALID_PARAM); 539 540 if ((length != 0) && (data == NULL)) 541 return (LIBUSB_ERROR_INVALID_PARAM); 542 543 xfer = libusb_alloc_transfer(0); 544 if (xfer == NULL) 545 return (LIBUSB_ERROR_NO_MEM); 546 547 ctx = libusb_get_device(devh)->ctx; 548 549 xfer->dev_handle = devh; 550 xfer->endpoint = endpoint; 551 xfer->type = type; 552 xfer->timeout = timeout; 553 xfer->buffer = data; 554 xfer->length = length; 555 xfer->user_data = (void *)&done; 556 xfer->callback = libusb10_do_transfer_cb; 557 done = 0; 558 559 if ((ret = libusb_submit_transfer(xfer)) < 0) { 560 libusb_free_transfer(xfer); 561 return (ret); 562 } 563 while (done == 0) { 564 if ((ret = libusb_handle_events(ctx)) < 0) { 565 libusb_cancel_transfer(xfer); 566 usleep(1000); /* nice it */ 567 } 568 } 569 570 *transferred = xfer->actual_length; 571 572 switch (xfer->status) { 573 case LIBUSB_TRANSFER_COMPLETED: 574 ret = 0; 575 break; 576 case LIBUSB_TRANSFER_TIMED_OUT: 577 ret = LIBUSB_ERROR_TIMEOUT; 578 break; 579 case LIBUSB_TRANSFER_OVERFLOW: 580 ret = LIBUSB_ERROR_OVERFLOW; 581 break; 582 case LIBUSB_TRANSFER_STALL: 583 ret = LIBUSB_ERROR_PIPE; 584 break; 585 case LIBUSB_TRANSFER_NO_DEVICE: 586 ret = LIBUSB_ERROR_NO_DEVICE; 587 break; 588 default: 589 ret = LIBUSB_ERROR_OTHER; 590 break; 591 } 592 593 libusb_free_transfer(xfer); 594 return (ret); 595} 596 597int 598libusb_bulk_transfer(libusb_device_handle *devh, 599 uint8_t endpoint, uint8_t *data, int length, 600 int *transferred, unsigned int timeout) 601{ 602 libusb_context *ctx; 603 int ret; 604 605 ctx = libusb10_get_context_by_device_handle(devh); 606 607 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_bulk_transfer enter"); 608 609 ret = libusb10_do_transfer(devh, endpoint, data, length, transferred, 610 timeout, LIBUSB_TRANSFER_TYPE_BULK); 611 612 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_bulk_transfer leave"); 613 return (ret); 614} 615 616int 617libusb_interrupt_transfer(libusb_device_handle *devh, 618 uint8_t endpoint, uint8_t *data, int length, 619 int *transferred, unsigned int timeout) 620{ 621 libusb_context *ctx; 622 int ret; 623 624 ctx = libusb10_get_context_by_device_handle(devh); 625 626 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_interrupt_transfer enter"); 627 628 ret = libusb10_do_transfer(devh, endpoint, data, length, transferred, 629 timeout, LIBUSB_TRANSFER_TYPE_INTERRUPT); 630 631 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_interrupt_transfer leave"); 632 return (ret); 633} 634 635uint8_t * 636libusb_get_iso_packet_buffer(struct libusb_transfer *transfer, uint32_t off) 637{ 638 uint8_t *ptr; 639 uint32_t n; 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 for (n = 0; n != off; n++) { 652 ptr += transfer->iso_packet_desc[n].length; 653 } 654 return (ptr); 655} 656 657uint8_t * 658libusb_get_iso_packet_buffer_simple(struct libusb_transfer *transfer, uint32_t off) 659{ 660 uint8_t *ptr; 661 662 if (transfer->num_iso_packets < 0) 663 return (NULL); 664 665 if (off >= (uint32_t)transfer->num_iso_packets) 666 return (NULL); 667 668 ptr = transfer->buffer; 669 if (ptr == NULL) 670 return (NULL); 671 672 ptr += transfer->iso_packet_desc[0].length * off; 673 674 return (ptr); 675} 676 677void 678libusb_set_iso_packet_lengths(struct libusb_transfer *transfer, uint32_t length) 679{ 680 int n; 681 682 if (transfer->num_iso_packets < 0) 683 return; 684 685 for (n = 0; n != transfer->num_iso_packets; n++) 686 transfer->iso_packet_desc[n].length = length; 687} 688 689uint8_t * 690libusb_control_transfer_get_data(struct libusb_transfer *transfer) 691{ 692 if (transfer->buffer == NULL) 693 return (NULL); 694 695 return (transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE); 696} 697 698struct libusb_control_setup * 699libusb_control_transfer_get_setup(struct libusb_transfer *transfer) 700{ 701 return ((struct libusb_control_setup *)transfer->buffer); 702} 703 704void 705libusb_fill_control_setup(uint8_t *buf, uint8_t bmRequestType, 706 uint8_t bRequest, uint16_t wValue, 707 uint16_t wIndex, uint16_t wLength) 708{ 709 struct libusb_control_setup *req = (struct libusb_control_setup *)buf; 710 711 /* The alignment is OK for all fields below. */ 712 req->bmRequestType = bmRequestType; 713 req->bRequest = bRequest; 714 req->wValue = htole16(wValue); 715 req->wIndex = htole16(wIndex); 716 req->wLength = htole16(wLength); 717} 718 719void 720libusb_fill_control_transfer(struct libusb_transfer *transfer, 721 libusb_device_handle *devh, uint8_t *buf, 722 libusb_transfer_cb_fn callback, void *user_data, 723 uint32_t timeout) 724{ 725 struct libusb_control_setup *setup = (struct libusb_control_setup *)buf; 726 727 transfer->dev_handle = devh; 728 transfer->endpoint = 0; 729 transfer->type = LIBUSB_TRANSFER_TYPE_CONTROL; 730 transfer->timeout = timeout; 731 transfer->buffer = buf; 732 if (setup != NULL) 733 transfer->length = LIBUSB_CONTROL_SETUP_SIZE 734 + le16toh(setup->wLength); 735 else 736 transfer->length = 0; 737 transfer->user_data = user_data; 738 transfer->callback = callback; 739 740} 741 742void 743libusb_fill_bulk_transfer(struct libusb_transfer *transfer, 744 libusb_device_handle *devh, uint8_t endpoint, uint8_t *buf, 745 int length, libusb_transfer_cb_fn callback, void *user_data, 746 uint32_t timeout) 747{ 748 transfer->dev_handle = devh; 749 transfer->endpoint = endpoint; 750 transfer->type = LIBUSB_TRANSFER_TYPE_BULK; 751 transfer->timeout = timeout; 752 transfer->buffer = buf; 753 transfer->length = length; 754 transfer->user_data = user_data; 755 transfer->callback = callback; 756} 757 758void 759libusb_fill_interrupt_transfer(struct libusb_transfer *transfer, 760 libusb_device_handle *devh, uint8_t endpoint, uint8_t *buf, 761 int length, libusb_transfer_cb_fn callback, void *user_data, 762 uint32_t timeout) 763{ 764 transfer->dev_handle = devh; 765 transfer->endpoint = endpoint; 766 transfer->type = LIBUSB_TRANSFER_TYPE_INTERRUPT; 767 transfer->timeout = timeout; 768 transfer->buffer = buf; 769 transfer->length = length; 770 transfer->user_data = user_data; 771 transfer->callback = callback; 772} 773 774void 775libusb_fill_iso_transfer(struct libusb_transfer *transfer, 776 libusb_device_handle *devh, uint8_t endpoint, uint8_t *buf, 777 int length, int npacket, libusb_transfer_cb_fn callback, 778 void *user_data, uint32_t timeout) 779{ 780 transfer->dev_handle = devh; 781 transfer->endpoint = endpoint; 782 transfer->type = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS; 783 transfer->timeout = timeout; 784 transfer->buffer = buf; 785 transfer->length = length; 786 transfer->num_iso_packets = npacket; 787 transfer->user_data = user_data; 788 transfer->callback = callback; 789} 790 791int 792libusb_alloc_streams(libusb_device_handle *dev, uint32_t num_streams, 793 unsigned char *endpoints, int num_endpoints) 794{ 795 if (num_streams > 1) 796 return (LIBUSB_ERROR_INVALID_PARAM); 797 return (0); 798} 799 800int 801libusb_free_streams(libusb_device_handle *dev, unsigned char *endpoints, int num_endpoints) 802{ 803 804 return (0); 805} 806 807void 808libusb_transfer_set_stream_id(struct libusb_transfer *transfer, uint32_t stream_id) 809{ 810 struct libusb_super_transfer *sxfer; 811 812 if (transfer == NULL) 813 return; 814 815 sxfer = (struct libusb_super_transfer *)( 816 ((uint8_t *)transfer) - sizeof(*sxfer)); 817 818 /* set stream ID */ 819 sxfer->stream_id = stream_id; 820} 821 822uint32_t 823libusb_transfer_get_stream_id(struct libusb_transfer *transfer) 824{ 825 struct libusb_super_transfer *sxfer; 826 827 if (transfer == NULL) 828 return (0); 829 830 sxfer = (struct libusb_super_transfer *)( 831 ((uint8_t *)transfer) - sizeof(*sxfer)); 832 833 /* get stream ID */ 834 return (sxfer->stream_id); 835} 836