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