libusb01.c revision 185087
1/* $FreeBSD: head/lib/libusb20/libusb20_compat01.c 185087 2008-11-19 08:56:35Z alfred $ */ 2/*- 3 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27/* 28 * This file contains the emulation layer for LibUSB v0.1 from sourceforge. 29 */ 30 31#include <sys/queue.h> 32 33#include <stdlib.h> 34#include <stdio.h> 35 36#include "libusb20.h" 37#include "libusb20_desc.h" 38#include "libusb20_int.h" 39#include "libusb20_compat01.h" 40 41/* 42 * The two following macros were taken from the original LibUSB v0.1 43 * for sake of compatibility: 44 */ 45#define LIST_ADD(begin, ent) \ 46 do { \ 47 if (begin) { \ 48 ent->next = begin; \ 49 ent->next->prev = ent; \ 50 } else { \ 51 ent->next = NULL; \ 52 } \ 53 ent->prev = NULL; \ 54 begin = ent; \ 55 } while(0) 56 57#define LIST_DEL(begin, ent) \ 58 do { \ 59 if (ent->prev) { \ 60 ent->prev->next = ent->next; \ 61 } else { \ 62 begin = ent->next; \ 63 } \ 64 if (ent->next) { \ 65 ent->next->prev = ent->prev; \ 66 } \ 67 ent->prev = NULL; \ 68 ent->next = NULL; \ 69 } while (0) 70 71struct usb_bus *usb_busses = NULL; 72 73static struct usb_bus usb_global_bus = { 74 .dirname = {"/dev/usb"}, 75 .root_dev = NULL, 76 .devices = NULL, 77}; 78 79static struct libusb20_backend *usb_backend = NULL; 80 81struct usb_parse_state { 82 83 struct { 84 struct libusb20_endpoint *currep; 85 struct libusb20_interface *currifc; 86 struct libusb20_config *currcfg; 87 struct libusb20_me_struct *currextra; 88 } a; 89 90 struct { 91 struct usb_config_descriptor *currcfg; 92 struct usb_interface_descriptor *currifc; 93 struct usb_endpoint_descriptor *currep; 94 struct usb_interface *currifcw; 95 uint8_t *currextra; 96 } b; 97 98 uint8_t preparse; 99}; 100 101static uint8_t 102usb_get_first_claimed_interface(usb_dev_handle * dev) 103{ 104 struct libusb20_device *pdev = (void *)dev; 105 uint32_t x; 106 uint8_t y; 107 108 x = pdev->claimed_interfaces; 109 110 for (y = 0; y != 32; y++) { 111 if (x & (1 << y)) 112 break; 113 } 114 115 if (y == 32) 116 y = 0xFF; /* dummy */ 117 118 return (y); 119} 120 121static struct libusb20_transfer * 122usb_get_transfer_by_ep_no(usb_dev_handle * dev, uint8_t ep_no) 123{ 124 struct libusb20_device *pdev = (void *)dev; 125 struct libusb20_transfer *xfer; 126 int err; 127 uint32_t bufsize; 128 uint8_t x; 129 uint8_t speed; 130 131 x = (ep_no & LIBUSB20_ENDPOINT_ADDRESS_MASK) * 2; 132 133 if (ep_no & LIBUSB20_ENDPOINT_DIR_MASK) { 134 /* this is an IN endpoint */ 135 x |= 1; 136 } 137 speed = libusb20_dev_get_speed(pdev); 138 139 /* select a sensible buffer size */ 140 if (speed == LIBUSB20_SPEED_LOW) { 141 bufsize = 256; 142 } else if (speed == LIBUSB20_SPEED_FULL) { 143 bufsize = 4096; 144 } else { 145 bufsize = 16384; 146 } 147 148 xfer = libusb20_tr_get_pointer(pdev, x); 149 150 if (xfer == NULL) 151 return (xfer); 152 153 err = libusb20_tr_open(xfer, bufsize, 1, ep_no); 154 if (err == LIBUSB20_ERROR_BUSY) { 155 /* already opened */ 156 return (xfer); 157 } else if (err) { 158 return (NULL); 159 } 160 /* success */ 161 return (xfer); 162} 163 164usb_dev_handle * 165usb_open(struct usb_device *dev) 166{ 167 int err; 168 169 err = libusb20_dev_open(dev->dev, 16 * 2); 170 if (err == LIBUSB20_ERROR_BUSY) { 171 /* 172 * Workaround buggy USB applications which open the USB 173 * device multiple times: 174 */ 175 return (dev->dev); 176 } 177 if (err) 178 return (NULL); 179 180 return (dev->dev); 181} 182 183int 184usb_close(usb_dev_handle * dev) 185{ 186 int err; 187 188 err = libusb20_dev_close((void *)dev); 189 190 if (err) 191 return (-1); 192 193 return (0); 194} 195 196int 197usb_get_string(usb_dev_handle * dev, int strindex, 198 int langid, char *buf, size_t buflen) 199{ 200 int err; 201 202 err = libusb20_dev_req_string_sync((void *)dev, 203 strindex, langid, buf, buflen); 204 205 if (err) 206 return (-1); 207 208 return (0); 209} 210 211int 212usb_get_string_simple(usb_dev_handle * dev, int strindex, 213 char *buf, size_t buflen) 214{ 215 int err; 216 217 err = libusb20_dev_req_string_simple_sync((void *)dev, 218 strindex, buf, buflen); 219 220 if (err) 221 return (-1); 222 223 return (strlen(buf)); 224} 225 226int 227usb_get_descriptor_by_endpoint(usb_dev_handle * udev, int ep, uint8_t type, 228 uint8_t ep_index, void *buf, int size) 229{ 230 memset(buf, 0, size); 231 232 return (usb_control_msg(udev, ep | USB_ENDPOINT_IN, 233 USB_REQ_GET_DESCRIPTOR, (type << 8) + ep_index, 0, 234 buf, size, 1000)); 235} 236 237int 238usb_get_descriptor(usb_dev_handle * udev, uint8_t type, uint8_t desc_index, 239 void *buf, int size) 240{ 241 memset(buf, 0, size); 242 243 return (usb_control_msg(udev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, 244 (type << 8) + desc_index, 0, buf, size, 1000)); 245} 246 247int 248usb_parse_descriptor(uint8_t *source, char *description, void *dest) 249{ 250 uint8_t *sp = source; 251 uint8_t *dp = dest; 252 uint16_t w; 253 uint32_t d; 254 char *cp; 255 256 for (cp = description; *cp; cp++) { 257 switch (*cp) { 258 case 'b': /* 8-bit byte */ 259 *dp++ = *sp++; 260 break; 261 /* 262 * 16-bit word, convert from little endian to CPU 263 */ 264 case 'w': 265 w = (sp[1] << 8) | sp[0]; 266 sp += 2; 267 /* Align to word boundary */ 268 dp += ((dp - (uint8_t *)0) & 1); 269 *((uint16_t *)dp) = w; 270 dp += 2; 271 break; 272 /* 273 * 32-bit dword, convert from little endian to CPU 274 */ 275 case 'd': 276 d = (sp[3] << 24) | (sp[2] << 16) | 277 (sp[1] << 8) | sp[0]; 278 sp += 4; 279 /* Align to word boundary */ 280 dp += ((dp - (uint8_t *)0) & 1); 281 /* Align to double word boundary */ 282 dp += ((dp - (uint8_t *)0) & 2); 283 *((uint32_t *)dp) = d; 284 dp += 4; 285 break; 286 } 287 } 288 return (sp - source); 289} 290 291static void 292usb_parse_extra(struct usb_parse_state *ps, uint8_t **pptr, int *plen) 293{ 294 void *ptr; 295 uint16_t len; 296 297 ptr = ps->a.currextra->ptr; 298 len = ps->a.currextra->len; 299 300 if (ps->preparse == 0) { 301 memcpy(ps->b.currextra, ptr, len); 302 *pptr = ps->b.currextra; 303 *plen = len; 304 } 305 ps->b.currextra += len; 306 return; 307} 308 309static void 310usb_parse_endpoint(struct usb_parse_state *ps) 311{ 312 struct usb_endpoint_descriptor *bep; 313 struct libusb20_endpoint *aep; 314 315 aep = ps->a.currep; 316 bep = ps->b.currep++; 317 318 if (ps->preparse == 0) { 319 /* copy descriptor fields */ 320 bep->bLength = aep->desc.bLength; 321 bep->bDescriptorType = aep->desc.bDescriptorType; 322 bep->bEndpointAddress = aep->desc.bEndpointAddress; 323 bep->bmAttributes = aep->desc.bmAttributes; 324 bep->wMaxPacketSize = aep->desc.wMaxPacketSize; 325 bep->bInterval = aep->desc.bInterval; 326 bep->bRefresh = aep->desc.bRefresh; 327 bep->bSynchAddress = aep->desc.bSynchAddress; 328 } 329 ps->a.currextra = &aep->extra; 330 usb_parse_extra(ps, &bep->extra, &bep->extralen); 331 return; 332} 333 334static void 335usb_parse_iface_sub(struct usb_parse_state *ps) 336{ 337 struct libusb20_interface *aifc; 338 struct usb_interface_descriptor *bifc; 339 uint8_t x; 340 341 aifc = ps->a.currifc; 342 bifc = ps->b.currifc++; 343 344 if (ps->preparse == 0) { 345 /* copy descriptor fields */ 346 bifc->bLength = aifc->desc.bLength; 347 bifc->bDescriptorType = aifc->desc.bDescriptorType; 348 bifc->bInterfaceNumber = aifc->desc.bInterfaceNumber; 349 bifc->bAlternateSetting = aifc->desc.bAlternateSetting; 350 bifc->bNumEndpoints = aifc->num_endpoints; 351 bifc->bInterfaceClass = aifc->desc.bInterfaceClass; 352 bifc->bInterfaceSubClass = aifc->desc.bInterfaceSubClass; 353 bifc->bInterfaceProtocol = aifc->desc.bInterfaceProtocol; 354 bifc->iInterface = aifc->desc.iInterface; 355 bifc->endpoint = ps->b.currep; 356 } 357 for (x = 0; x != aifc->num_endpoints; x++) { 358 ps->a.currep = aifc->endpoints + x; 359 usb_parse_endpoint(ps); 360 } 361 362 ps->a.currextra = &aifc->extra; 363 usb_parse_extra(ps, &bifc->extra, &bifc->extralen); 364 return; 365} 366 367static void 368usb_parse_iface(struct usb_parse_state *ps) 369{ 370 struct libusb20_interface *aifc; 371 struct usb_interface *bifc; 372 uint8_t x; 373 374 aifc = ps->a.currifc; 375 bifc = ps->b.currifcw++; 376 377 if (ps->preparse == 0) { 378 /* initialise interface wrapper */ 379 bifc->altsetting = ps->b.currifc; 380 bifc->num_altsetting = aifc->num_altsetting + 1; 381 } 382 usb_parse_iface_sub(ps); 383 384 for (x = 0; x != aifc->num_altsetting; x++) { 385 ps->a.currifc = aifc->altsetting + x; 386 usb_parse_iface_sub(ps); 387 } 388 return; 389} 390 391static void 392usb_parse_config(struct usb_parse_state *ps) 393{ 394 struct libusb20_config *acfg; 395 struct usb_config_descriptor *bcfg; 396 uint8_t x; 397 398 acfg = ps->a.currcfg; 399 bcfg = ps->b.currcfg; 400 401 if (ps->preparse == 0) { 402 /* initialise config wrapper */ 403 bcfg->bLength = acfg->desc.bLength; 404 bcfg->bDescriptorType = acfg->desc.bDescriptorType; 405 bcfg->wTotalLength = acfg->desc.wTotalLength; 406 bcfg->bNumInterfaces = acfg->num_interface; 407 bcfg->bConfigurationValue = acfg->desc.bConfigurationValue; 408 bcfg->iConfiguration = acfg->desc.iConfiguration; 409 bcfg->bmAttributes = acfg->desc.bmAttributes; 410 bcfg->MaxPower = acfg->desc.bMaxPower; 411 bcfg->interface = ps->b.currifcw; 412 } 413 for (x = 0; x != acfg->num_interface; x++) { 414 ps->a.currifc = acfg->interface + x; 415 usb_parse_iface(ps); 416 } 417 418 ps->a.currextra = &acfg->extra; 419 usb_parse_extra(ps, &bcfg->extra, &bcfg->extralen); 420 return; 421} 422 423int 424usb_parse_configuration(struct usb_config_descriptor *config, 425 uint8_t *buffer) 426{ 427 struct usb_parse_state ps; 428 uint8_t *ptr; 429 uint32_t a; 430 uint32_t b; 431 uint32_t c; 432 uint32_t d; 433 434 if ((buffer == NULL) || (config == NULL)) { 435 return (-1); 436 } 437 memset(&ps, 0, sizeof(ps)); 438 439 ps.a.currcfg = libusb20_parse_config_desc(buffer); 440 ps.b.currcfg = config; 441 if (ps.a.currcfg == NULL) { 442 /* could not parse config or out of memory */ 443 return (-1); 444 } 445 /* do the pre-parse */ 446 ps.preparse = 1; 447 usb_parse_config(&ps); 448 449 a = ((uint8_t *)(ps.b.currifcw) - ((uint8_t *)0)); 450 b = ((uint8_t *)(ps.b.currifc) - ((uint8_t *)0)); 451 c = ((uint8_t *)(ps.b.currep) - ((uint8_t *)0)); 452 d = ((uint8_t *)(ps.b.currextra) - ((uint8_t *)0)); 453 454 /* allocate memory for our configuration */ 455 ptr = malloc(a + b + c + d); 456 457 /* "currifcw" must be first, hence this pointer is freed */ 458 ps.b.currifcw = (void *)(ptr); 459 ps.b.currifc = (void *)(ptr + a); 460 ps.b.currep = (void *)(ptr + a + b); 461 ps.b.currextra = (void *)(ptr + a + b + c); 462 463 /* generate a libusb v0.1 compatible structure */ 464 ps.preparse = 0; 465 usb_parse_config(&ps); 466 467 /* free config structure */ 468 free(ps.a.currcfg); 469 470 return (0); /* success */ 471} 472 473void 474usb_destroy_configuration(struct usb_device *dev) 475{ 476 uint8_t c; 477 478 if (dev->config == NULL) { 479 return; 480 } 481 for (c = 0; c != dev->descriptor.bNumConfigurations; c++) { 482 struct usb_config_descriptor *cf = &dev->config[c]; 483 484 if (cf->interface != NULL) { 485 free(cf->interface); 486 cf->interface = NULL; 487 } 488 } 489 490 free(dev->config); 491 dev->config = NULL; 492 return; 493} 494 495void 496usb_fetch_and_parse_descriptors(usb_dev_handle * udev) 497{ 498 struct usb_device *dev; 499 struct libusb20_device *pdev; 500 uint8_t *ptr; 501 int error; 502 uint32_t size; 503 uint16_t len; 504 uint8_t x; 505 506 if (udev == NULL) { 507 /* be NULL safe */ 508 return; 509 } 510 dev = usb_device(udev); 511 pdev = (void *)udev; 512 513 if (dev->descriptor.bNumConfigurations == 0) { 514 /* invalid device */ 515 return; 516 } 517 size = dev->descriptor.bNumConfigurations * 518 sizeof(struct usb_config_descriptor); 519 520 dev->config = malloc(size); 521 if (dev->config == NULL) { 522 /* out of memory */ 523 return; 524 } 525 memset(dev->config, 0, size); 526 527 for (x = 0; x != dev->descriptor.bNumConfigurations; x++) { 528 529 error = (pdev->methods->get_config_desc_full) ( 530 pdev, &ptr, &len, x); 531 532 if (error) { 533 usb_destroy_configuration(dev); 534 return; 535 } 536 usb_parse_configuration(dev->config + x, ptr); 537 538 /* free config buffer */ 539 free(ptr); 540 } 541 return; 542} 543 544static int 545usb_std_io(usb_dev_handle * dev, int ep, char *bytes, int size, 546 int timeout, int is_intr) 547{ 548 struct libusb20_transfer *xfer; 549 uint32_t temp; 550 uint32_t maxsize; 551 uint32_t actlen; 552 char *oldbytes; 553 554 xfer = usb_get_transfer_by_ep_no(dev, ep); 555 if (xfer == NULL) 556 return (-1); 557 558 if (libusb20_tr_pending(xfer)) { 559 /* there is already a transfer ongoing */ 560 return (-1); 561 } 562 maxsize = libusb20_tr_get_max_total_length(xfer); 563 oldbytes = bytes; 564 565 /* 566 * We allow transferring zero bytes which is the same 567 * equivalent to a zero length USB packet. 568 */ 569 do { 570 571 temp = size; 572 if (temp > maxsize) { 573 /* find maximum possible length */ 574 temp = maxsize; 575 } 576 if (is_intr) 577 libusb20_tr_setup_intr(xfer, bytes, temp, timeout); 578 else 579 libusb20_tr_setup_bulk(xfer, bytes, temp, timeout); 580 581 libusb20_tr_start(xfer); 582 583 while (1) { 584 585 if (libusb20_dev_process((void *)dev) != 0) { 586 /* device detached */ 587 return (-1); 588 } 589 if (libusb20_tr_pending(xfer) == 0) { 590 /* transfer complete */ 591 break; 592 } 593 /* wait for USB event from kernel */ 594 libusb20_dev_wait_process((void *)dev, -1); 595 } 596 597 if (libusb20_tr_get_status(xfer)) { 598 /* transfer error */ 599 return (-1); 600 } 601 actlen = libusb20_tr_get_actual_length(xfer); 602 603 bytes += actlen; 604 size -= actlen; 605 606 if (actlen != temp) { 607 /* short transfer */ 608 break; 609 } 610 } while (size > 0); 611 612 return (bytes - oldbytes); 613} 614 615int 616usb_bulk_write(usb_dev_handle * dev, int ep, char *bytes, 617 int size, int timeout) 618{ 619 return (usb_std_io(dev, ep & ~USB_ENDPOINT_DIR_MASK, 620 bytes, size, timeout, 0)); 621} 622 623int 624usb_bulk_read(usb_dev_handle * dev, int ep, char *bytes, 625 int size, int timeout) 626{ 627 return (usb_std_io(dev, ep | USB_ENDPOINT_DIR_MASK, 628 bytes, size, timeout, 0)); 629} 630 631int 632usb_interrupt_write(usb_dev_handle * dev, int ep, char *bytes, 633 int size, int timeout) 634{ 635 return (usb_std_io(dev, ep & ~USB_ENDPOINT_DIR_MASK, 636 bytes, size, timeout, 1)); 637} 638 639int 640usb_interrupt_read(usb_dev_handle * dev, int ep, char *bytes, 641 int size, int timeout) 642{ 643 return (usb_std_io(dev, ep | USB_ENDPOINT_DIR_MASK, 644 bytes, size, timeout, 1)); 645} 646 647int 648usb_control_msg(usb_dev_handle * dev, int requesttype, int request, 649 int value, int wIndex, char *bytes, int size, int timeout) 650{ 651 struct LIBUSB20_CONTROL_SETUP_DECODED req; 652 int err; 653 uint16_t actlen; 654 655 LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &req); 656 657 req.bmRequestType = requesttype; 658 req.bRequest = request; 659 req.wValue = value; 660 req.wIndex = wIndex; 661 req.wLength = size; 662 663 err = libusb20_dev_request_sync((void *)dev, &req, bytes, 664 &actlen, timeout, 0); 665 666 if (err) 667 return (-1); 668 669 return (actlen); 670} 671 672int 673usb_set_configuration(usb_dev_handle * udev, int bConfigurationValue) 674{ 675 struct usb_device *dev; 676 int err; 677 uint8_t i; 678 679 /* 680 * Need to translate from "bConfigurationValue" to 681 * configuration index: 682 */ 683 684 if (bConfigurationValue == 0) { 685 /* unconfigure */ 686 i = 255; 687 } else { 688 /* lookup configuration index */ 689 dev = usb_device(udev); 690 691 /* check if the configuration array is not there */ 692 if (dev->config == NULL) { 693 return (-1); 694 } 695 for (i = 0;; i++) { 696 if (i == dev->descriptor.bNumConfigurations) { 697 /* "bConfigurationValue" not found */ 698 return (-1); 699 } 700 if ((dev->config + i)->bConfigurationValue == bConfigurationValue) { 701 break; 702 } 703 } 704 } 705 706 err = libusb20_dev_set_config_index((void *)udev, i); 707 708 if (err) 709 return (-1); 710 711 return (0); 712} 713 714int 715usb_claim_interface(usb_dev_handle * dev, int interface) 716{ 717 int err; 718 719 err = libusb20_dev_claim_interface((void *)dev, interface); 720 721 if (err) 722 return (-1); 723 724 return (0); 725} 726 727int 728usb_release_interface(usb_dev_handle * dev, int interface) 729{ 730 int err; 731 732 err = libusb20_dev_release_interface((void *)dev, interface); 733 734 if (err) 735 return (-1); 736 737 return (0); 738} 739 740int 741usb_set_altinterface(usb_dev_handle * dev, int alternate) 742{ 743 int err; 744 uint8_t iface; 745 746 iface = usb_get_first_claimed_interface(dev); 747 748 err = libusb20_dev_set_alt_index((void *)dev, iface, alternate); 749 750 if (err) 751 return (-1); 752 753 return (0); 754} 755 756int 757usb_resetep(usb_dev_handle * dev, unsigned int ep) 758{ 759 /* emulate an endpoint reset through clear-STALL */ 760 return (usb_clear_halt(dev, ep)); 761} 762 763int 764usb_clear_halt(usb_dev_handle * dev, unsigned int ep) 765{ 766 struct libusb20_transfer *xfer; 767 768 xfer = usb_get_transfer_by_ep_no(dev, ep); 769 if (xfer == NULL) 770 return (-1); 771 772 libusb20_tr_clear_stall_sync(xfer); 773 774 return (0); 775} 776 777int 778usb_reset(usb_dev_handle * dev) 779{ 780 int err; 781 782 err = libusb20_dev_reset((void *)dev); 783 784 if (err) 785 return (-1); 786 787 return (0); 788} 789 790const char * 791usb_strerror(void) 792{ 793 /* TODO */ 794 return ("Unknown error"); 795} 796 797void 798usb_init(void) 799{ 800 /* nothing to do */ 801 return; 802} 803 804void 805usb_set_debug(int level) 806{ 807 /* use kernel UGEN debugging if you need to see what is going on */ 808 return; 809} 810 811int 812usb_find_busses(void) 813{ 814 usb_busses = &usb_global_bus; 815 return (0); 816} 817 818int 819usb_find_devices(void) 820{ 821 struct libusb20_device *pdev; 822 struct usb_device *udev; 823 struct LIBUSB20_DEVICE_DESC_DECODED *ddesc; 824 struct libusb20_backend *pold; 825 int err; 826 827 /* cleanup after last device search */ 828 829 pold = usb_backend; 830 831 pdev = NULL; 832 while ((pdev = libusb20_be_device_foreach(pold, pdev))) { 833 if (!pdev->is_opened) { 834 /* 835 * if the device has not been opened we free the 836 * device data 837 */ 838 udev = pdev->priv01Data; 839 libusb20_be_dequeue_device(pold, pdev); 840 libusb20_dev_free(pdev); 841 if (udev != NULL) { 842 LIST_DEL(usb_global_bus.devices, udev); 843 free(udev); 844 } 845 pdev = NULL; /* restart search */ 846 } 847 } 848 849 /* do a new backend device search */ 850 851 usb_backend = libusb20_be_alloc_default(); 852 if (usb_backend == NULL) { 853 usb_backend = pold; /* restore */ 854 return (-1); 855 } 856 /* iterate all devices */ 857 858 pdev = NULL; 859 while ((pdev = libusb20_be_device_foreach(usb_backend, pdev))) { 860 udev = malloc(sizeof(*udev)); 861 if (udev == NULL) 862 break; 863 864 memset(udev, 0, sizeof(*udev)); 865 866 udev->bus = &usb_global_bus; 867 868 snprintf(udev->filename, sizeof(udev->filename), 869 "/dev/ugen%u.%u", 870 libusb20_dev_get_bus_number(pdev), 871 libusb20_dev_get_address(pdev)); 872 873 ddesc = libusb20_dev_get_device_desc(pdev); 874 875 udev->descriptor.bLength = sizeof(udev->descriptor); 876 udev->descriptor.bDescriptorType = ddesc->bDescriptorType; 877 udev->descriptor.bcdUSB = ddesc->bcdUSB; 878 udev->descriptor.bDeviceClass = ddesc->bDeviceClass; 879 udev->descriptor.bDeviceSubClass = ddesc->bDeviceSubClass; 880 udev->descriptor.bDeviceProtocol = ddesc->bDeviceProtocol; 881 udev->descriptor.bMaxPacketSize0 = ddesc->bMaxPacketSize0; 882 udev->descriptor.idVendor = ddesc->idVendor; 883 udev->descriptor.idProduct = ddesc->idProduct; 884 udev->descriptor.bcdDevice = ddesc->bcdDevice; 885 udev->descriptor.iManufacturer = ddesc->iManufacturer; 886 udev->descriptor.iProduct = ddesc->iProduct; 887 udev->descriptor.iSerialNumber = ddesc->iSerialNumber; 888 udev->descriptor.bNumConfigurations = 889 ddesc->bNumConfigurations; 890 if (udev->descriptor.bNumConfigurations > USB_MAXCONFIG) { 891 /* truncate number of configurations */ 892 udev->descriptor.bNumConfigurations = USB_MAXCONFIG; 893 } 894 /* link together the two structures */ 895 udev->dev = pdev; 896 pdev->priv01Data = udev; 897 898 err = libusb20_dev_open(pdev, 0); 899 if (err == 0) { 900 /* XXX get all config descriptors by default */ 901 usb_fetch_and_parse_descriptors((void *)pdev); 902 libusb20_dev_close(pdev); 903 } 904 LIST_ADD(usb_global_bus.devices, udev); 905 } 906 907 /* move old devices over to the new USB backend */ 908 909 while ((pdev = libusb20_be_device_foreach(pold, pdev))) { 910 libusb20_be_dequeue_device(pold, pdev); 911 libusb20_be_enqueue_device(usb_backend, pdev); 912 } 913 914 /* free old backend, if any */ 915 916 libusb20_be_free(pold); 917 918 return (0); /* success */ 919} 920 921struct usb_device * 922usb_device(usb_dev_handle * dev) 923{ 924 struct libusb20_device *pdev; 925 926 pdev = (void *)dev; 927 928 return (pdev->priv01Data); 929} 930 931struct usb_bus * 932usb_get_busses(void) 933{ 934 return (usb_busses); 935} 936