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