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