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