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