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