1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2008-2009 Hans Petter Selasky. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #ifdef LIBUSB_GLOBAL_INCLUDE_FILE 29 #include LIBUSB_GLOBAL_INCLUDE_FILE 30 #else 31 #include <ctype.h> 32 #include <poll.h> 33 #include <pthread.h> 34 #include <stdio.h> 35 #include <stdlib.h> 36 #include <string.h> 37 #include <time.h> 38 #include <sys/queue.h> 39 #endif 40 41 #include "libusb20.h" 42 #include "libusb20_desc.h" 43 #include "libusb20_int.h" 44 45 static int 46 dummy_int(void) 47 { 48 return (LIBUSB20_ERROR_NOT_SUPPORTED); 49 } 50 51 static void 52 dummy_void(void) 53 { 54 return; 55 } 56 57 static void 58 dummy_callback(struct libusb20_transfer *xfer) 59 { 60 ; /* style fix */ 61 switch (libusb20_tr_get_status(xfer)) { 62 case LIBUSB20_TRANSFER_START: 63 libusb20_tr_submit(xfer); 64 break; 65 default: 66 /* complete or error */ 67 break; 68 } 69 return; 70 } 71 72 #define dummy_get_config_desc_full (void *)dummy_int 73 #define dummy_get_config_index (void *)dummy_int 74 #define dummy_set_config_index (void *)dummy_int 75 #define dummy_set_alt_index (void *)dummy_int 76 #define dummy_reset_device (void *)dummy_int 77 #define dummy_check_connected (void *)dummy_int 78 #define dummy_set_power_mode (void *)dummy_int 79 #define dummy_get_power_mode (void *)dummy_int 80 #define dummy_get_power_usage (void *)dummy_int 81 #define dummy_get_stats (void *)dummy_int 82 #define dummy_kernel_driver_active (void *)dummy_int 83 #define dummy_detach_kernel_driver (void *)dummy_int 84 #define dummy_attach_kernel_driver (void *)dummy_int 85 #define dummy_do_request_sync (void *)dummy_int 86 #define dummy_tr_open (void *)dummy_int 87 #define dummy_tr_close (void *)dummy_int 88 #define dummy_tr_clear_stall_sync (void *)dummy_int 89 #define dummy_process (void *)dummy_int 90 #define dummy_dev_info (void *)dummy_int 91 #define dummy_dev_get_iface_driver (void *)dummy_int 92 93 #define dummy_tr_submit (void *)dummy_void 94 #define dummy_tr_cancel_async (void *)dummy_void 95 96 static const struct libusb20_device_methods libusb20_dummy_methods = { 97 LIBUSB20_DEVICE(LIBUSB20_DECLARE, dummy) 98 }; 99 100 void 101 libusb20_tr_callback_wrapper(struct libusb20_transfer *xfer) 102 { 103 ; /* style fix */ 104 105 repeat: 106 107 if (!xfer->is_pending) { 108 xfer->status = LIBUSB20_TRANSFER_START; 109 } else { 110 xfer->is_pending = 0; 111 } 112 113 xfer->callback(xfer); 114 115 if (xfer->is_restart) { 116 xfer->is_restart = 0; 117 goto repeat; 118 } 119 if (xfer->is_draining && 120 (!xfer->is_pending)) { 121 xfer->is_draining = 0; 122 xfer->status = LIBUSB20_TRANSFER_DRAINED; 123 xfer->callback(xfer); 124 } 125 return; 126 } 127 128 int 129 libusb20_tr_close(struct libusb20_transfer *xfer) 130 { 131 int error; 132 133 if (!xfer->is_opened) { 134 return (LIBUSB20_ERROR_OTHER); 135 } 136 error = xfer->pdev->methods->tr_close(xfer); 137 138 if (xfer->pLength) { 139 free(xfer->pLength); 140 } 141 if (xfer->ppBuffer) { 142 free(xfer->ppBuffer); 143 } 144 /* reset variable fields in case the transfer is opened again */ 145 xfer->priv_sc0 = NULL; 146 xfer->priv_sc1 = NULL; 147 xfer->is_opened = 0; 148 xfer->is_pending = 0; 149 xfer->is_cancel = 0; 150 xfer->is_draining = 0; 151 xfer->is_restart = 0; 152 xfer->status = 0; 153 xfer->flags = 0; 154 xfer->nFrames = 0; 155 xfer->aFrames = 0; 156 xfer->timeout = 0; 157 xfer->maxFrames = 0; 158 xfer->maxTotalLength = 0; 159 xfer->maxPacketLen = 0; 160 return (error); 161 } 162 163 int 164 libusb20_tr_open(struct libusb20_transfer *xfer, uint32_t MaxBufSize, 165 uint32_t MaxFrameCount, uint8_t ep_no) 166 { 167 return (libusb20_tr_open_stream(xfer, MaxBufSize, MaxFrameCount, ep_no, 0)); 168 } 169 170 int 171 libusb20_tr_open_stream(struct libusb20_transfer *xfer, uint32_t MaxBufSize, 172 uint32_t MaxFrameCount, uint8_t ep_no, uint16_t stream_id) 173 { 174 uint32_t size; 175 uint8_t pre_scale; 176 int error; 177 178 if (xfer->is_opened) 179 return (LIBUSB20_ERROR_BUSY); 180 if (MaxFrameCount & LIBUSB20_MAX_FRAME_PRE_SCALE) { 181 MaxFrameCount &= ~LIBUSB20_MAX_FRAME_PRE_SCALE; 182 /* 183 * The kernel can setup 8 times more frames when 184 * pre-scaling ISOCHRONOUS transfers. Make sure the 185 * length and pointer buffers are big enough: 186 */ 187 MaxFrameCount *= 8; 188 pre_scale = 1; 189 } else { 190 pre_scale = 0; 191 } 192 if (MaxFrameCount == 0) 193 return (LIBUSB20_ERROR_INVALID_PARAM); 194 195 xfer->maxFrames = MaxFrameCount; 196 197 size = MaxFrameCount * sizeof(xfer->pLength[0]); 198 xfer->pLength = malloc(size); 199 if (xfer->pLength == NULL) { 200 return (LIBUSB20_ERROR_NO_MEM); 201 } 202 memset(xfer->pLength, 0, size); 203 204 size = MaxFrameCount * sizeof(xfer->ppBuffer[0]); 205 xfer->ppBuffer = malloc(size); 206 if (xfer->ppBuffer == NULL) { 207 free(xfer->pLength); 208 return (LIBUSB20_ERROR_NO_MEM); 209 } 210 memset(xfer->ppBuffer, 0, size); 211 212 if (pre_scale) { 213 error = xfer->pdev->methods->tr_open(xfer, MaxBufSize, 214 MaxFrameCount / 8, ep_no, stream_id, 1); 215 } else { 216 error = xfer->pdev->methods->tr_open(xfer, MaxBufSize, 217 MaxFrameCount, ep_no, stream_id, 0); 218 } 219 220 if (error) { 221 free(xfer->ppBuffer); 222 free(xfer->pLength); 223 } else { 224 xfer->is_opened = 1; 225 } 226 return (error); 227 } 228 229 struct libusb20_transfer * 230 libusb20_tr_get_pointer(struct libusb20_device *pdev, uint16_t trIndex) 231 { 232 if (trIndex >= pdev->nTransfer) { 233 return (NULL); 234 } 235 return (pdev->pTransfer + trIndex); 236 } 237 238 uint32_t 239 libusb20_tr_get_actual_frames(struct libusb20_transfer *xfer) 240 { 241 return (xfer->aFrames); 242 } 243 244 uint16_t 245 libusb20_tr_get_time_complete(struct libusb20_transfer *xfer) 246 { 247 return (xfer->timeComplete); 248 } 249 250 uint32_t 251 libusb20_tr_get_actual_length(struct libusb20_transfer *xfer) 252 { 253 uint32_t x; 254 uint32_t actlen = 0; 255 256 for (x = 0; x != xfer->aFrames; x++) { 257 actlen += xfer->pLength[x]; 258 } 259 return (actlen); 260 } 261 262 uint32_t 263 libusb20_tr_get_max_frames(struct libusb20_transfer *xfer) 264 { 265 return (xfer->maxFrames); 266 } 267 268 uint32_t 269 libusb20_tr_get_max_packet_length(struct libusb20_transfer *xfer) 270 { 271 /* 272 * Special Case NOTE: If the packet multiplier is non-zero for 273 * High Speed USB, the value returned is equal to 274 * "wMaxPacketSize * multiplier" ! 275 */ 276 return (xfer->maxPacketLen); 277 } 278 279 uint32_t 280 libusb20_tr_get_max_total_length(struct libusb20_transfer *xfer) 281 { 282 return (xfer->maxTotalLength); 283 } 284 285 uint8_t 286 libusb20_tr_get_status(struct libusb20_transfer *xfer) 287 { 288 return (xfer->status); 289 } 290 291 uint8_t 292 libusb20_tr_pending(struct libusb20_transfer *xfer) 293 { 294 return (xfer->is_pending); 295 } 296 297 void * 298 libusb20_tr_get_priv_sc0(struct libusb20_transfer *xfer) 299 { 300 return (xfer->priv_sc0); 301 } 302 303 void * 304 libusb20_tr_get_priv_sc1(struct libusb20_transfer *xfer) 305 { 306 return (xfer->priv_sc1); 307 } 308 309 void 310 libusb20_tr_stop(struct libusb20_transfer *xfer) 311 { 312 if (!xfer->is_opened) { 313 /* transfer is not opened */ 314 return; 315 } 316 if (!xfer->is_pending) { 317 /* transfer not pending */ 318 return; 319 } 320 if (xfer->is_cancel) { 321 /* already cancelling */ 322 return; 323 } 324 xfer->is_cancel = 1; /* we are cancelling */ 325 326 xfer->pdev->methods->tr_cancel_async(xfer); 327 return; 328 } 329 330 void 331 libusb20_tr_drain(struct libusb20_transfer *xfer) 332 { 333 if (!xfer->is_opened) { 334 /* transfer is not opened */ 335 return; 336 } 337 /* make sure that we are cancelling */ 338 libusb20_tr_stop(xfer); 339 340 if (xfer->is_pending) { 341 xfer->is_draining = 1; 342 } 343 return; 344 } 345 346 void 347 libusb20_tr_clear_stall_sync(struct libusb20_transfer *xfer) 348 { 349 xfer->pdev->methods->tr_clear_stall_sync(xfer); 350 return; 351 } 352 353 void 354 libusb20_tr_set_buffer(struct libusb20_transfer *xfer, void *buffer, uint16_t frIndex) 355 { 356 xfer->ppBuffer[frIndex] = buffer; 357 return; 358 } 359 360 void 361 libusb20_tr_set_callback(struct libusb20_transfer *xfer, libusb20_tr_callback_t *cb) 362 { 363 xfer->callback = cb; 364 return; 365 } 366 367 void 368 libusb20_tr_set_flags(struct libusb20_transfer *xfer, uint8_t flags) 369 { 370 xfer->flags = flags; 371 return; 372 } 373 374 uint8_t 375 libusb20_tr_get_flags(struct libusb20_transfer *xfer) 376 { 377 return (xfer->flags); 378 } 379 380 uint32_t 381 libusb20_tr_get_length(struct libusb20_transfer *xfer, uint16_t frIndex) 382 { 383 return (xfer->pLength[frIndex]); 384 } 385 386 void 387 libusb20_tr_set_length(struct libusb20_transfer *xfer, uint32_t length, uint16_t frIndex) 388 { 389 xfer->pLength[frIndex] = length; 390 return; 391 } 392 393 void 394 libusb20_tr_set_priv_sc0(struct libusb20_transfer *xfer, void *sc0) 395 { 396 xfer->priv_sc0 = sc0; 397 return; 398 } 399 400 void 401 libusb20_tr_set_priv_sc1(struct libusb20_transfer *xfer, void *sc1) 402 { 403 xfer->priv_sc1 = sc1; 404 return; 405 } 406 407 void 408 libusb20_tr_set_timeout(struct libusb20_transfer *xfer, uint32_t timeout) 409 { 410 xfer->timeout = timeout; 411 return; 412 } 413 414 void 415 libusb20_tr_set_total_frames(struct libusb20_transfer *xfer, uint32_t nFrames) 416 { 417 if (nFrames > xfer->maxFrames) { 418 /* should not happen */ 419 nFrames = xfer->maxFrames; 420 } 421 xfer->nFrames = nFrames; 422 return; 423 } 424 425 void 426 libusb20_tr_setup_bulk(struct libusb20_transfer *xfer, void *pBuf, uint32_t length, uint32_t timeout) 427 { 428 xfer->ppBuffer[0] = pBuf; 429 xfer->pLength[0] = length; 430 xfer->timeout = timeout; 431 xfer->nFrames = 1; 432 return; 433 } 434 435 void 436 libusb20_tr_setup_control(struct libusb20_transfer *xfer, void *psetup, void *pBuf, uint32_t timeout) 437 { 438 uint16_t len; 439 440 xfer->ppBuffer[0] = psetup; 441 xfer->pLength[0] = 8; /* fixed */ 442 xfer->timeout = timeout; 443 444 len = ((uint8_t *)psetup)[6] | (((uint8_t *)psetup)[7] << 8); 445 446 if (len != 0) { 447 xfer->nFrames = 2; 448 xfer->ppBuffer[1] = pBuf; 449 xfer->pLength[1] = len; 450 } else { 451 xfer->nFrames = 1; 452 } 453 return; 454 } 455 456 void 457 libusb20_tr_setup_intr(struct libusb20_transfer *xfer, void *pBuf, uint32_t length, uint32_t timeout) 458 { 459 xfer->ppBuffer[0] = pBuf; 460 xfer->pLength[0] = length; 461 xfer->timeout = timeout; 462 xfer->nFrames = 1; 463 return; 464 } 465 466 void 467 libusb20_tr_setup_isoc(struct libusb20_transfer *xfer, void *pBuf, uint32_t length, uint16_t frIndex) 468 { 469 if (frIndex >= xfer->maxFrames) { 470 /* should not happen */ 471 return; 472 } 473 xfer->ppBuffer[frIndex] = pBuf; 474 xfer->pLength[frIndex] = length; 475 return; 476 } 477 478 uint8_t 479 libusb20_tr_bulk_intr_sync(struct libusb20_transfer *xfer, 480 void *pbuf, uint32_t length, uint32_t *pactlen, 481 uint32_t timeout) 482 { 483 struct libusb20_device *pdev = xfer->pdev; 484 uint32_t transfer_max; 485 uint32_t transfer_act; 486 uint8_t retval; 487 488 /* set some sensible default value */ 489 if (pactlen != NULL) 490 *pactlen = 0; 491 492 /* check for error condition */ 493 if (libusb20_tr_pending(xfer)) 494 return (LIBUSB20_ERROR_OTHER); 495 496 do { 497 /* compute maximum transfer length */ 498 transfer_max = 499 libusb20_tr_get_max_total_length(xfer); 500 501 if (transfer_max > length) 502 transfer_max = length; 503 504 /* setup bulk or interrupt transfer */ 505 libusb20_tr_setup_bulk(xfer, pbuf, 506 transfer_max, timeout); 507 508 /* start the transfer */ 509 libusb20_tr_start(xfer); 510 511 /* wait for transfer completion */ 512 while (libusb20_dev_process(pdev) == 0) { 513 514 if (libusb20_tr_pending(xfer) == 0) 515 break; 516 517 libusb20_dev_wait_process(pdev, -1); 518 } 519 520 transfer_act = libusb20_tr_get_actual_length(xfer); 521 522 /* update actual length, if any */ 523 if (pactlen != NULL) 524 pactlen[0] += transfer_act; 525 526 /* check transfer status */ 527 retval = libusb20_tr_get_status(xfer); 528 if (retval) 529 break; 530 531 /* check for short transfer */ 532 if (transfer_act != transfer_max) 533 break; 534 535 /* update buffer pointer and length */ 536 pbuf = ((uint8_t *)pbuf) + transfer_max; 537 length = length - transfer_max; 538 539 } while (length != 0); 540 541 return (retval); 542 } 543 544 void 545 libusb20_tr_submit(struct libusb20_transfer *xfer) 546 { 547 if (!xfer->is_opened) { 548 /* transfer is not opened */ 549 return; 550 } 551 if (xfer->is_pending) { 552 /* should not happen */ 553 return; 554 } 555 xfer->is_pending = 1; /* we are pending */ 556 xfer->is_cancel = 0; /* not cancelling */ 557 xfer->is_restart = 0; /* not restarting */ 558 559 xfer->pdev->methods->tr_submit(xfer); 560 return; 561 } 562 563 void 564 libusb20_tr_start(struct libusb20_transfer *xfer) 565 { 566 if (!xfer->is_opened) { 567 /* transfer is not opened */ 568 return; 569 } 570 if (xfer->is_pending) { 571 if (xfer->is_cancel) { 572 /* cancelling - restart */ 573 xfer->is_restart = 1; 574 } 575 /* transfer not pending */ 576 return; 577 } 578 /* get into the callback */ 579 libusb20_tr_callback_wrapper(xfer); 580 return; 581 } 582 583 /* USB device operations */ 584 585 int 586 libusb20_dev_close(struct libusb20_device *pdev) 587 { 588 struct libusb20_transfer *xfer; 589 uint16_t x; 590 int error = 0; 591 592 if (!pdev->is_opened) { 593 return (LIBUSB20_ERROR_OTHER); 594 } 595 for (x = 0; x != pdev->nTransfer; x++) { 596 xfer = pdev->pTransfer + x; 597 598 if (!xfer->is_opened) { 599 /* transfer is not opened */ 600 continue; 601 } 602 603 libusb20_tr_drain(xfer); 604 605 libusb20_tr_close(xfer); 606 } 607 608 if (pdev->pTransfer != NULL) { 609 free(pdev->pTransfer); 610 pdev->pTransfer = NULL; 611 } 612 error = pdev->beMethods->close_device(pdev); 613 614 pdev->methods = &libusb20_dummy_methods; 615 616 pdev->is_opened = 0; 617 618 /* 619 * Make sure libusb20_tr_get_pointer() fails: 620 */ 621 pdev->nTransfer = 0; 622 623 /* 624 * The following variable is only used by the libusb v0.1 625 * compat layer: 626 */ 627 pdev->claimed_interface = 0; 628 629 /* 630 * The following variable is only used by the libusb v1.0 631 * compat layer: 632 */ 633 pdev->auto_detach = 0; 634 635 return (error); 636 } 637 638 int 639 libusb20_dev_detach_kernel_driver(struct libusb20_device *pdev, uint8_t ifaceIndex) 640 { 641 int error; 642 643 error = pdev->methods->detach_kernel_driver(pdev, ifaceIndex); 644 return (error); 645 } 646 647 int 648 libusb20_dev_attach_kernel_driver(struct libusb20_device *pdev, 649 uint8_t ifaceIndex) 650 { 651 int error; 652 653 error = pdev->methods->attach_kernel_driver(pdev, ifaceIndex); 654 return (error); 655 } 656 657 struct LIBUSB20_DEVICE_DESC_DECODED * 658 libusb20_dev_get_device_desc(struct libusb20_device *pdev) 659 { 660 return (&(pdev->ddesc)); 661 } 662 663 int 664 libusb20_dev_get_fd(struct libusb20_device *pdev) 665 { 666 return (pdev->file); 667 } 668 669 int 670 libusb20_dev_kernel_driver_active(struct libusb20_device *pdev, uint8_t ifaceIndex) 671 { 672 int error; 673 674 error = pdev->methods->kernel_driver_active(pdev, ifaceIndex); 675 return (error); 676 } 677 678 int 679 libusb20_dev_open(struct libusb20_device *pdev, uint16_t nTransferMax) 680 { 681 struct libusb20_transfer *xfer; 682 uint32_t size; 683 uint16_t x; 684 int error; 685 686 if (pdev->is_opened) { 687 return (LIBUSB20_ERROR_BUSY); 688 } 689 if (nTransferMax >= 256) { 690 return (LIBUSB20_ERROR_INVALID_PARAM); 691 } else if (nTransferMax != 0) { 692 size = sizeof(pdev->pTransfer[0]) * nTransferMax; 693 pdev->pTransfer = malloc(size); 694 if (pdev->pTransfer == NULL) { 695 return (LIBUSB20_ERROR_NO_MEM); 696 } 697 memset(pdev->pTransfer, 0, size); 698 } 699 /* initialise all transfers */ 700 for (x = 0; x != nTransferMax; x++) { 701 702 xfer = pdev->pTransfer + x; 703 704 xfer->pdev = pdev; 705 xfer->trIndex = x; 706 xfer->callback = &dummy_callback; 707 } 708 709 /* set "nTransfer" early */ 710 pdev->nTransfer = nTransferMax; 711 712 error = pdev->beMethods->open_device(pdev, nTransferMax); 713 714 if (error) { 715 if (pdev->pTransfer != NULL) { 716 free(pdev->pTransfer); 717 pdev->pTransfer = NULL; 718 } 719 pdev->file = -1; 720 pdev->file_ctrl = -1; 721 pdev->nTransfer = 0; 722 } else { 723 pdev->is_opened = 1; 724 } 725 return (error); 726 } 727 728 int 729 libusb20_dev_reset(struct libusb20_device *pdev) 730 { 731 int error; 732 733 error = pdev->methods->reset_device(pdev); 734 return (error); 735 } 736 737 int 738 libusb20_dev_check_connected(struct libusb20_device *pdev) 739 { 740 int error; 741 742 error = pdev->methods->check_connected(pdev); 743 return (error); 744 } 745 746 int 747 libusb20_dev_set_power_mode(struct libusb20_device *pdev, uint8_t power_mode) 748 { 749 int error; 750 751 error = pdev->methods->set_power_mode(pdev, power_mode); 752 return (error); 753 } 754 755 uint8_t 756 libusb20_dev_get_power_mode(struct libusb20_device *pdev) 757 { 758 int error; 759 uint8_t power_mode; 760 761 error = pdev->methods->get_power_mode(pdev, &power_mode); 762 if (error) 763 power_mode = LIBUSB20_POWER_ON; /* fake power mode */ 764 return (power_mode); 765 } 766 767 int 768 libusb20_dev_get_port_path(struct libusb20_device *pdev, uint8_t *buf, uint8_t bufsize) 769 { 770 771 if (pdev->port_level == 0) { 772 /* 773 * Fallback for backends without port path: 774 */ 775 if (bufsize < 2) 776 return (LIBUSB20_ERROR_OVERFLOW); 777 buf[0] = pdev->parent_address; 778 buf[1] = pdev->parent_port; 779 return (2); 780 } 781 782 /* check if client buffer is too small */ 783 if (pdev->port_level > bufsize) 784 return (LIBUSB20_ERROR_OVERFLOW); 785 786 /* copy port number information */ 787 memcpy(buf, pdev->port_path, pdev->port_level); 788 789 return (pdev->port_level); /* success */ 790 } 791 792 uint16_t 793 libusb20_dev_get_power_usage(struct libusb20_device *pdev) 794 { 795 int error; 796 uint16_t power_usage; 797 798 error = pdev->methods->get_power_usage(pdev, &power_usage); 799 if (error) 800 power_usage = 0; 801 return (power_usage); 802 } 803 804 int 805 libusb20_dev_set_alt_index(struct libusb20_device *pdev, uint8_t ifaceIndex, uint8_t altIndex) 806 { 807 int error; 808 809 error = pdev->methods->set_alt_index(pdev, ifaceIndex, altIndex); 810 return (error); 811 } 812 813 int 814 libusb20_dev_set_config_index(struct libusb20_device *pdev, uint8_t configIndex) 815 { 816 int error; 817 818 error = pdev->methods->set_config_index(pdev, configIndex); 819 return (error); 820 } 821 822 int 823 libusb20_dev_request_sync(struct libusb20_device *pdev, 824 struct LIBUSB20_CONTROL_SETUP_DECODED *setup, void *data, 825 uint16_t *pactlen, uint32_t timeout, uint8_t flags) 826 { 827 int error; 828 829 error = pdev->methods->do_request_sync(pdev, 830 setup, data, pactlen, timeout, flags); 831 return (error); 832 } 833 834 int 835 libusb20_dev_req_string_sync(struct libusb20_device *pdev, 836 uint8_t str_index, uint16_t langid, void *ptr, uint16_t len) 837 { 838 struct LIBUSB20_CONTROL_SETUP_DECODED req; 839 int error; 840 int flags; 841 842 /* make sure memory is initialised */ 843 memset(ptr, 0, len); 844 845 if (len < 4) { 846 /* invalid length */ 847 return (LIBUSB20_ERROR_INVALID_PARAM); 848 } 849 LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &req); 850 851 /* 852 * We need to read the USB string in two steps else some USB 853 * devices will complain. 854 */ 855 req.bmRequestType = 856 LIBUSB20_REQUEST_TYPE_STANDARD | 857 LIBUSB20_RECIPIENT_DEVICE | 858 LIBUSB20_ENDPOINT_IN; 859 req.bRequest = LIBUSB20_REQUEST_GET_DESCRIPTOR; 860 req.wValue = (LIBUSB20_DT_STRING << 8) | str_index; 861 req.wIndex = langid; 862 req.wLength = 4; /* bytes */ 863 864 error = libusb20_dev_request_sync(pdev, &req, 865 ptr, NULL, 1000, LIBUSB20_TRANSFER_SINGLE_SHORT_NOT_OK); 866 if (error) { 867 /* try to request full string */ 868 req.wLength = 255; 869 flags = 0; 870 } else { 871 /* extract length and request full string */ 872 req.wLength = *(uint8_t *)ptr; 873 flags = LIBUSB20_TRANSFER_SINGLE_SHORT_NOT_OK; 874 } 875 if (req.wLength > len) { 876 /* partial string read */ 877 req.wLength = len; 878 } 879 error = libusb20_dev_request_sync(pdev, &req, ptr, NULL, 1000, flags); 880 if (error) 881 return (error); 882 883 if (((uint8_t *)ptr)[1] != LIBUSB20_DT_STRING) 884 return (LIBUSB20_ERROR_OTHER); 885 return (0); /* success */ 886 } 887 888 int 889 libusb20_dev_req_string_simple_sync(struct libusb20_device *pdev, 890 uint8_t str_index, void *ptr, uint16_t len) 891 { 892 char *buf; 893 int error; 894 uint16_t langid; 895 uint16_t n; 896 uint16_t i; 897 uint16_t c; 898 uint8_t temp[255]; 899 uint8_t swap; 900 901 /* the following code derives from the FreeBSD USB kernel */ 902 903 if ((len < 1) || (ptr == NULL)) { 904 /* too short buffer */ 905 return (LIBUSB20_ERROR_INVALID_PARAM); 906 } 907 error = libusb20_dev_req_string_sync(pdev, 908 0, 0, temp, sizeof(temp)); 909 if (error < 0) { 910 *(uint8_t *)ptr = 0; /* zero terminate */ 911 return (error); 912 } 913 langid = temp[2] | (temp[3] << 8); 914 915 error = libusb20_dev_req_string_sync(pdev, str_index, 916 langid, temp, sizeof(temp)); 917 if (error < 0) { 918 *(uint8_t *)ptr = 0; /* zero terminate */ 919 return (error); 920 } 921 if (temp[0] < 2) { 922 /* string length is too short */ 923 *(uint8_t *)ptr = 0; /* zero terminate */ 924 return (LIBUSB20_ERROR_OTHER); 925 } 926 /* reserve one byte for terminating zero */ 927 len--; 928 929 /* find maximum length */ 930 n = (temp[0] / 2) - 1; 931 if (n > len) { 932 n = len; 933 } 934 /* reset swap state */ 935 swap = 3; 936 937 /* setup output buffer pointer */ 938 buf = ptr; 939 940 /* convert and filter */ 941 for (i = 0; (i != n); i++) { 942 c = temp[(2 * i) + 2] | (temp[(2 * i) + 3] << 8); 943 944 /* convert from Unicode, handle buggy strings */ 945 if (((c & 0xff00) == 0) && (swap & 1)) { 946 /* Little Endian, default */ 947 *buf = c; 948 swap = 1; 949 } else if (((c & 0x00ff) == 0) && (swap & 2)) { 950 /* Big Endian */ 951 *buf = c >> 8; 952 swap = 2; 953 } else { 954 /* skip invalid character */ 955 continue; 956 } 957 /* 958 * Filter by default - we don't allow greater and less than 959 * signs because they might confuse the dmesg printouts! 960 */ 961 if ((*buf == '<') || (*buf == '>') || (!isprint(*buf))) { 962 /* skip invalid character */ 963 continue; 964 } 965 buf++; 966 } 967 *buf = 0; /* zero terminate string */ 968 969 return (0); 970 } 971 972 struct libusb20_config * 973 libusb20_dev_alloc_config(struct libusb20_device *pdev, uint8_t configIndex) 974 { 975 struct libusb20_config *retval = NULL; 976 uint8_t *ptr; 977 uint16_t len; 978 uint8_t do_close; 979 int error; 980 981 /* 982 * Catch invalid configuration descriptor reads early on to 983 * avoid issues with devices that don't check for a valid USB 984 * configuration read request. 985 */ 986 if (configIndex >= pdev->ddesc.bNumConfigurations) 987 return (NULL); 988 989 if (!pdev->is_opened) { 990 error = libusb20_dev_open(pdev, 0); 991 if (error) { 992 return (NULL); 993 } 994 do_close = 1; 995 } else { 996 do_close = 0; 997 } 998 error = pdev->methods->get_config_desc_full(pdev, 999 &ptr, &len, configIndex); 1000 1001 if (error) { 1002 goto done; 1003 } 1004 /* parse new config descriptor */ 1005 retval = libusb20_parse_config_desc(ptr); 1006 1007 /* free config descriptor */ 1008 free(ptr); 1009 1010 done: 1011 if (do_close) { 1012 error = libusb20_dev_close(pdev); 1013 } 1014 return (retval); 1015 } 1016 1017 struct libusb20_device * 1018 libusb20_dev_alloc(void) 1019 { 1020 struct libusb20_device *pdev; 1021 1022 pdev = malloc(sizeof(*pdev)); 1023 if (pdev == NULL) { 1024 return (NULL); 1025 } 1026 memset(pdev, 0, sizeof(*pdev)); 1027 1028 pdev->file = -1; 1029 pdev->file_ctrl = -1; 1030 pdev->methods = &libusb20_dummy_methods; 1031 return (pdev); 1032 } 1033 1034 uint8_t 1035 libusb20_dev_get_config_index(struct libusb20_device *pdev) 1036 { 1037 int error; 1038 uint8_t cfg_index; 1039 uint8_t do_close; 1040 1041 if (!pdev->is_opened) { 1042 error = libusb20_dev_open(pdev, 0); 1043 if (error == 0) { 1044 do_close = 1; 1045 } else { 1046 do_close = 0; 1047 } 1048 } else { 1049 do_close = 0; 1050 } 1051 1052 error = pdev->methods->get_config_index(pdev, &cfg_index); 1053 if (error) 1054 cfg_index = 0xFF; /* current config index */ 1055 if (do_close) { 1056 if (libusb20_dev_close(pdev)) { 1057 /* ignore */ 1058 } 1059 } 1060 return (cfg_index); 1061 } 1062 1063 uint8_t 1064 libusb20_dev_get_mode(struct libusb20_device *pdev) 1065 { 1066 return (pdev->usb_mode); 1067 } 1068 1069 uint8_t 1070 libusb20_dev_get_speed(struct libusb20_device *pdev) 1071 { 1072 return (pdev->usb_speed); 1073 } 1074 1075 int 1076 libusb20_dev_get_stats(struct libusb20_device *pdev, struct libusb20_device_stats *pstats) 1077 { 1078 uint8_t do_close; 1079 int error; 1080 1081 if (!pdev->is_opened) { 1082 error = libusb20_dev_open(pdev, 0); 1083 if (error == 0) { 1084 do_close = 1; 1085 } else { 1086 do_close = 0; 1087 } 1088 } else { 1089 do_close = 0; 1090 } 1091 1092 error = pdev->methods->get_stats(pdev, pstats); 1093 1094 if (do_close) 1095 (void) libusb20_dev_close(pdev); 1096 1097 return (error); 1098 } 1099 1100 /* if this function returns an error, the device is gone */ 1101 int 1102 libusb20_dev_process(struct libusb20_device *pdev) 1103 { 1104 int error; 1105 1106 error = pdev->methods->process(pdev); 1107 return (error); 1108 } 1109 1110 void 1111 libusb20_dev_wait_process(struct libusb20_device *pdev, int timeout) 1112 { 1113 struct pollfd pfd[1]; 1114 1115 if (!pdev->is_opened) { 1116 return; 1117 } 1118 pfd[0].fd = pdev->file; 1119 pfd[0].events = (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM); 1120 pfd[0].revents = 0; 1121 1122 if (poll(pfd, 1, timeout)) { 1123 /* ignore any error */ 1124 } 1125 return; 1126 } 1127 1128 void 1129 libusb20_dev_free(struct libusb20_device *pdev) 1130 { 1131 if (pdev == NULL) { 1132 /* be NULL safe */ 1133 return; 1134 } 1135 if (pdev->is_opened) { 1136 if (libusb20_dev_close(pdev)) { 1137 /* ignore any errors */ 1138 } 1139 } 1140 free(pdev); 1141 return; 1142 } 1143 1144 int 1145 libusb20_dev_get_info(struct libusb20_device *pdev, 1146 struct usb_device_info *pinfo) 1147 { 1148 if (pinfo == NULL) 1149 return (LIBUSB20_ERROR_INVALID_PARAM); 1150 1151 return (pdev->beMethods->dev_get_info(pdev, pinfo)); 1152 } 1153 1154 const char * 1155 libusb20_dev_get_backend_name(struct libusb20_device *pdev) 1156 { 1157 return (pdev->beMethods->get_backend_name()); 1158 } 1159 1160 const char * 1161 libusb20_dev_get_desc(struct libusb20_device *pdev) 1162 { 1163 return (pdev->usb_desc); 1164 } 1165 1166 void 1167 libusb20_dev_set_debug(struct libusb20_device *pdev, int debug) 1168 { 1169 pdev->debug = debug; 1170 return; 1171 } 1172 1173 int 1174 libusb20_dev_get_debug(struct libusb20_device *pdev) 1175 { 1176 return (pdev->debug); 1177 } 1178 1179 uint8_t 1180 libusb20_dev_get_address(struct libusb20_device *pdev) 1181 { 1182 return (pdev->device_address); 1183 } 1184 1185 uint8_t 1186 libusb20_dev_get_parent_address(struct libusb20_device *pdev) 1187 { 1188 return (pdev->parent_address); 1189 } 1190 1191 uint8_t 1192 libusb20_dev_get_parent_port(struct libusb20_device *pdev) 1193 { 1194 return (pdev->parent_port); 1195 } 1196 1197 uint8_t 1198 libusb20_dev_get_bus_number(struct libusb20_device *pdev) 1199 { 1200 return (pdev->bus_number); 1201 } 1202 1203 int 1204 libusb20_dev_get_iface_desc(struct libusb20_device *pdev, 1205 uint8_t iface_index, char *buf, uint8_t len) 1206 { 1207 if ((buf == NULL) || (len == 0)) 1208 return (LIBUSB20_ERROR_INVALID_PARAM); 1209 1210 buf[0] = 0; /* set default string value */ 1211 1212 return (pdev->beMethods->dev_get_iface_desc( 1213 pdev, iface_index, buf, len)); 1214 } 1215 1216 /* USB backend operations */ 1217 1218 int 1219 libusb20_be_get_dev_quirk(struct libusb20_backend *pbe, 1220 uint16_t quirk_index, struct libusb20_quirk *pq) 1221 { 1222 return (pbe->methods->root_get_dev_quirk(pbe, quirk_index, pq)); 1223 } 1224 1225 int 1226 libusb20_be_get_quirk_name(struct libusb20_backend *pbe, 1227 uint16_t quirk_index, struct libusb20_quirk *pq) 1228 { 1229 return (pbe->methods->root_get_quirk_name(pbe, quirk_index, pq)); 1230 } 1231 1232 int 1233 libusb20_be_add_dev_quirk(struct libusb20_backend *pbe, 1234 struct libusb20_quirk *pq) 1235 { 1236 return (pbe->methods->root_add_dev_quirk(pbe, pq)); 1237 } 1238 1239 int 1240 libusb20_be_remove_dev_quirk(struct libusb20_backend *pbe, 1241 struct libusb20_quirk *pq) 1242 { 1243 return (pbe->methods->root_remove_dev_quirk(pbe, pq)); 1244 } 1245 1246 int 1247 libusb20_be_set_template(struct libusb20_backend *pbe, int temp) 1248 { 1249 return (pbe->methods->root_set_template(pbe, temp)); 1250 } 1251 1252 int 1253 libusb20_be_get_template(struct libusb20_backend *pbe, int *ptemp) 1254 { 1255 int temp; 1256 1257 if (ptemp == NULL) 1258 ptemp = &temp; 1259 1260 return (pbe->methods->root_get_template(pbe, ptemp)); 1261 } 1262 1263 struct libusb20_device * 1264 libusb20_be_device_foreach(struct libusb20_backend *pbe, struct libusb20_device *pdev) 1265 { 1266 if (pbe == NULL) { 1267 pdev = NULL; 1268 } else if (pdev == NULL) { 1269 pdev = TAILQ_FIRST(&(pbe->usb_devs)); 1270 } else { 1271 pdev = TAILQ_NEXT(pdev, dev_entry); 1272 } 1273 return (pdev); 1274 } 1275 1276 struct libusb20_backend * 1277 libusb20_be_alloc(const struct libusb20_backend_methods *methods, 1278 struct libusb20_be_ctx *pctx) 1279 { 1280 struct libusb20_backend *pbe; 1281 1282 pbe = malloc(sizeof(*pbe)); 1283 if (pbe == NULL) { 1284 return (NULL); 1285 } 1286 memset(pbe, 0, sizeof(*pbe)); 1287 1288 if (pctx == NULL) { 1289 /* the backend owns its own context */ 1290 pctx = libusb20_be_ctx_alloc(); 1291 if (pctx == NULL) { 1292 free(pbe); 1293 return (NULL); 1294 } 1295 pbe->be_ctx_owner = 1; 1296 } 1297 pbe->be_ctx = pctx; 1298 1299 TAILQ_INIT(&(pbe->usb_devs)); 1300 1301 pbe->methods = methods; /* set backend methods */ 1302 1303 /* do the initial device scan */ 1304 if (pbe->methods->init_backend) { 1305 pbe->methods->init_backend(pbe); 1306 } 1307 return (pbe); 1308 } 1309 1310 struct libusb20_backend * 1311 libusb20_be_alloc_linux(struct libusb20_be_ctx *pctx) 1312 { 1313 return (NULL); 1314 } 1315 1316 struct libusb20_backend * 1317 libusb20_be_alloc_ugen20(struct libusb20_be_ctx *pctx) 1318 { 1319 return (libusb20_be_alloc(&libusb20_ugen20_backend, pctx)); 1320 } 1321 1322 struct libusb20_backend * 1323 libusb20_be_alloc_default(struct libusb20_be_ctx *pctx) 1324 { 1325 struct libusb20_backend *pbe; 1326 1327 #ifdef __linux__ 1328 pbe = libusb20_be_alloc_linux(pctx); 1329 if (pbe) { 1330 return (pbe); 1331 } 1332 #endif 1333 pbe = libusb20_be_alloc_ugen20(pctx); 1334 if (pbe) { 1335 return (pbe); 1336 } 1337 return (NULL); /* no backend found */ 1338 } 1339 1340 void 1341 libusb20_be_free(struct libusb20_backend *pbe) 1342 { 1343 struct libusb20_device *pdev; 1344 1345 if (pbe == NULL) { 1346 /* be NULL safe */ 1347 return; 1348 } 1349 while ((pdev = libusb20_be_device_foreach(pbe, NULL))) { 1350 libusb20_be_dequeue_device(pbe, pdev); 1351 libusb20_dev_free(pdev); 1352 } 1353 if (pbe->methods->exit_backend) { 1354 pbe->methods->exit_backend(pbe); 1355 } 1356 if (pbe->be_ctx_owner) 1357 libusb20_be_ctx_free(pbe->be_ctx); 1358 /* free backend */ 1359 free(pbe); 1360 } 1361 1362 void 1363 libusb20_be_enqueue_device(struct libusb20_backend *pbe, struct libusb20_device *pdev) 1364 { 1365 pdev->beMethods = pbe->methods; /* copy backend methods */ 1366 TAILQ_INSERT_TAIL(&(pbe->usb_devs), pdev, dev_entry); 1367 } 1368 1369 void 1370 libusb20_be_dequeue_device(struct libusb20_backend *pbe, 1371 struct libusb20_device *pdev) 1372 { 1373 TAILQ_REMOVE(&(pbe->usb_devs), pdev, dev_entry); 1374 } 1375 1376 const char * 1377 libusb20_strerror(int code) 1378 { 1379 switch (code) { 1380 case LIBUSB20_SUCCESS: 1381 return ("Success"); 1382 case LIBUSB20_ERROR_IO: 1383 return ("I/O error"); 1384 case LIBUSB20_ERROR_INVALID_PARAM: 1385 return ("Invalid parameter"); 1386 case LIBUSB20_ERROR_ACCESS: 1387 return ("Permissions error"); 1388 case LIBUSB20_ERROR_NO_DEVICE: 1389 return ("No device"); 1390 case LIBUSB20_ERROR_NOT_FOUND: 1391 return ("Not found"); 1392 case LIBUSB20_ERROR_BUSY: 1393 return ("Device busy"); 1394 case LIBUSB20_ERROR_TIMEOUT: 1395 return ("Timeout"); 1396 case LIBUSB20_ERROR_OVERFLOW: 1397 return ("Overflow"); 1398 case LIBUSB20_ERROR_PIPE: 1399 return ("Pipe error"); 1400 case LIBUSB20_ERROR_INTERRUPTED: 1401 return ("Interrupted"); 1402 case LIBUSB20_ERROR_NO_MEM: 1403 return ("Out of memory"); 1404 case LIBUSB20_ERROR_NOT_SUPPORTED: 1405 return ("Not supported"); 1406 case LIBUSB20_ERROR_OTHER: 1407 return ("Other error"); 1408 default: 1409 return ("Unknown error"); 1410 } 1411 } 1412 1413 const char * 1414 libusb20_error_name(int code) 1415 { 1416 switch (code) { 1417 case LIBUSB20_SUCCESS: 1418 return ("LIBUSB20_SUCCESS"); 1419 case LIBUSB20_ERROR_IO: 1420 return ("LIBUSB20_ERROR_IO"); 1421 case LIBUSB20_ERROR_INVALID_PARAM: 1422 return ("LIBUSB20_ERROR_INVALID_PARAM"); 1423 case LIBUSB20_ERROR_ACCESS: 1424 return ("LIBUSB20_ERROR_ACCESS"); 1425 case LIBUSB20_ERROR_NO_DEVICE: 1426 return ("LIBUSB20_ERROR_NO_DEVICE"); 1427 case LIBUSB20_ERROR_NOT_FOUND: 1428 return ("LIBUSB20_ERROR_NOT_FOUND"); 1429 case LIBUSB20_ERROR_BUSY: 1430 return ("LIBUSB20_ERROR_BUSY"); 1431 case LIBUSB20_ERROR_TIMEOUT: 1432 return ("LIBUSB20_ERROR_TIMEOUT"); 1433 case LIBUSB20_ERROR_OVERFLOW: 1434 return ("LIBUSB20_ERROR_OVERFLOW"); 1435 case LIBUSB20_ERROR_PIPE: 1436 return ("LIBUSB20_ERROR_PIPE"); 1437 case LIBUSB20_ERROR_INTERRUPTED: 1438 return ("LIBUSB20_ERROR_INTERRUPTED"); 1439 case LIBUSB20_ERROR_NO_MEM: 1440 return ("LIBUSB20_ERROR_NO_MEM"); 1441 case LIBUSB20_ERROR_NOT_SUPPORTED: 1442 return ("LIBUSB20_ERROR_NOT_SUPPORTED"); 1443 case LIBUSB20_ERROR_OTHER: 1444 return ("LIBUSB20_ERROR_OTHER"); 1445 default: 1446 return ("LIBUSB20_ERROR_UNKNOWN"); 1447 } 1448 } 1449