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