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