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