1 /* $FreeBSD$ */ 2 /*- 3 * Copyright (c) 2009 Sylvestre Gallon. 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 #include <stdlib.h> 29 #include <unistd.h> 30 #include <stdio.h> 31 #include <poll.h> 32 #include <pthread.h> 33 #include <time.h> 34 #include <errno.h> 35 36 #include "libusb20.h" 37 #include "libusb20_desc.h" 38 #include "libusb20_int.h" 39 #include "libusb.h" 40 #include "libusb10.h" 41 42 static pthread_mutex_t default_context_lock = PTHREAD_MUTEX_INITIALIZER; 43 struct libusb_context *usbi_default_context = NULL; 44 pthread_mutex_t libusb20_lock = PTHREAD_MUTEX_INITIALIZER; 45 46 /* Library initialisation / deinitialisation */ 47 48 void 49 libusb_set_debug(libusb_context * ctx, int level) 50 { 51 GET_CONTEXT(ctx); 52 if (ctx) 53 ctx->debug = level; 54 } 55 56 int 57 libusb_init(libusb_context ** context) 58 { 59 struct libusb_context *ctx; 60 char * debug; 61 int ret; 62 63 ctx = malloc(sizeof(*ctx)); 64 if (!ctx) 65 return (LIBUSB_ERROR_INVALID_PARAM); 66 67 memset(ctx, 0, sizeof(*ctx)); 68 69 debug = getenv("LIBUSB_DEBUG"); 70 if (debug != NULL) { 71 ctx->debug = atoi(debug); 72 if (ctx->debug != 0) 73 ctx->debug_fixed = 1; 74 } 75 76 pthread_mutex_init(&ctx->usb_devs_lock, NULL); 77 pthread_mutex_init(&ctx->open_devs_lock, NULL); 78 TAILQ_INIT(&ctx->usb_devs); 79 TAILQ_INIT(&ctx->open_devs); 80 81 pthread_mutex_init(&ctx->flying_transfers_lock, NULL); 82 pthread_mutex_init(&ctx->pollfds_lock, NULL); 83 pthread_mutex_init(&ctx->pollfd_modify_lock, NULL); 84 pthread_mutex_init(&ctx->events_lock, NULL); 85 pthread_mutex_init(&ctx->event_waiters_lock, NULL); 86 pthread_cond_init(&ctx->event_waiters_cond, NULL); 87 88 TAILQ_INIT(&ctx->flying_transfers); 89 TAILQ_INIT(&ctx->pollfds); 90 91 ret = pipe(ctx->ctrl_pipe); 92 if (ret < 0) { 93 usb_remove_pollfd(ctx, ctx->ctrl_pipe[0]); 94 close(ctx->ctrl_pipe[0]); 95 close(ctx->ctrl_pipe[1]); 96 free(ctx); 97 return (LIBUSB_ERROR_OTHER); 98 } 99 100 ret = usb_add_pollfd(ctx, ctx->ctrl_pipe[0], POLLIN); 101 if (ret < 0) { 102 usb_remove_pollfd(ctx, ctx->ctrl_pipe[0]); 103 close(ctx->ctrl_pipe[0]); 104 close(ctx->ctrl_pipe[1]); 105 free(ctx); 106 return ret; 107 } 108 109 pthread_mutex_lock(&default_context_lock); 110 if (usbi_default_context == NULL) { 111 usbi_default_context = ctx; 112 } 113 pthread_mutex_unlock(&default_context_lock); 114 115 if (context) 116 *context = ctx; 117 118 return (0); 119 } 120 121 void 122 libusb_exit(libusb_context * ctx) 123 { 124 GET_CONTEXT(ctx); 125 126 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_exit enter"); 127 usb_remove_pollfd(ctx, ctx->ctrl_pipe[0]); 128 close(ctx->ctrl_pipe[0]); 129 close(ctx->ctrl_pipe[1]); 130 131 pthread_mutex_lock(&default_context_lock); 132 if (ctx == usbi_default_context) { 133 usbi_default_context = NULL; 134 } 135 pthread_mutex_unlock(&default_context_lock); 136 137 free(ctx); 138 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_exit leave"); 139 } 140 141 /* Device handling and initialisation. */ 142 143 ssize_t 144 libusb_get_device_list(libusb_context * ctx, libusb_device *** list) 145 { 146 struct libusb20_device *pdev; 147 struct LIBUSB20_DEVICE_DESC_DECODED *ddesc; 148 struct libusb_device *dev; 149 struct libusb20_backend *usb_backend; 150 int i; 151 152 GET_CONTEXT(ctx); 153 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device_list enter"); 154 155 usb_backend = libusb20_be_alloc_default(); 156 if (usb_backend == NULL) 157 return (-1); 158 159 pdev = NULL; 160 i = 0; 161 while ((pdev = libusb20_be_device_foreach(usb_backend, pdev))) 162 i++; 163 164 if (list == NULL) { 165 libusb20_be_free(usb_backend); 166 return (LIBUSB_ERROR_INVALID_PARAM); 167 } 168 *list = malloc((i + 1) * sizeof(void *)); 169 if (*list == NULL) { 170 libusb20_be_free(usb_backend); 171 return (LIBUSB_ERROR_NO_MEM); 172 } 173 i = 0; 174 while ((pdev = libusb20_be_device_foreach(usb_backend, NULL))) { 175 /* get device into libUSB v1.0 list */ 176 libusb20_be_dequeue_device(usb_backend, pdev); 177 178 ddesc = libusb20_dev_get_device_desc(pdev); 179 dev = malloc(sizeof(*dev)); 180 if (dev == NULL) { 181 while (i != 0) { 182 libusb_unref_device((*list)[i - 1]); 183 i--; 184 } 185 free(*list); 186 libusb20_be_free(usb_backend); 187 return (LIBUSB_ERROR_NO_MEM); 188 } 189 memset(dev, 0, sizeof(*dev)); 190 191 pthread_mutex_init(&dev->lock, NULL); 192 dev->ctx = ctx; 193 dev->bus_number = pdev->bus_number; 194 dev->device_address = pdev->device_address; 195 dev->num_configurations = ddesc->bNumConfigurations; 196 197 /* link together the two structures */ 198 dev->os_priv = pdev; 199 200 pthread_mutex_lock(&ctx->usb_devs_lock); 201 TAILQ_INSERT_HEAD(&ctx->usb_devs, dev, list); 202 pthread_mutex_unlock(&ctx->usb_devs_lock); 203 204 (*list)[i] = libusb_ref_device(dev); 205 i++; 206 } 207 (*list)[i] = NULL; 208 209 libusb20_be_free(usb_backend); 210 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device_list leave"); 211 return (i); 212 } 213 214 /* 215 * In this function we cant free all the device contained into list because 216 * open_with_pid_vid use some node of list after the free_device_list. 217 */ 218 void 219 libusb_free_device_list(libusb_device **list, int unref_devices) 220 { 221 int i; 222 libusb_context *ctx; 223 224 ctx = NULL; 225 GET_CONTEXT(ctx); 226 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_free_device_list enter"); 227 228 if (list == NULL) 229 return ; 230 231 if (unref_devices) { 232 for (i = 0; list[i] != NULL; i++) 233 libusb_unref_device(list[i]); 234 } 235 free(list); 236 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_free_device_list leave"); 237 } 238 239 uint8_t 240 libusb_get_bus_number(libusb_device * dev) 241 { 242 libusb_context *ctx; 243 244 ctx = NULL; 245 GET_CONTEXT(ctx); 246 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_bus_number enter"); 247 248 if (dev == NULL) 249 return (LIBUSB_ERROR_NO_DEVICE); 250 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_bus_number leave"); 251 return (dev->bus_number); 252 } 253 254 uint8_t 255 libusb_get_device_address(libusb_device * dev) 256 { 257 libusb_context *ctx; 258 259 ctx = NULL; 260 GET_CONTEXT(ctx); 261 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device_address enter"); 262 263 if (dev == NULL) 264 return (LIBUSB_ERROR_NO_DEVICE); 265 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device_address leave"); 266 return (dev->device_address); 267 } 268 269 int 270 libusb_get_max_packet_size(libusb_device *dev, unsigned char endpoint) 271 { 272 struct libusb_config_descriptor *pdconf; 273 struct libusb_interface *pinf; 274 struct libusb_interface_descriptor *pdinf; 275 struct libusb_endpoint_descriptor *pdend; 276 libusb_context *ctx; 277 int i, j, k, ret; 278 279 ctx = NULL; 280 GET_CONTEXT(ctx); 281 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_max_packet_size enter"); 282 283 if (dev == NULL) 284 return (LIBUSB_ERROR_NO_DEVICE); 285 286 if (libusb_get_active_config_descriptor(dev, &pdconf) < 0) 287 return (LIBUSB_ERROR_OTHER); 288 289 ret = LIBUSB_ERROR_NOT_FOUND; 290 for (i = 0 ; i < pdconf->bNumInterfaces ; i++) { 291 pinf = &pdconf->interface[i]; 292 for (j = 0 ; j < pinf->num_altsetting ; j++) { 293 pdinf = &pinf->altsetting[j]; 294 for (k = 0 ; k < pdinf->bNumEndpoints ; k++) { 295 pdend = &pdinf->endpoint[k]; 296 if (pdend->bEndpointAddress == endpoint) { 297 ret = pdend->wMaxPacketSize; 298 goto out; 299 } 300 } 301 } 302 } 303 304 out: 305 libusb_free_config_descriptor(pdconf); 306 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_max_packet_size leave"); 307 return (ret); 308 } 309 310 libusb_device * 311 libusb_ref_device(libusb_device * dev) 312 { 313 libusb_context *ctx; 314 315 ctx = NULL; 316 GET_CONTEXT(ctx); 317 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_ref_device enter"); 318 319 if (dev == NULL) 320 return (NULL); 321 322 pthread_mutex_lock(&dev->lock); 323 dev->refcnt++; 324 pthread_mutex_unlock(&dev->lock); 325 326 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_ref_device leave"); 327 return (dev); 328 } 329 330 void 331 libusb_unref_device(libusb_device * dev) 332 { 333 libusb_context *ctx; 334 335 ctx = NULL; 336 GET_CONTEXT(ctx); 337 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_unref_device enter"); 338 339 if (dev == NULL) 340 return; 341 342 pthread_mutex_lock(&dev->lock); 343 dev->refcnt--; 344 pthread_mutex_unlock(&dev->lock); 345 346 if (dev->refcnt == 0) { 347 pthread_mutex_lock(&dev->ctx->usb_devs_lock); 348 TAILQ_REMOVE(&ctx->usb_devs, dev, list); 349 pthread_mutex_unlock(&dev->ctx->usb_devs_lock); 350 351 libusb20_dev_free(dev->os_priv); 352 free(dev); 353 } 354 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_unref_device leave"); 355 } 356 357 int 358 libusb_open(libusb_device * dev, libusb_device_handle **devh) 359 { 360 libusb_context *ctx = dev->ctx; 361 struct libusb20_device *pdev = dev->os_priv; 362 libusb_device_handle *hdl; 363 unsigned char dummy; 364 int err; 365 366 GET_CONTEXT(ctx); 367 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open enter"); 368 369 dummy = 1; 370 if (devh == NULL) 371 return (LIBUSB_ERROR_INVALID_PARAM); 372 373 hdl = malloc(sizeof(*hdl)); 374 if (hdl == NULL) 375 return (LIBUSB_ERROR_NO_MEM); 376 377 err = libusb20_dev_open(pdev, 16 * 4 /* number of endpoints */ ); 378 if (err) { 379 free(hdl); 380 return (LIBUSB_ERROR_NO_MEM); 381 } 382 memset(hdl, 0, sizeof(*hdl)); 383 pthread_mutex_init(&hdl->lock, NULL); 384 385 TAILQ_INIT(&hdl->ep_list); 386 hdl->dev = libusb_ref_device(dev); 387 hdl->claimed_interfaces = 0; 388 hdl->os_priv = dev->os_priv; 389 err = usb_add_pollfd(ctx, libusb20_dev_get_fd(pdev), POLLIN | 390 POLLOUT | POLLRDNORM | POLLWRNORM); 391 if (err < 0) { 392 libusb_unref_device(dev); 393 free(hdl); 394 return (err); 395 } 396 397 pthread_mutex_lock(&ctx->open_devs_lock); 398 TAILQ_INSERT_HEAD(&ctx->open_devs, hdl, list); 399 pthread_mutex_unlock(&ctx->open_devs_lock); 400 401 *devh = hdl; 402 403 pthread_mutex_lock(&ctx->pollfd_modify_lock); 404 ctx->pollfd_modify++; 405 pthread_mutex_unlock(&ctx->pollfd_modify_lock); 406 407 err = write(ctx->ctrl_pipe[1], &dummy, sizeof(dummy)); 408 if (err <= 0) { 409 pthread_mutex_lock(&ctx->pollfd_modify_lock); 410 ctx->pollfd_modify--; 411 pthread_mutex_unlock(&ctx->pollfd_modify_lock); 412 return 0; 413 } 414 415 libusb_lock_events(ctx); 416 read(ctx->ctrl_pipe[0], &dummy, sizeof(dummy)); 417 pthread_mutex_lock(&ctx->pollfd_modify_lock); 418 ctx->pollfd_modify--; 419 pthread_mutex_unlock(&ctx->pollfd_modify_lock); 420 libusb_unlock_events(ctx); 421 422 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open leave"); 423 return (0); 424 } 425 426 libusb_device_handle * 427 libusb_open_device_with_vid_pid(libusb_context * ctx, uint16_t vendor_id, 428 uint16_t product_id) 429 { 430 struct libusb_device **devs; 431 struct libusb_device_handle *devh; 432 struct libusb20_device *pdev; 433 struct LIBUSB20_DEVICE_DESC_DECODED *pdesc; 434 int i, j; 435 436 GET_CONTEXT(ctx); 437 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open_device_width_vid_pid enter"); 438 439 devh = NULL; 440 441 if ((i = libusb_get_device_list(ctx, &devs)) < 0) 442 return (NULL); 443 444 for (j = 0; j < i; j++) { 445 pdev = (struct libusb20_device *)devs[j]->os_priv; 446 pdesc = libusb20_dev_get_device_desc(pdev); 447 if (pdesc->idVendor == vendor_id && 448 pdesc->idProduct == product_id) { 449 if (libusb_open(devs[j], &devh) < 0) 450 devh = NULL; 451 break ; 452 } 453 } 454 455 libusb_free_device_list(devs, 1); 456 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open_device_width_vid_pid leave"); 457 return (devh); 458 } 459 460 void 461 libusb_close(libusb_device_handle * devh) 462 { 463 libusb_context *ctx; 464 struct libusb20_device *pdev; 465 struct usb_ep_tr *eptr; 466 unsigned char dummy = 1; 467 int err; 468 469 if (devh == NULL) 470 return ; 471 472 ctx = devh->dev->ctx; 473 pdev = devh->os_priv; 474 475 GET_CONTEXT(ctx); 476 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_close enter"); 477 478 pthread_mutex_lock(&ctx->pollfd_modify_lock); 479 ctx->pollfd_modify++; 480 pthread_mutex_unlock(&ctx->pollfd_modify_lock); 481 482 err = write(ctx->ctrl_pipe[1], &dummy, sizeof(dummy)); 483 484 if (err <= 0) { 485 pthread_mutex_lock(&ctx->open_devs_lock); 486 TAILQ_REMOVE(&ctx->open_devs, devh, list); 487 pthread_mutex_unlock(&ctx->open_devs_lock); 488 489 usb_remove_pollfd(ctx, libusb20_dev_get_fd(pdev)); 490 libusb20_dev_close(pdev); 491 libusb_unref_device(devh->dev); 492 TAILQ_FOREACH(eptr, &devh->ep_list, list) { 493 TAILQ_REMOVE(&devh->ep_list, eptr, list); 494 libusb20_tr_close(((struct libusb20_transfer **) 495 eptr->os_priv)[0]); 496 if (eptr->flags) 497 libusb20_tr_close(((struct libusb20_transfer **) 498 eptr->os_priv)[1]); 499 free((struct libusb20_transfer **)eptr->os_priv); 500 } 501 free(devh); 502 503 pthread_mutex_lock(&ctx->pollfd_modify_lock); 504 ctx->pollfd_modify--; 505 pthread_mutex_unlock(&ctx->pollfd_modify_lock); 506 return ; 507 } 508 libusb_lock_events(ctx); 509 510 read(ctx->ctrl_pipe[0], &dummy, sizeof(dummy)); 511 pthread_mutex_lock(&ctx->open_devs_lock); 512 TAILQ_REMOVE(&ctx->open_devs, devh, list); 513 pthread_mutex_unlock(&ctx->open_devs_lock); 514 515 usb_remove_pollfd(ctx, libusb20_dev_get_fd(pdev)); 516 libusb20_dev_close(pdev); 517 libusb_unref_device(devh->dev); 518 TAILQ_FOREACH(eptr, &devh->ep_list, list) { 519 TAILQ_REMOVE(&devh->ep_list, eptr, list); 520 libusb20_tr_close(((struct libusb20_transfer **) 521 eptr->os_priv)[0]); 522 if (eptr->flags) 523 libusb20_tr_close(((struct libusb20_transfer **) 524 eptr->os_priv)[1]); 525 free((struct libusb20_transfer **)eptr->os_priv); 526 } 527 free(devh); 528 529 pthread_mutex_lock(&ctx->pollfd_modify_lock); 530 ctx->pollfd_modify--; 531 pthread_mutex_unlock(&ctx->pollfd_modify_lock); 532 533 libusb_unlock_events(ctx); 534 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_close leave"); 535 } 536 537 libusb_device * 538 libusb_get_device(libusb_device_handle * devh) 539 { 540 libusb_context *ctx; 541 542 ctx = NULL; 543 GET_CONTEXT(ctx); 544 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device enter"); 545 546 if (devh == NULL) 547 return (NULL); 548 549 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device leave"); 550 return (devh->dev); 551 } 552 553 int 554 libusb_get_configuration(libusb_device_handle * devh, int *config) 555 { 556 libusb_context *ctx; 557 558 ctx = NULL; 559 GET_CONTEXT(ctx); 560 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_configuration enter"); 561 562 if (devh == NULL || config == NULL) 563 return (LIBUSB_ERROR_INVALID_PARAM); 564 565 *config = libusb20_dev_get_config_index((struct libusb20_device *) 566 devh->dev->os_priv); 567 568 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_configuration leave"); 569 return (0); 570 } 571 572 int 573 libusb_set_configuration(libusb_device_handle * devh, int configuration) 574 { 575 struct libusb20_device *pdev; 576 libusb_context *ctx; 577 578 ctx = NULL; 579 GET_CONTEXT(ctx); 580 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_set_configuration enter"); 581 582 if (devh == NULL) 583 return (LIBUSB_ERROR_INVALID_PARAM); 584 585 pdev = (struct libusb20_device *)devh->dev->os_priv; 586 587 libusb20_dev_set_config_index(pdev, configuration); 588 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_set_configuration leave"); 589 return (0); 590 } 591 592 int 593 libusb_claim_interface(libusb_device_handle * dev, int interface_number) 594 { 595 libusb_context *ctx; 596 int ret = 0; 597 598 ctx = NULL; 599 GET_CONTEXT(ctx); 600 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_claim_interface enter"); 601 602 if (dev == NULL) 603 return (LIBUSB_ERROR_INVALID_PARAM); 604 605 if (interface_number >= sizeof(dev->claimed_interfaces) * 8) 606 return (LIBUSB_ERROR_INVALID_PARAM); 607 608 pthread_mutex_lock(&(dev->lock)); 609 if (dev->claimed_interfaces & (1 << interface_number)) 610 ret = LIBUSB_ERROR_BUSY; 611 612 if (!ret) 613 dev->claimed_interfaces |= (1 << interface_number); 614 pthread_mutex_unlock(&(dev->lock)); 615 616 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_claim_interface leave"); 617 return (ret); 618 } 619 620 int 621 libusb_release_interface(libusb_device_handle * dev, int interface_number) 622 { 623 libusb_context *ctx; 624 int ret; 625 626 ctx = NULL; 627 GET_CONTEXT(ctx); 628 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_release_interface enter"); 629 630 ret = 0; 631 if (dev == NULL) 632 return (LIBUSB_ERROR_INVALID_PARAM); 633 634 if (interface_number >= sizeof(dev->claimed_interfaces) * 8) 635 return (LIBUSB_ERROR_INVALID_PARAM); 636 637 pthread_mutex_lock(&(dev->lock)); 638 if (!(dev->claimed_interfaces & (1 << interface_number))) 639 ret = LIBUSB_ERROR_NOT_FOUND; 640 641 if (!ret) 642 dev->claimed_interfaces &= ~(1 << interface_number); 643 pthread_mutex_unlock(&(dev->lock)); 644 645 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_release_interface leave"); 646 return (ret); 647 } 648 649 int 650 libusb_set_interface_alt_setting(libusb_device_handle * dev, 651 int interface_number, int alternate_setting) 652 { 653 libusb_context *ctx; 654 655 ctx = NULL; 656 GET_CONTEXT(ctx); 657 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_set_interface_alt_setting enter"); 658 659 if (dev == NULL) 660 return (LIBUSB_ERROR_INVALID_PARAM); 661 662 if (interface_number >= sizeof(dev->claimed_interfaces) *8) 663 return (LIBUSB_ERROR_INVALID_PARAM); 664 665 pthread_mutex_lock(&dev->lock); 666 if (!(dev->claimed_interfaces & (1 << interface_number))) { 667 pthread_mutex_unlock(&dev->lock); 668 return (LIBUSB_ERROR_NOT_FOUND); 669 } 670 pthread_mutex_unlock(&dev->lock); 671 672 if (libusb20_dev_set_alt_index(dev->os_priv, interface_number, 673 alternate_setting) != 0) 674 return (LIBUSB_ERROR_OTHER); 675 676 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_set_interface_alt_setting leave"); 677 return (0); 678 } 679 680 int 681 libusb_clear_halt(libusb_device_handle * devh, unsigned char endpoint) 682 { 683 struct libusb20_transfer *xfer; 684 struct libusb20_device *pdev; 685 libusb_context *ctx; 686 int ret; 687 688 ctx = NULL; 689 GET_CONTEXT(ctx); 690 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_clear_halt enter"); 691 692 pdev = devh->os_priv; 693 xfer = libusb20_tr_get_pointer(pdev, 694 ((endpoint / 0x40) | (endpoint * 4)) % (16 * 4)); 695 if (xfer == NULL) 696 return (LIBUSB_ERROR_NO_MEM); 697 698 pthread_mutex_lock(&libusb20_lock); 699 ret = libusb20_tr_open(xfer, 0, 0, endpoint); 700 if (ret != 0 && ret != LIBUSB20_ERROR_BUSY) { 701 pthread_mutex_unlock(&libusb20_lock); 702 return (LIBUSB_ERROR_OTHER); 703 } 704 705 libusb20_tr_clear_stall_sync(xfer); 706 if (ret == 0) /* check if we have open the device */ 707 libusb20_tr_close(xfer); 708 pthread_mutex_unlock(&libusb20_lock); 709 710 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_clear_halt leave"); 711 return (0); 712 } 713 714 int 715 libusb_reset_device(libusb_device_handle * dev) 716 { 717 libusb_context *ctx; 718 719 ctx = NULL; 720 GET_CONTEXT(ctx); 721 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_reset_device enter"); 722 723 if (dev == NULL) 724 return (LIBUSB20_ERROR_INVALID_PARAM); 725 726 libusb20_dev_reset(dev->os_priv); 727 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_reset_device leave"); 728 return (0); 729 } 730 731 int 732 libusb_kernel_driver_active(libusb_device_handle * devh, int interface) 733 { 734 libusb_context *ctx; 735 736 ctx = NULL; 737 GET_CONTEXT(ctx); 738 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_kernel_driver_active enter"); 739 740 if (devh == NULL) 741 return (LIBUSB_ERROR_INVALID_PARAM); 742 743 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_kernel_driver_active leave"); 744 return (libusb20_dev_kernel_driver_active(devh->os_priv, interface)); 745 } 746 747 int 748 libusb_detach_kernel_driver(libusb_device_handle * devh, int interface) 749 { 750 struct libusb20_device *pdev; 751 libusb_context *ctx; 752 753 ctx = NULL; 754 GET_CONTEXT(ctx); 755 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_detach_kernel_driver enter"); 756 757 if (devh == NULL) 758 return (LIBUSB_ERROR_INVALID_PARAM); 759 760 pdev = (struct libusb20_device *)devh->dev->os_priv; 761 if (libusb20_dev_detach_kernel_driver(pdev, interface) == LIBUSB20_ERROR_OTHER) 762 return (LIBUSB_ERROR_OTHER); 763 764 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_detach_kernel_driver leave"); 765 return (0); 766 } 767 768 /* 769 * stub function. 770 * libusb20 doesn't support this feature. 771 */ 772 int 773 libusb_attach_kernel_driver(libusb_device_handle * devh, int interface) 774 { 775 libusb_context *ctx; 776 777 ctx = NULL; 778 GET_CONTEXT(ctx); 779 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_attach_kernel_driver enter"); 780 781 if (devh == NULL) 782 return (LIBUSB_ERROR_INVALID_PARAM); 783 784 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_attach_kernel_driver leave"); 785 return (0); 786 } 787 788 /* Asynchronous device I/O */ 789 790 struct libusb_transfer * 791 libusb_alloc_transfer(int iso_packets) 792 { 793 struct libusb_transfer *xfer; 794 struct usb_transfer *bxfer; 795 libusb_context *ctx; 796 int len; 797 798 ctx = NULL; 799 GET_CONTEXT(ctx); 800 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_alloc_transfer enter"); 801 802 len = sizeof(struct libusb_transfer) + 803 sizeof(struct usb_transfer) + 804 (iso_packets * sizeof(libusb_iso_packet_descriptor)); 805 806 bxfer = malloc(len); 807 if (bxfer == NULL) 808 return (NULL); 809 810 memset(bxfer, 0, len); 811 bxfer->num_iso_packets = iso_packets; 812 813 xfer = (struct libusb_transfer *) ((uint8_t *)bxfer + 814 sizeof(struct usb_transfer)); 815 816 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_alloc_transfer leave"); 817 return (xfer); 818 } 819 820 void 821 libusb_free_transfer(struct libusb_transfer *xfer) 822 { 823 struct usb_transfer *bxfer; 824 libusb_context *ctx; 825 826 ctx = NULL; 827 GET_CONTEXT(ctx); 828 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_free_transfer enter"); 829 830 if (xfer == NULL) 831 return ; 832 833 bxfer = (struct usb_transfer *) ((uint8_t *)xfer - 834 sizeof(struct usb_transfer)); 835 836 free(bxfer); 837 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_free_transfer leave"); 838 return; 839 } 840 841 static int 842 libusb_get_maxframe(struct libusb20_device *pdev, libusb_transfer *xfer) 843 { 844 int ret; 845 int usb_speed; 846 847 usb_speed = libusb20_dev_get_speed(pdev); 848 849 switch (xfer->type) { 850 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: 851 switch (usb_speed) { 852 case LIBUSB20_SPEED_LOW: 853 case LIBUSB20_SPEED_FULL: 854 ret = 60 * 1; 855 break ; 856 default : 857 ret = 60 * 8; 858 break ; 859 } 860 break ; 861 case LIBUSB_TRANSFER_TYPE_CONTROL: 862 ret = 2; 863 break ; 864 default: 865 ret = 1; 866 break ; 867 } 868 869 return ret; 870 } 871 872 static int 873 libusb_get_buffsize(struct libusb20_device *pdev, libusb_transfer *xfer) 874 { 875 int ret; 876 int usb_speed; 877 878 usb_speed = libusb20_dev_get_speed(pdev); 879 880 switch (xfer->type) { 881 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: 882 ret = 0; 883 break ; 884 case LIBUSB_TRANSFER_TYPE_CONTROL: 885 switch (usb_speed) { 886 case LIBUSB20_SPEED_LOW: 887 ret = 8; 888 break ; 889 case LIBUSB20_SPEED_FULL: 890 ret = 64; 891 break ; 892 default: 893 ret = 64; 894 break ; 895 } 896 ret += 8; 897 break ; 898 default : 899 switch (usb_speed) { 900 case LIBUSB20_SPEED_LOW: 901 ret = 256; 902 break ; 903 case LIBUSB20_SPEED_FULL: 904 ret = 4096; 905 break ; 906 default: 907 ret = 16384; 908 break ; 909 } 910 break ; 911 } 912 913 return ret; 914 } 915 916 static void 917 libusb10_proxy(struct libusb20_transfer *xfer) 918 { 919 struct usb_transfer *usb_backend; 920 struct libusb20_device *pdev; 921 libusb_transfer *usb_xfer; 922 libusb_context *ctx; 923 uint32_t pos; 924 uint32_t max; 925 uint32_t size; 926 uint8_t status; 927 uint32_t iso_packets; 928 int i; 929 930 status = libusb20_tr_get_status(xfer); 931 usb_xfer = libusb20_tr_get_priv_sc0(xfer); 932 usb_backend = (struct usb_transfer *) ((uint8_t *)usb_xfer - 933 sizeof(struct usb_transfer)); 934 pdev = usb_xfer->dev_handle->dev->os_priv; 935 ctx = usb_xfer->dev_handle->dev->ctx; 936 GET_CONTEXT(ctx); 937 938 switch (status) { 939 case LIBUSB20_TRANSFER_COMPLETED: 940 usb_backend->transferred += libusb20_tr_get_actual_length(xfer); 941 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "LIBUSB20 TRANSFER %i bytes", 942 usb_backend->transferred); 943 if (usb_backend->transferred != usb_xfer->length) 944 goto tr_start; 945 946 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "LIBUSB20 TRANSFER COMPLETE"); 947 usb_handle_transfer_completion(usb_backend, LIBUSB_TRANSFER_COMPLETED); 948 949 break ; 950 case LIBUSB20_TRANSFER_START: 951 tr_start: 952 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "LIBUSB20 START"); 953 max = libusb_get_buffsize(pdev, usb_xfer); 954 pos = usb_backend->transferred; 955 size = (usb_xfer->length - pos); 956 size = (size > max) ? max : size; 957 usb_xfer->actual_length = 0; 958 switch (usb_xfer->type) { 959 case LIBUSB_TRANSFER_TYPE_CONTROL: 960 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "TYPE CTR"); 961 libusb20_tr_setup_control(xfer, usb_xfer->buffer, 962 (void *)(((uint8_t *) &usb_xfer->buffer[pos]) + 963 sizeof(libusb_control_setup)), 964 usb_xfer->timeout); 965 break ; 966 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: 967 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "TYPE ISO"); 968 iso_packets = libusb20_tr_get_max_frames(xfer); 969 if (usb_xfer->num_iso_packets > iso_packets) 970 usb_xfer->num_iso_packets = iso_packets; 971 for (i = 0 ; i < usb_xfer->num_iso_packets ; i++) { 972 libusb20_tr_setup_isoc(xfer, 973 &usb_xfer->buffer[pos], size, i); 974 } 975 libusb20_tr_set_total_frames(xfer, i); 976 break ; 977 case LIBUSB_TRANSFER_TYPE_BULK: 978 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "TYPE BULK"); 979 libusb20_tr_setup_bulk(xfer, &usb_xfer->buffer[pos], 980 size, usb_xfer->timeout); 981 break ; 982 case LIBUSB_TRANSFER_TYPE_INTERRUPT: 983 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "TYPE INTR"); 984 libusb20_tr_setup_intr(xfer, &usb_xfer->buffer[pos], 985 size, usb_xfer->timeout); 986 break ; 987 } 988 libusb20_tr_submit(xfer); 989 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "LIBUSB20 SUBMITED"); 990 break ; 991 default: 992 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "TRANSFER DEFAULT 0x%x\n", 993 status); 994 usb_backend->transferred = 0; 995 usb_handle_transfer_completion(usb_backend, LIBUSB_TRANSFER_CANCELLED); 996 break ; 997 } 998 999 switch (status) { 1000 case LIBUSB20_TRANSFER_COMPLETED: 1001 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS COMPLETED"); 1002 usb_xfer->status = LIBUSB_TRANSFER_COMPLETED; 1003 break ; 1004 case LIBUSB20_TRANSFER_OVERFLOW: 1005 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS TR OVERFLOW"); 1006 usb_xfer->status = LIBUSB_TRANSFER_OVERFLOW; 1007 break ; 1008 case LIBUSB20_TRANSFER_NO_DEVICE: 1009 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS TR NO DEVICE"); 1010 usb_xfer->status = LIBUSB_TRANSFER_NO_DEVICE; 1011 break ; 1012 case LIBUSB20_TRANSFER_STALL: 1013 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS TR STALL"); 1014 usb_xfer->status = LIBUSB_TRANSFER_STALL; 1015 break ; 1016 case LIBUSB20_TRANSFER_CANCELLED: 1017 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS TR CANCELLED"); 1018 usb_xfer->status = LIBUSB_TRANSFER_CANCELLED; 1019 break ; 1020 case LIBUSB20_TRANSFER_TIMED_OUT: 1021 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS TR TIMEOUT"); 1022 usb_xfer->status = LIBUSB_TRANSFER_TIMED_OUT; 1023 break ; 1024 case LIBUSB20_TRANSFER_ERROR: 1025 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "ERROR"); 1026 usb_xfer->status = LIBUSB_TRANSFER_ERROR; 1027 break ; 1028 } 1029 } 1030 1031 int 1032 libusb_submit_transfer(struct libusb_transfer *xfer) 1033 { 1034 struct libusb20_transfer **usb20_xfer; 1035 struct usb_transfer *usb_backend; 1036 struct usb_transfer *usb_node; 1037 struct libusb20_device *pdev; 1038 struct usb_ep_tr *eptr; 1039 struct timespec cur_ts; 1040 struct timeval *cur_tv; 1041 libusb_device_handle *devh; 1042 libusb_context *ctx; 1043 int maxframe; 1044 int buffsize; 1045 int ep_idx; 1046 int ret; 1047 1048 if (xfer == NULL) 1049 return (LIBUSB_ERROR_NO_MEM); 1050 1051 usb20_xfer = malloc(2 * sizeof(struct libusb20_transfer *)); 1052 if (usb20_xfer == NULL) 1053 return (LIBUSB_ERROR_NO_MEM); 1054 1055 ctx = xfer->dev_handle->dev->ctx; 1056 pdev = xfer->dev_handle->os_priv; 1057 devh = xfer->dev_handle; 1058 1059 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_submit_transfer enter"); 1060 1061 usb_backend = (struct usb_transfer *) ((uint8_t *)xfer - 1062 sizeof(struct usb_transfer)); 1063 usb_backend->transferred = 0; 1064 usb_backend->flags = 0; 1065 1066 if (xfer->timeout != 0) { 1067 clock_gettime(CLOCK_MONOTONIC, &cur_ts); 1068 cur_ts.tv_sec += xfer->timeout / 1000; 1069 cur_ts.tv_nsec += (xfer->timeout % 1000) * 1000000; 1070 1071 if (cur_ts.tv_nsec > 1000000000) { 1072 cur_ts.tv_nsec -= 1000000000; 1073 cur_ts.tv_sec++; 1074 } 1075 1076 TIMESPEC_TO_TIMEVAL(&usb_backend->timeout, &cur_ts); 1077 } 1078 1079 /*Add to flying list*/ 1080 pthread_mutex_lock(&ctx->flying_transfers_lock); 1081 if (TAILQ_EMPTY(&ctx->flying_transfers)) { 1082 TAILQ_INSERT_HEAD(&ctx->flying_transfers, usb_backend, list); 1083 goto out; 1084 } 1085 if (timerisset(&usb_backend->timeout) == 0) { 1086 TAILQ_INSERT_HEAD(&ctx->flying_transfers, usb_backend, list); 1087 goto out; 1088 } 1089 TAILQ_FOREACH(usb_node, &ctx->flying_transfers, list) { 1090 cur_tv = &usb_node->timeout; 1091 if (timerisset(cur_tv) == 0 || 1092 (cur_tv->tv_sec > usb_backend->timeout.tv_sec) || 1093 (cur_tv->tv_sec == usb_backend->timeout.tv_sec && 1094 cur_tv->tv_usec > usb_backend->timeout.tv_usec)) { 1095 TAILQ_INSERT_TAIL(&ctx->flying_transfers, usb_backend, list); 1096 goto out; 1097 } 1098 } 1099 TAILQ_INSERT_TAIL(&ctx->flying_transfers, usb_backend, list); 1100 1101 out: 1102 pthread_mutex_unlock(&ctx->flying_transfers_lock); 1103 1104 ep_idx = (xfer->endpoint / 0x40) | (xfer->endpoint * 4) % (16 * 4); 1105 usb20_xfer[0] = libusb20_tr_get_pointer(pdev, ep_idx); 1106 usb20_xfer[1] = libusb20_tr_get_pointer(pdev, ep_idx + 1); 1107 1108 if (usb20_xfer[0] == NULL) 1109 return (LIBUSB_ERROR_OTHER); 1110 1111 xfer->os_priv = usb20_xfer; 1112 1113 pthread_mutex_lock(&libusb20_lock); 1114 1115 buffsize = libusb_get_buffsize(pdev, xfer); 1116 maxframe = libusb_get_maxframe(pdev, xfer); 1117 1118 ret = 0; 1119 TAILQ_FOREACH(eptr, &devh->ep_list, list) { 1120 if (xfer->endpoint == eptr->addr) 1121 ret++; 1122 } 1123 if (ret == 0) { 1124 eptr = malloc(sizeof(struct usb_ep_tr)); 1125 eptr->addr = xfer->endpoint; 1126 eptr->idx = ep_idx; 1127 eptr->os_priv = usb20_xfer; 1128 eptr->flags = (xfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS)?1:0; 1129 TAILQ_INSERT_HEAD(&devh->ep_list, eptr, list); 1130 ret = libusb20_tr_open(usb20_xfer[0], buffsize, 1131 maxframe, xfer->endpoint); 1132 if (xfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) 1133 ret |= libusb20_tr_open(usb20_xfer[1], buffsize, 1134 maxframe, xfer->endpoint); 1135 1136 if (ret != 0) { 1137 pthread_mutex_unlock(&libusb20_lock); 1138 pthread_mutex_lock(&ctx->flying_transfers_lock); 1139 TAILQ_REMOVE(&ctx->flying_transfers, usb_backend, list); 1140 pthread_mutex_unlock(&ctx->flying_transfers_lock); 1141 return (LIBUSB_ERROR_OTHER); 1142 } 1143 } 1144 1145 libusb20_tr_set_priv_sc0(usb20_xfer[0], xfer); 1146 libusb20_tr_set_callback(usb20_xfer[0], libusb10_proxy); 1147 if (xfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) { 1148 libusb20_tr_set_priv_sc0(usb20_xfer[1], xfer); 1149 libusb20_tr_set_callback(usb20_xfer[1], libusb10_proxy); 1150 } 1151 1152 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "LIBUSB20_TR_START"); 1153 libusb20_tr_start(usb20_xfer[0]); 1154 if (xfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) 1155 libusb20_tr_start(usb20_xfer[1]); 1156 1157 pthread_mutex_unlock(&libusb20_lock); 1158 1159 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_submit_transfer leave"); 1160 return (0); 1161 } 1162 1163 int 1164 libusb_cancel_transfer(struct libusb_transfer *xfer) 1165 { 1166 libusb_context *ctx; 1167 1168 ctx = NULL; 1169 GET_CONTEXT(ctx); 1170 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_cancel_transfer enter"); 1171 1172 if (xfer == NULL) 1173 return (LIBUSB_ERROR_NO_MEM); 1174 1175 pthread_mutex_lock(&libusb20_lock); 1176 libusb20_tr_stop(xfer->os_priv); 1177 pthread_mutex_unlock(&libusb20_lock); 1178 1179 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_cancel_transfer leave"); 1180 return (0); 1181 } 1182 1183