1/* $FreeBSD: head/lib/libusb/libusb10.c 195957 2009-07-30 00:11:41Z alfred $ */
|
1/* $FreeBSD: head/lib/libusb/libusb10.c 199055 2009-11-08 20:03:52Z thompsa $ */ |
2/*- 3 * Copyright (c) 2009 Sylvestre Gallon. All rights reserved. 4 * Copyright (c) 2009 Hans Petter Selasky. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 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#include <sys/ioctl.h> 36#include <sys/filio.h> 37#include <sys/queue.h>
|
38#include <sys/endian.h> |
39 40#include "libusb20.h" 41#include "libusb20_desc.h" 42#include "libusb20_int.h" 43#include "libusb.h" 44#include "libusb10.h" 45 46static pthread_mutex_t default_context_lock = PTHREAD_MUTEX_INITIALIZER; 47struct libusb_context *usbi_default_context = NULL; 48 49/* Prototypes */ 50 51static struct libusb20_transfer *libusb10_get_transfer(struct libusb20_device *, uint8_t, uint8_t); 52static int libusb10_get_maxframe(struct libusb20_device *, libusb_transfer *); 53static int libusb10_get_buffsize(struct libusb20_device *, libusb_transfer *); 54static int libusb10_convert_error(uint8_t status); 55static void libusb10_complete_transfer(struct libusb20_transfer *, struct libusb_super_transfer *, int); 56static void libusb10_isoc_proxy(struct libusb20_transfer *); 57static void libusb10_bulk_intr_proxy(struct libusb20_transfer *); 58static void libusb10_ctrl_proxy(struct libusb20_transfer *); 59static void libusb10_submit_transfer_sub(struct libusb20_device *, uint8_t); 60 61/* Library initialisation / deinitialisation */ 62 63void 64libusb_set_debug(libusb_context *ctx, int level) 65{ 66 ctx = GET_CONTEXT(ctx); 67 if (ctx) 68 ctx->debug = level; 69} 70 71int 72libusb_init(libusb_context **context) 73{ 74 struct libusb_context *ctx; 75 char *debug; 76 int ret; 77 78 ctx = malloc(sizeof(*ctx)); 79 if (!ctx) 80 return (LIBUSB_ERROR_INVALID_PARAM); 81 82 memset(ctx, 0, sizeof(*ctx)); 83 84 debug = getenv("LIBUSB_DEBUG"); 85 if (debug != NULL) { 86 ctx->debug = atoi(debug); 87 if (ctx->debug != 0) 88 ctx->debug_fixed = 1; 89 } 90 TAILQ_INIT(&ctx->pollfds); 91 TAILQ_INIT(&ctx->tr_done); 92 93 pthread_mutex_init(&ctx->ctx_lock, NULL); 94 pthread_cond_init(&ctx->ctx_cond, NULL); 95 96 ctx->ctx_handler = NO_THREAD; 97 98 ret = pipe(ctx->ctrl_pipe); 99 if (ret < 0) { 100 pthread_mutex_destroy(&ctx->ctx_lock); 101 pthread_cond_destroy(&ctx->ctx_cond); 102 free(ctx); 103 return (LIBUSB_ERROR_OTHER); 104 } 105 /* set non-blocking mode on the control pipe to avoid deadlock */ 106 ret = 1; 107 ioctl(ctx->ctrl_pipe[0], FIONBIO, &ret); 108 ret = 1; 109 ioctl(ctx->ctrl_pipe[1], FIONBIO, &ret); 110 111 libusb10_add_pollfd(ctx, &ctx->ctx_poll, NULL, ctx->ctrl_pipe[0], POLLIN); 112 113 pthread_mutex_lock(&default_context_lock); 114 if (usbi_default_context == NULL) { 115 usbi_default_context = ctx; 116 } 117 pthread_mutex_unlock(&default_context_lock); 118 119 if (context) 120 *context = ctx; 121 122 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_init complete"); 123 124 return (0); 125} 126 127void 128libusb_exit(libusb_context *ctx) 129{ 130 ctx = GET_CONTEXT(ctx); 131 132 if (ctx == NULL) 133 return; 134 135 /* XXX cleanup devices */ 136 137 libusb10_remove_pollfd(ctx, &ctx->ctx_poll); 138 close(ctx->ctrl_pipe[0]); 139 close(ctx->ctrl_pipe[1]); 140 pthread_mutex_destroy(&ctx->ctx_lock); 141 pthread_cond_destroy(&ctx->ctx_cond); 142 143 pthread_mutex_lock(&default_context_lock); 144 if (ctx == usbi_default_context) { 145 usbi_default_context = NULL; 146 } 147 pthread_mutex_unlock(&default_context_lock); 148 149 free(ctx); 150} 151 152/* Device handling and initialisation. */ 153 154ssize_t 155libusb_get_device_list(libusb_context *ctx, libusb_device ***list) 156{ 157 struct libusb20_backend *usb_backend; 158 struct libusb20_device *pdev; 159 struct libusb_device *dev; 160 int i; 161 162 ctx = GET_CONTEXT(ctx); 163 164 if (ctx == NULL) 165 return (LIBUSB_ERROR_INVALID_PARAM); 166 167 if (list == NULL) 168 return (LIBUSB_ERROR_INVALID_PARAM); 169 170 usb_backend = libusb20_be_alloc_default(); 171 if (usb_backend == NULL) 172 return (LIBUSB_ERROR_NO_MEM); 173 174 /* figure out how many USB devices are present */ 175 pdev = NULL; 176 i = 0; 177 while ((pdev = libusb20_be_device_foreach(usb_backend, pdev))) 178 i++; 179 180 /* allocate device pointer list */ 181 *list = malloc((i + 1) * sizeof(void *)); 182 if (*list == NULL) { 183 libusb20_be_free(usb_backend); 184 return (LIBUSB_ERROR_NO_MEM); 185 } 186 /* create libusb v1.0 compliant devices */ 187 i = 0; 188 while ((pdev = libusb20_be_device_foreach(usb_backend, NULL))) {
|
188 /* get device into libUSB v1.0 list */
189 libusb20_be_dequeue_device(usb_backend, pdev);
|
189 190 dev = malloc(sizeof(*dev)); 191 if (dev == NULL) { 192 while (i != 0) { 193 libusb_unref_device((*list)[i - 1]); 194 i--; 195 } 196 free(*list); 197 *list = NULL; 198 libusb20_be_free(usb_backend); 199 return (LIBUSB_ERROR_NO_MEM); 200 }
|
201 202 /* get device into libUSB v1.0 list */ 203 libusb20_be_dequeue_device(usb_backend, pdev); 204 |
205 memset(dev, 0, sizeof(*dev)); 206 207 /* init transfer queues */ 208 TAILQ_INIT(&dev->tr_head); 209 210 /* set context we belong to */ 211 dev->ctx = ctx; 212 213 /* link together the two structures */ 214 dev->os_priv = pdev; 215 pdev->privLuData = dev; 216 217 (*list)[i] = libusb_ref_device(dev); 218 i++; 219 } 220 (*list)[i] = NULL; 221 222 libusb20_be_free(usb_backend); 223 return (i); 224} 225 226void 227libusb_free_device_list(libusb_device **list, int unref_devices) 228{ 229 int i; 230 231 if (list == NULL) 232 return; /* be NULL safe */ 233 234 if (unref_devices) { 235 for (i = 0; list[i] != NULL; i++) 236 libusb_unref_device(list[i]); 237 } 238 free(list); 239} 240 241uint8_t 242libusb_get_bus_number(libusb_device *dev) 243{ 244 if (dev == NULL) 245 return (0); /* should not happen */ 246 return (libusb20_dev_get_bus_number(dev->os_priv)); 247} 248 249uint8_t 250libusb_get_device_address(libusb_device *dev) 251{ 252 if (dev == NULL) 253 return (0); /* should not happen */ 254 return (libusb20_dev_get_address(dev->os_priv)); 255} 256 257int 258libusb_get_max_packet_size(libusb_device *dev, uint8_t endpoint) 259{ 260 struct libusb_config_descriptor *pdconf; 261 struct libusb_interface *pinf; 262 struct libusb_interface_descriptor *pdinf; 263 struct libusb_endpoint_descriptor *pdend; 264 int i; 265 int j; 266 int k; 267 int ret; 268 269 if (dev == NULL) 270 return (LIBUSB_ERROR_NO_DEVICE); 271 272 ret = libusb_get_active_config_descriptor(dev, &pdconf); 273 if (ret < 0) 274 return (ret); 275 276 ret = LIBUSB_ERROR_NOT_FOUND; 277 for (i = 0; i < pdconf->bNumInterfaces; i++) { 278 pinf = &pdconf->interface[i]; 279 for (j = 0; j < pinf->num_altsetting; j++) { 280 pdinf = &pinf->altsetting[j]; 281 for (k = 0; k < pdinf->bNumEndpoints; k++) { 282 pdend = &pdinf->endpoint[k]; 283 if (pdend->bEndpointAddress == endpoint) { 284 ret = pdend->wMaxPacketSize; 285 goto out; 286 } 287 } 288 } 289 } 290 291out: 292 libusb_free_config_descriptor(pdconf); 293 return (ret); 294} 295 296libusb_device * 297libusb_ref_device(libusb_device *dev) 298{ 299 if (dev == NULL) 300 return (NULL); /* be NULL safe */ 301 302 CTX_LOCK(dev->ctx); 303 dev->refcnt++; 304 CTX_UNLOCK(dev->ctx); 305 306 return (dev); 307} 308 309void 310libusb_unref_device(libusb_device *dev) 311{ 312 if (dev == NULL) 313 return; /* be NULL safe */ 314 315 CTX_LOCK(dev->ctx); 316 dev->refcnt--; 317 CTX_UNLOCK(dev->ctx); 318 319 if (dev->refcnt == 0) { 320 libusb20_dev_free(dev->os_priv); 321 free(dev); 322 } 323} 324 325int 326libusb_open(libusb_device *dev, libusb_device_handle **devh) 327{ 328 libusb_context *ctx = dev->ctx; 329 struct libusb20_device *pdev = dev->os_priv; 330 uint8_t dummy; 331 int err; 332 333 if (devh == NULL) 334 return (LIBUSB_ERROR_INVALID_PARAM); 335 336 /* set default device handle value */ 337 *devh = NULL; 338 339 dev = libusb_ref_device(dev); 340 if (dev == NULL) 341 return (LIBUSB_ERROR_INVALID_PARAM); 342 343 err = libusb20_dev_open(pdev, 16 * 4 /* number of endpoints */ ); 344 if (err) { 345 libusb_unref_device(dev); 346 return (LIBUSB_ERROR_NO_MEM); 347 } 348 libusb10_add_pollfd(ctx, &dev->dev_poll, pdev, libusb20_dev_get_fd(pdev), POLLIN | 349 POLLOUT | POLLRDNORM | POLLWRNORM); 350 351 /* make sure our event loop detects the new device */ 352 dummy = 0; 353 err = write(ctx->ctrl_pipe[1], &dummy, sizeof(dummy)); 354 if (err < sizeof(dummy)) { 355 /* ignore error, if any */ 356 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open write failed!"); 357 } 358 *devh = pdev; 359 360 return (0); 361} 362 363libusb_device_handle * 364libusb_open_device_with_vid_pid(libusb_context *ctx, uint16_t vendor_id, 365 uint16_t product_id) 366{ 367 struct libusb_device **devs; 368 struct libusb20_device *pdev; 369 struct LIBUSB20_DEVICE_DESC_DECODED *pdesc; 370 int i; 371 int j; 372 373 ctx = GET_CONTEXT(ctx); 374 if (ctx == NULL) 375 return (NULL); /* be NULL safe */ 376 377 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open_device_width_vid_pid enter"); 378 379 if ((i = libusb_get_device_list(ctx, &devs)) < 0) 380 return (NULL); 381 382 pdev = NULL; 383 384 for (j = 0; j < i; j++) { 385 pdev = devs[j]->os_priv; 386 pdesc = libusb20_dev_get_device_desc(pdev); 387 /* 388 * NOTE: The USB library will automatically swap the 389 * fields in the device descriptor to be of host 390 * endian type! 391 */ 392 if (pdesc->idVendor == vendor_id && 393 pdesc->idProduct == product_id) { 394 if (libusb_open(devs[j], &pdev) < 0) 395 pdev = NULL; 396 break; 397 } 398 } 399 400 libusb_free_device_list(devs, 1); 401 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open_device_width_vid_pid leave"); 402 return (pdev); 403} 404 405void 406libusb_close(struct libusb20_device *pdev) 407{ 408 libusb_context *ctx; 409 struct libusb_device *dev; 410 uint8_t dummy; 411 int err; 412 413 if (pdev == NULL) 414 return; /* be NULL safe */ 415 416 dev = libusb_get_device(pdev); 417 ctx = dev->ctx; 418 419 libusb10_remove_pollfd(ctx, &dev->dev_poll); 420 421 libusb20_dev_close(pdev);
|
422 423 /* unref will free the "pdev" when the refcount reaches zero */ |
424 libusb_unref_device(dev); 425 426 /* make sure our event loop detects the closed device */ 427 dummy = 0; 428 err = write(ctx->ctrl_pipe[1], &dummy, sizeof(dummy)); 429 if (err < sizeof(dummy)) { 430 /* ignore error, if any */ 431 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_close write failed!"); 432 } 433} 434 435libusb_device * 436libusb_get_device(struct libusb20_device *pdev) 437{ 438 if (pdev == NULL) 439 return (NULL); 440 return ((libusb_device *)pdev->privLuData); 441} 442 443int 444libusb_get_configuration(struct libusb20_device *pdev, int *config) 445{ 446 struct libusb20_config *pconf; 447 448 if (pdev == NULL || config == NULL) 449 return (LIBUSB_ERROR_INVALID_PARAM); 450 451 pconf = libusb20_dev_alloc_config(pdev, libusb20_dev_get_config_index(pdev)); 452 if (pconf == NULL) 453 return (LIBUSB_ERROR_NO_MEM); 454 455 *config = pconf->desc.bConfigurationValue; 456 457 free(pconf); 458 459 return (0); 460} 461 462int 463libusb_set_configuration(struct libusb20_device *pdev, int configuration) 464{ 465 struct libusb20_config *pconf; 466 struct libusb_device *dev; 467 int err; 468 uint8_t i; 469 470 dev = libusb_get_device(pdev); 471 472 if (dev == NULL) 473 return (LIBUSB_ERROR_INVALID_PARAM); 474 475 if (configuration < 1) { 476 /* unconfigure */ 477 i = 255; 478 } else { 479 for (i = 0; i != 255; i++) { 480 uint8_t found; 481 482 pconf = libusb20_dev_alloc_config(pdev, i); 483 if (pconf == NULL) 484 return (LIBUSB_ERROR_INVALID_PARAM); 485 found = (pconf->desc.bConfigurationValue 486 == configuration); 487 free(pconf); 488 489 if (found) 490 goto set_config; 491 } 492 return (LIBUSB_ERROR_INVALID_PARAM); 493 } 494 495set_config: 496 497 libusb10_cancel_all_transfer(dev); 498 499 libusb10_remove_pollfd(dev->ctx, &dev->dev_poll); 500 501 err = libusb20_dev_set_config_index(pdev, i); 502 503 libusb10_add_pollfd(dev->ctx, &dev->dev_poll, pdev, libusb20_dev_get_fd(pdev), POLLIN | 504 POLLOUT | POLLRDNORM | POLLWRNORM); 505 506 return (err ? LIBUSB_ERROR_INVALID_PARAM : 0); 507} 508 509int 510libusb_claim_interface(struct libusb20_device *pdev, int interface_number) 511{ 512 libusb_device *dev; 513 int err = 0; 514 515 dev = libusb_get_device(pdev); 516 if (dev == NULL) 517 return (LIBUSB_ERROR_INVALID_PARAM); 518 519 if (interface_number < 0 || interface_number > 31) 520 return (LIBUSB_ERROR_INVALID_PARAM); 521 522 CTX_LOCK(dev->ctx); 523 if (dev->claimed_interfaces & (1 << interface_number)) 524 err = LIBUSB_ERROR_BUSY; 525 526 if (!err) 527 dev->claimed_interfaces |= (1 << interface_number); 528 CTX_UNLOCK(dev->ctx); 529 return (err); 530} 531 532int 533libusb_release_interface(struct libusb20_device *pdev, int interface_number) 534{ 535 libusb_device *dev; 536 int err = 0; 537 538 dev = libusb_get_device(pdev); 539 if (dev == NULL) 540 return (LIBUSB_ERROR_INVALID_PARAM); 541 542 if (interface_number < 0 || interface_number > 31) 543 return (LIBUSB_ERROR_INVALID_PARAM); 544 545 CTX_LOCK(dev->ctx); 546 if (!(dev->claimed_interfaces & (1 << interface_number))) 547 err = LIBUSB_ERROR_NOT_FOUND; 548 549 if (!err) 550 dev->claimed_interfaces &= ~(1 << interface_number); 551 CTX_UNLOCK(dev->ctx); 552 return (err); 553} 554 555int 556libusb_set_interface_alt_setting(struct libusb20_device *pdev, 557 int interface_number, int alternate_setting) 558{ 559 libusb_device *dev; 560 int err = 0; 561 562 dev = libusb_get_device(pdev); 563 if (dev == NULL) 564 return (LIBUSB_ERROR_INVALID_PARAM); 565 566 if (interface_number < 0 || interface_number > 31) 567 return (LIBUSB_ERROR_INVALID_PARAM); 568 569 CTX_LOCK(dev->ctx); 570 if (!(dev->claimed_interfaces & (1 << interface_number))) 571 err = LIBUSB_ERROR_NOT_FOUND; 572 CTX_UNLOCK(dev->ctx); 573 574 if (err) 575 return (err); 576 577 libusb10_cancel_all_transfer(dev); 578 579 libusb10_remove_pollfd(dev->ctx, &dev->dev_poll); 580 581 err = libusb20_dev_set_alt_index(pdev, 582 interface_number, alternate_setting); 583 584 libusb10_add_pollfd(dev->ctx, &dev->dev_poll, 585 pdev, libusb20_dev_get_fd(pdev), 586 POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM); 587 588 return (err ? LIBUSB_ERROR_OTHER : 0); 589} 590 591static struct libusb20_transfer * 592libusb10_get_transfer(struct libusb20_device *pdev, 593 uint8_t endpoint, uint8_t index) 594{ 595 index &= 1; /* double buffering */ 596 597 index |= (endpoint & LIBUSB20_ENDPOINT_ADDRESS_MASK) * 4; 598 599 if (endpoint & LIBUSB20_ENDPOINT_DIR_MASK) { 600 /* this is an IN endpoint */ 601 index |= 2; 602 } 603 return (libusb20_tr_get_pointer(pdev, index)); 604} 605 606int 607libusb_clear_halt(struct libusb20_device *pdev, uint8_t endpoint) 608{ 609 struct libusb20_transfer *xfer; 610 struct libusb_device *dev; 611 int err; 612 613 xfer = libusb10_get_transfer(pdev, endpoint, 0); 614 if (xfer == NULL) 615 return (LIBUSB_ERROR_INVALID_PARAM); 616 617 dev = libusb_get_device(pdev); 618 619 CTX_LOCK(dev->ctx); 620 err = libusb20_tr_open(xfer, 0, 0, endpoint); 621 CTX_UNLOCK(dev->ctx); 622 623 if (err != 0 && err != LIBUSB20_ERROR_BUSY) 624 return (LIBUSB_ERROR_OTHER); 625 626 libusb20_tr_clear_stall_sync(xfer); 627 628 /* check if we opened the transfer */ 629 if (err == 0) { 630 CTX_LOCK(dev->ctx); 631 libusb20_tr_close(xfer); 632 CTX_UNLOCK(dev->ctx); 633 } 634 return (0); /* success */ 635} 636 637int 638libusb_reset_device(struct libusb20_device *pdev) 639{ 640 libusb_device *dev; 641 int err; 642 643 dev = libusb_get_device(pdev); 644 if (dev == NULL) 645 return (LIBUSB20_ERROR_INVALID_PARAM); 646 647 libusb10_cancel_all_transfer(dev); 648 649 libusb10_remove_pollfd(dev->ctx, &dev->dev_poll); 650 651 err = libusb20_dev_reset(pdev); 652 653 libusb10_add_pollfd(dev->ctx, &dev->dev_poll, 654 pdev, libusb20_dev_get_fd(pdev), 655 POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM); 656 657 return (err ? LIBUSB_ERROR_OTHER : 0); 658} 659 660int 661libusb_kernel_driver_active(struct libusb20_device *pdev, int interface) 662{ 663 if (pdev == NULL) 664 return (LIBUSB_ERROR_INVALID_PARAM); 665 666 return (libusb20_dev_kernel_driver_active( 667 pdev, interface)); 668} 669 670int 671libusb_detach_kernel_driver(struct libusb20_device *pdev, int interface) 672{ 673 int err; 674 675 if (pdev == NULL) 676 return (LIBUSB_ERROR_INVALID_PARAM); 677 678 err = libusb20_dev_detach_kernel_driver( 679 pdev, interface); 680 681 return (err ? LIBUSB20_ERROR_OTHER : 0); 682} 683 684int 685libusb_attach_kernel_driver(struct libusb20_device *pdev, int interface) 686{ 687 if (pdev == NULL) 688 return (LIBUSB_ERROR_INVALID_PARAM); 689 /* stub - currently not supported by libusb20 */ 690 return (0); 691} 692 693/* Asynchronous device I/O */ 694 695struct libusb_transfer * 696libusb_alloc_transfer(int iso_packets) 697{ 698 struct libusb_transfer *uxfer; 699 struct libusb_super_transfer *sxfer; 700 int len; 701 702 len = sizeof(struct libusb_transfer) + 703 sizeof(struct libusb_super_transfer) + 704 (iso_packets * sizeof(libusb_iso_packet_descriptor)); 705 706 sxfer = malloc(len); 707 if (sxfer == NULL) 708 return (NULL); 709 710 memset(sxfer, 0, len); 711 712 uxfer = (struct libusb_transfer *)( 713 ((uint8_t *)sxfer) + sizeof(*sxfer)); 714 715 /* set default value */ 716 uxfer->num_iso_packets = iso_packets; 717 718 return (uxfer); 719} 720 721void 722libusb_free_transfer(struct libusb_transfer *uxfer) 723{ 724 struct libusb_super_transfer *sxfer; 725 726 if (uxfer == NULL) 727 return; /* be NULL safe */ 728 729 sxfer = (struct libusb_super_transfer *)( 730 (uint8_t *)uxfer - sizeof(*sxfer)); 731 732 free(sxfer); 733} 734 735static int 736libusb10_get_maxframe(struct libusb20_device *pdev, libusb_transfer *xfer) 737{ 738 int ret; 739 int usb_speed; 740 741 usb_speed = libusb20_dev_get_speed(pdev); 742 743 switch (xfer->type) { 744 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: 745 switch (usb_speed) { 746 case LIBUSB20_SPEED_LOW: 747 case LIBUSB20_SPEED_FULL: 748 ret = 60 * 1; 749 break; 750 default: 751 ret = 60 * 8; 752 break; 753 } 754 break; 755 case LIBUSB_TRANSFER_TYPE_CONTROL: 756 ret = 2; 757 break; 758 default: 759 ret = 1; 760 break; 761 } 762 return (ret); 763} 764 765static int 766libusb10_get_buffsize(struct libusb20_device *pdev, libusb_transfer *xfer) 767{ 768 int ret; 769 int usb_speed; 770 771 usb_speed = libusb20_dev_get_speed(pdev); 772 773 switch (xfer->type) { 774 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: 775 ret = 0; /* kernel will auto-select */ 776 break; 777 case LIBUSB_TRANSFER_TYPE_CONTROL: 778 ret = 1024; 779 break; 780 default: 781 switch (usb_speed) { 782 case LIBUSB20_SPEED_LOW: 783 ret = 256; 784 break; 785 case LIBUSB20_SPEED_FULL: 786 ret = 4096; 787 break; 788 default: 789 ret = 16384; 790 break; 791 } 792 break; 793 } 794 return (ret); 795} 796 797static int 798libusb10_convert_error(uint8_t status) 799{ 800 ; /* indent fix */ 801 802 switch (status) { 803 case LIBUSB20_TRANSFER_START: 804 case LIBUSB20_TRANSFER_COMPLETED: 805 return (LIBUSB_TRANSFER_COMPLETED); 806 case LIBUSB20_TRANSFER_OVERFLOW: 807 return (LIBUSB_TRANSFER_OVERFLOW); 808 case LIBUSB20_TRANSFER_NO_DEVICE: 809 return (LIBUSB_TRANSFER_NO_DEVICE); 810 case LIBUSB20_TRANSFER_STALL: 811 return (LIBUSB_TRANSFER_STALL); 812 case LIBUSB20_TRANSFER_CANCELLED: 813 return (LIBUSB_TRANSFER_CANCELLED); 814 case LIBUSB20_TRANSFER_TIMED_OUT: 815 return (LIBUSB_TRANSFER_TIMED_OUT); 816 default: 817 return (LIBUSB_TRANSFER_ERROR); 818 } 819} 820 821/* This function must be called locked */ 822 823static void 824libusb10_complete_transfer(struct libusb20_transfer *pxfer, 825 struct libusb_super_transfer *sxfer, int status) 826{ 827 struct libusb_transfer *uxfer; 828 struct libusb_device *dev; 829 830 uxfer = (struct libusb_transfer *)( 831 ((uint8_t *)sxfer) + sizeof(*sxfer)); 832 833 if (pxfer != NULL) 834 libusb20_tr_set_priv_sc1(pxfer, NULL); 835 836 uxfer->status = status; 837 838 dev = libusb_get_device(uxfer->dev_handle); 839 840 TAILQ_INSERT_TAIL(&dev->ctx->tr_done, sxfer, entry); 841} 842 843/* This function must be called locked */ 844 845static void 846libusb10_isoc_proxy(struct libusb20_transfer *pxfer) 847{ 848 struct libusb_super_transfer *sxfer; 849 struct libusb_transfer *uxfer; 850 uint32_t actlen; 851 uint16_t iso_packets; 852 uint16_t i; 853 uint8_t status; 854 uint8_t flags; 855 856 status = libusb20_tr_get_status(pxfer); 857 sxfer = libusb20_tr_get_priv_sc1(pxfer); 858 actlen = libusb20_tr_get_actual_length(pxfer); 859 iso_packets = libusb20_tr_get_max_frames(pxfer); 860 861 if (sxfer == NULL) 862 return; /* cancelled - nothing to do */ 863 864 uxfer = (struct libusb_transfer *)( 865 ((uint8_t *)sxfer) + sizeof(*sxfer)); 866 867 if (iso_packets > uxfer->num_iso_packets) 868 iso_packets = uxfer->num_iso_packets; 869 870 if (iso_packets == 0) 871 return; /* nothing to do */ 872 873 /* make sure that the number of ISOCHRONOUS packets is valid */ 874 uxfer->num_iso_packets = iso_packets; 875 876 flags = uxfer->flags; 877 878 switch (status) { 879 case LIBUSB20_TRANSFER_COMPLETED: 880 881 /* update actual length */ 882 uxfer->actual_length = actlen; 883 for (i = 0; i != iso_packets; i++) { 884 uxfer->iso_packet_desc[i].actual_length = 885 libusb20_tr_get_length(pxfer, i); 886 } 887 libusb10_complete_transfer(pxfer, sxfer, LIBUSB_TRANSFER_COMPLETED); 888 break; 889 890 case LIBUSB20_TRANSFER_START: 891 892 /* setup length(s) */ 893 actlen = 0; 894 for (i = 0; i != iso_packets; i++) { 895 libusb20_tr_setup_isoc(pxfer, 896 &uxfer->buffer[actlen], 897 uxfer->iso_packet_desc[i].length, i); 898 actlen += uxfer->iso_packet_desc[i].length; 899 } 900 901 /* no remainder */ 902 sxfer->rem_len = 0; 903 904 libusb20_tr_set_total_frames(pxfer, iso_packets); 905 libusb20_tr_submit(pxfer); 906 907 /* fork another USB transfer, if any */ 908 libusb10_submit_transfer_sub(libusb20_tr_get_priv_sc0(pxfer), uxfer->endpoint); 909 break; 910 911 default: 912 libusb10_complete_transfer(pxfer, sxfer, libusb10_convert_error(status)); 913 break; 914 } 915} 916 917/* This function must be called locked */ 918 919static void 920libusb10_bulk_intr_proxy(struct libusb20_transfer *pxfer) 921{ 922 struct libusb_super_transfer *sxfer; 923 struct libusb_transfer *uxfer; 924 uint32_t max_bulk; 925 uint32_t actlen; 926 uint8_t status; 927 uint8_t flags; 928 929 status = libusb20_tr_get_status(pxfer); 930 sxfer = libusb20_tr_get_priv_sc1(pxfer); 931 max_bulk = libusb20_tr_get_max_total_length(pxfer); 932 actlen = libusb20_tr_get_actual_length(pxfer); 933 934 if (sxfer == NULL) 935 return; /* cancelled - nothing to do */ 936 937 uxfer = (struct libusb_transfer *)( 938 ((uint8_t *)sxfer) + sizeof(*sxfer)); 939 940 flags = uxfer->flags; 941 942 switch (status) { 943 case LIBUSB20_TRANSFER_COMPLETED: 944 945 uxfer->actual_length += actlen; 946 947 /* check for short packet */ 948 if (sxfer->last_len != actlen) { 949 if (flags & LIBUSB_TRANSFER_SHORT_NOT_OK) { 950 libusb10_complete_transfer(pxfer, sxfer, LIBUSB_TRANSFER_ERROR); 951 } else { 952 libusb10_complete_transfer(pxfer, sxfer, LIBUSB_TRANSFER_COMPLETED); 953 } 954 break; 955 } 956 /* check for end of data */ 957 if (sxfer->rem_len == 0) { 958 libusb10_complete_transfer(pxfer, sxfer, LIBUSB_TRANSFER_COMPLETED); 959 break; 960 } 961 /* FALLTHROUGH */ 962 963 case LIBUSB20_TRANSFER_START: 964 if (max_bulk > sxfer->rem_len) { 965 max_bulk = sxfer->rem_len; 966 } 967 /* setup new BULK or INTERRUPT transaction */ 968 libusb20_tr_setup_bulk(pxfer, 969 sxfer->curr_data, max_bulk, uxfer->timeout); 970 971 /* update counters */ 972 sxfer->last_len = max_bulk; 973 sxfer->curr_data += max_bulk; 974 sxfer->rem_len -= max_bulk; 975 976 libusb20_tr_submit(pxfer); 977 978 /* check if we can fork another USB transfer */ 979 if (sxfer->rem_len == 0) 980 libusb10_submit_transfer_sub(libusb20_tr_get_priv_sc0(pxfer), uxfer->endpoint); 981 break; 982 983 default: 984 libusb10_complete_transfer(pxfer, sxfer, libusb10_convert_error(status)); 985 break; 986 } 987} 988 989/* This function must be called locked */ 990 991static void 992libusb10_ctrl_proxy(struct libusb20_transfer *pxfer) 993{ 994 struct libusb_super_transfer *sxfer; 995 struct libusb_transfer *uxfer; 996 uint32_t max_bulk; 997 uint32_t actlen; 998 uint8_t status; 999 uint8_t flags; 1000 1001 status = libusb20_tr_get_status(pxfer); 1002 sxfer = libusb20_tr_get_priv_sc1(pxfer); 1003 max_bulk = libusb20_tr_get_max_total_length(pxfer); 1004 actlen = libusb20_tr_get_actual_length(pxfer); 1005 1006 if (sxfer == NULL) 1007 return; /* cancelled - nothing to do */ 1008 1009 uxfer = (struct libusb_transfer *)( 1010 ((uint8_t *)sxfer) + sizeof(*sxfer)); 1011 1012 flags = uxfer->flags; 1013 1014 switch (status) { 1015 case LIBUSB20_TRANSFER_COMPLETED: 1016 1017 uxfer->actual_length += actlen; 1018 1019 /* subtract length of SETUP packet, if any */ 1020 actlen -= libusb20_tr_get_length(pxfer, 0); 1021 1022 /* check for short packet */ 1023 if (sxfer->last_len != actlen) { 1024 if (flags & LIBUSB_TRANSFER_SHORT_NOT_OK) { 1025 libusb10_complete_transfer(pxfer, sxfer, LIBUSB_TRANSFER_ERROR); 1026 } else { 1027 libusb10_complete_transfer(pxfer, sxfer, LIBUSB_TRANSFER_COMPLETED); 1028 } 1029 break; 1030 } 1031 /* check for end of data */ 1032 if (sxfer->rem_len == 0) { 1033 libusb10_complete_transfer(pxfer, sxfer, LIBUSB_TRANSFER_COMPLETED); 1034 break; 1035 } 1036 /* FALLTHROUGH */ 1037 1038 case LIBUSB20_TRANSFER_START: 1039 if (max_bulk > sxfer->rem_len) { 1040 max_bulk = sxfer->rem_len; 1041 } 1042 /* setup new CONTROL transaction */ 1043 if (status == LIBUSB20_TRANSFER_COMPLETED) { 1044 /* next fragment - don't send SETUP packet */ 1045 libusb20_tr_set_length(pxfer, 0, 0); 1046 } else { 1047 /* first fragment - send SETUP packet */ 1048 libusb20_tr_set_length(pxfer, 8, 0); 1049 libusb20_tr_set_buffer(pxfer, uxfer->buffer, 0); 1050 } 1051 1052 if (max_bulk != 0) { 1053 libusb20_tr_set_length(pxfer, max_bulk, 1); 1054 libusb20_tr_set_buffer(pxfer, sxfer->curr_data, 1); 1055 libusb20_tr_set_total_frames(pxfer, 2); 1056 } else { 1057 libusb20_tr_set_total_frames(pxfer, 1); 1058 } 1059 1060 /* update counters */ 1061 sxfer->last_len = max_bulk; 1062 sxfer->curr_data += max_bulk; 1063 sxfer->rem_len -= max_bulk; 1064 1065 libusb20_tr_submit(pxfer); 1066 1067 /* check if we can fork another USB transfer */ 1068 if (sxfer->rem_len == 0) 1069 libusb10_submit_transfer_sub(libusb20_tr_get_priv_sc0(pxfer), uxfer->endpoint); 1070 break; 1071 1072 default: 1073 libusb10_complete_transfer(pxfer, sxfer, libusb10_convert_error(status)); 1074 break; 1075 } 1076} 1077 1078/* The following function must be called locked */ 1079 1080static void 1081libusb10_submit_transfer_sub(struct libusb20_device *pdev, uint8_t endpoint) 1082{ 1083 struct libusb20_transfer *pxfer0; 1084 struct libusb20_transfer *pxfer1; 1085 struct libusb_super_transfer *sxfer; 1086 struct libusb_transfer *uxfer; 1087 struct libusb_device *dev; 1088 int err; 1089 int buffsize; 1090 int maxframe; 1091 int temp; 1092 uint8_t dummy; 1093 1094 dev = libusb_get_device(pdev); 1095 1096 pxfer0 = libusb10_get_transfer(pdev, endpoint, 0); 1097 pxfer1 = libusb10_get_transfer(pdev, endpoint, 1); 1098 1099 if (pxfer0 == NULL || pxfer1 == NULL) 1100 return; /* shouldn't happen */ 1101 1102 temp = 0; 1103 if (libusb20_tr_pending(pxfer0)) 1104 temp |= 1; 1105 if (libusb20_tr_pending(pxfer1)) 1106 temp |= 2; 1107 1108 switch (temp) { 1109 case 3: 1110 /* wait till one of the transfers complete */ 1111 return; 1112 case 2: 1113 sxfer = libusb20_tr_get_priv_sc1(pxfer1); 1114 if (sxfer->rem_len) 1115 return; /* cannot queue another one */ 1116 /* swap transfers */ 1117 pxfer1 = pxfer0; 1118 break; 1119 case 1: 1120 sxfer = libusb20_tr_get_priv_sc1(pxfer0); 1121 if (sxfer->rem_len) 1122 return; /* cannot queue another one */ 1123 /* swap transfers */ 1124 pxfer0 = pxfer1; 1125 break; 1126 default: 1127 break; 1128 } 1129 1130 /* find next transfer on same endpoint */ 1131 TAILQ_FOREACH(sxfer, &dev->tr_head, entry) { 1132 1133 uxfer = (struct libusb_transfer *)( 1134 ((uint8_t *)sxfer) + sizeof(*sxfer)); 1135 1136 if (uxfer->endpoint == endpoint) { 1137 TAILQ_REMOVE(&dev->tr_head, sxfer, entry); 1138 sxfer->entry.tqe_prev = NULL; 1139 goto found; 1140 } 1141 } 1142 return; /* success */ 1143 1144found: 1145 1146 libusb20_tr_set_priv_sc0(pxfer0, pdev); 1147 libusb20_tr_set_priv_sc1(pxfer0, sxfer); 1148 1149 /* reset super transfer state */ 1150 sxfer->rem_len = uxfer->length; 1151 sxfer->curr_data = uxfer->buffer; 1152 uxfer->actual_length = 0; 1153 1154 switch (uxfer->type) { 1155 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: 1156 libusb20_tr_set_callback(pxfer0, libusb10_isoc_proxy); 1157 break; 1158 case LIBUSB_TRANSFER_TYPE_BULK: 1159 case LIBUSB_TRANSFER_TYPE_INTERRUPT: 1160 libusb20_tr_set_callback(pxfer0, libusb10_bulk_intr_proxy); 1161 break; 1162 case LIBUSB_TRANSFER_TYPE_CONTROL: 1163 libusb20_tr_set_callback(pxfer0, libusb10_ctrl_proxy); 1164 if (sxfer->rem_len < 8) 1165 goto failure; 1166 1167 /* remove SETUP packet from data */ 1168 sxfer->rem_len -= 8; 1169 sxfer->curr_data += 8; 1170 break; 1171 default: 1172 goto failure; 1173 } 1174 1175 buffsize = libusb10_get_buffsize(pdev, uxfer); 1176 maxframe = libusb10_get_maxframe(pdev, uxfer); 1177 1178 /* make sure the transfer is opened */ 1179 err = libusb20_tr_open(pxfer0, buffsize, maxframe, endpoint); 1180 if (err && (err != LIBUSB20_ERROR_BUSY)) { 1181 goto failure; 1182 } 1183 libusb20_tr_start(pxfer0); 1184 return; 1185 1186failure: 1187 libusb10_complete_transfer(pxfer0, sxfer, LIBUSB_TRANSFER_ERROR); 1188 1189 /* make sure our event loop spins the done handler */ 1190 dummy = 0; 1191 write(dev->ctx->ctrl_pipe[1], &dummy, sizeof(dummy)); 1192} 1193 1194/* The following function must be called unlocked */ 1195 1196int 1197libusb_submit_transfer(struct libusb_transfer *uxfer) 1198{ 1199 struct libusb20_transfer *pxfer0; 1200 struct libusb20_transfer *pxfer1; 1201 struct libusb_super_transfer *sxfer; 1202 struct libusb_device *dev;
|
1198 unsigned int endpoint;
|
1203 uint32_t endpoint; |
1204 int err; 1205 1206 if (uxfer == NULL) 1207 return (LIBUSB_ERROR_INVALID_PARAM); 1208 1209 if (uxfer->dev_handle == NULL) 1210 return (LIBUSB_ERROR_INVALID_PARAM); 1211 1212 endpoint = uxfer->endpoint; 1213 1214 if (endpoint > 255) 1215 return (LIBUSB_ERROR_INVALID_PARAM); 1216 1217 dev = libusb_get_device(uxfer->dev_handle); 1218 1219 DPRINTF(dev->ctx, LIBUSB_DEBUG_FUNCTION, "libusb_submit_transfer enter"); 1220 1221 sxfer = (struct libusb_super_transfer *)( 1222 (uint8_t *)uxfer - sizeof(*sxfer)); 1223 1224 CTX_LOCK(dev->ctx); 1225 1226 pxfer0 = libusb10_get_transfer(uxfer->dev_handle, endpoint, 0); 1227 pxfer1 = libusb10_get_transfer(uxfer->dev_handle, endpoint, 1); 1228 1229 if (pxfer0 == NULL || pxfer1 == NULL) { 1230 err = LIBUSB_ERROR_OTHER; 1231 } else if ((sxfer->entry.tqe_prev != NULL) || 1232 (libusb20_tr_get_priv_sc1(pxfer0) == sxfer) || 1233 (libusb20_tr_get_priv_sc1(pxfer1) == sxfer)) { 1234 err = LIBUSB_ERROR_BUSY; 1235 } else { 1236 TAILQ_INSERT_TAIL(&dev->tr_head, sxfer, entry); 1237 1238 libusb10_submit_transfer_sub( 1239 uxfer->dev_handle, endpoint); 1240 1241 err = 0; /* success */ 1242 } 1243 1244 CTX_UNLOCK(dev->ctx); 1245 1246 DPRINTF(dev->ctx, LIBUSB_DEBUG_FUNCTION, "libusb_submit_transfer leave %d", err); 1247 1248 return (err); 1249} 1250 1251/* Asynchronous transfer cancel */ 1252 1253int 1254libusb_cancel_transfer(struct libusb_transfer *uxfer) 1255{ 1256 struct libusb20_transfer *pxfer0; 1257 struct libusb20_transfer *pxfer1; 1258 struct libusb_super_transfer *sxfer; 1259 struct libusb_device *dev;
|
1255 unsigned int endpoint;
|
1260 uint32_t endpoint; |
1261 1262 if (uxfer == NULL) 1263 return (LIBUSB_ERROR_INVALID_PARAM); 1264 1265 if (uxfer->dev_handle == NULL) 1266 return (LIBUSB_ERROR_INVALID_PARAM); 1267 1268 endpoint = uxfer->endpoint; 1269 1270 if (endpoint > 255) 1271 return (LIBUSB_ERROR_INVALID_PARAM); 1272 1273 dev = libusb_get_device(uxfer->dev_handle); 1274 1275 DPRINTF(dev->ctx, LIBUSB_DEBUG_FUNCTION, "libusb_cancel_transfer enter"); 1276 1277 sxfer = (struct libusb_super_transfer *)( 1278 (uint8_t *)uxfer - sizeof(*sxfer)); 1279 1280 CTX_LOCK(dev->ctx); 1281 1282 pxfer0 = libusb10_get_transfer(uxfer->dev_handle, endpoint, 0); 1283 pxfer1 = libusb10_get_transfer(uxfer->dev_handle, endpoint, 1); 1284 1285 if (sxfer->entry.tqe_prev != NULL) { 1286 /* we are lucky - transfer is on a queue */ 1287 TAILQ_REMOVE(&dev->tr_head, sxfer, entry); 1288 sxfer->entry.tqe_prev = NULL; 1289 libusb10_complete_transfer(NULL, sxfer, LIBUSB_TRANSFER_CANCELLED); 1290 } else if (pxfer0 == NULL || pxfer1 == NULL) { 1291 /* not started */ 1292 } else if (libusb20_tr_get_priv_sc1(pxfer0) == sxfer) { 1293 libusb10_complete_transfer(pxfer0, sxfer, LIBUSB_TRANSFER_CANCELLED); 1294 libusb20_tr_stop(pxfer0); 1295 /* make sure the queue doesn't stall */ 1296 libusb10_submit_transfer_sub( 1297 uxfer->dev_handle, endpoint); 1298 } else if (libusb20_tr_get_priv_sc1(pxfer1) == sxfer) { 1299 libusb10_complete_transfer(pxfer1, sxfer, LIBUSB_TRANSFER_CANCELLED); 1300 libusb20_tr_stop(pxfer1); 1301 /* make sure the queue doesn't stall */ 1302 libusb10_submit_transfer_sub( 1303 uxfer->dev_handle, endpoint); 1304 } else { 1305 /* not started */ 1306 } 1307 1308 CTX_UNLOCK(dev->ctx); 1309 1310 DPRINTF(dev->ctx, LIBUSB_DEBUG_FUNCTION, "libusb_cancel_transfer leave"); 1311 1312 return (0); 1313} 1314 1315UNEXPORTED void 1316libusb10_cancel_all_transfer(libusb_device *dev) 1317{ 1318 /* TODO */ 1319}
|
1320 1321uint16_t 1322libusb_cpu_to_le16(uint16_t x) 1323{ 1324 return (htole16(x)); 1325} 1326 1327uint16_t 1328libusb_le16_to_cpu(uint16_t x) 1329{ 1330 return (le16toh(x)); 1331} 1332 |
|