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