1 /* 2 * Copyright 2011-2013 Martin Pieuchot <mpi (at) openbsd.org> 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 19 #include <sys/time.h> 20 #include <sys/types.h> 21 22 #include <errno.h> 23 #include <fcntl.h> 24 #include <stdio.h> 25 #include <stdlib.h> 26 #include <string.h> 27 #include <unistd.h> 28 29 #include <dev/usb/usb.h> 30 31 #include "libusb.h" 32 #include "libusbi.h" 33 34 struct device_priv { 35 char *devname; /* name of the ugen(4) node */ 36 int fd; /* device file descriptor */ 37 38 unsigned char *cdesc; /* active config descriptor */ 39 usb_device_descriptor_t ddesc; /* usb device descriptor */ 40 }; 41 42 struct handle_priv { 43 int pipe[2]; /* for event notification */ 44 int endpoints[USB_MAX_ENDPOINTS]; 45 }; 46 47 /* 48 * Backend functions 49 */ 50 static int obsd_get_device_list(struct libusb_context *, 51 struct discovered_devs **); 52 static int obsd_open(struct libusb_device_handle *); 53 static void obsd_close(struct libusb_device_handle *); 54 55 static int obsd_get_device_descriptor(struct libusb_device *, unsigned char *, 56 int *); 57 static int obsd_get_active_config_descriptor(struct libusb_device *, 58 unsigned char *, size_t, int *); 59 static int obsd_get_config_descriptor(struct libusb_device *, uint8_t, 60 unsigned char *, size_t, int *); 61 62 static int obsd_get_configuration(struct libusb_device_handle *, int *); 63 static int obsd_set_configuration(struct libusb_device_handle *, int); 64 65 static int obsd_claim_interface(struct libusb_device_handle *, int); 66 static int obsd_release_interface(struct libusb_device_handle *, int); 67 68 static int obsd_set_interface_altsetting(struct libusb_device_handle *, int, 69 int); 70 static int obsd_clear_halt(struct libusb_device_handle *, unsigned char); 71 static int obsd_reset_device(struct libusb_device_handle *); 72 static void obsd_destroy_device(struct libusb_device *); 73 74 static int obsd_submit_transfer(struct usbi_transfer *); 75 static int obsd_cancel_transfer(struct usbi_transfer *); 76 static void obsd_clear_transfer_priv(struct usbi_transfer *); 77 static int obsd_handle_events(struct libusb_context *ctx, struct pollfd *, 78 nfds_t, int); 79 static int obsd_clock_gettime(int, struct timespec *); 80 81 /* 82 * Private functions 83 */ 84 static int _errno_to_libusb(int); 85 static int _cache_active_config_descriptor(struct libusb_device *); 86 static int _sync_control_transfer(struct usbi_transfer *); 87 static int _sync_gen_transfer(struct usbi_transfer *); 88 static int _access_endpoint(struct libusb_transfer *); 89 90 static int _bus_open(int); 91 92 93 const struct usbi_os_backend openbsd_backend = { 94 "Synchronous OpenBSD backend", 95 0, 96 NULL, /* init() */ 97 NULL, /* exit() */ 98 obsd_get_device_list, 99 NULL, /* hotplug_poll */ 100 obsd_open, 101 obsd_close, 102 103 obsd_get_device_descriptor, 104 obsd_get_active_config_descriptor, 105 obsd_get_config_descriptor, 106 NULL, /* get_config_descriptor_by_value() */ 107 108 obsd_get_configuration, 109 obsd_set_configuration, 110 111 obsd_claim_interface, 112 obsd_release_interface, 113 114 obsd_set_interface_altsetting, 115 obsd_clear_halt, 116 obsd_reset_device, 117 118 NULL, /* kernel_driver_active() */ 119 NULL, /* detach_kernel_driver() */ 120 NULL, /* attach_kernel_driver() */ 121 122 obsd_destroy_device, 123 124 obsd_submit_transfer, 125 obsd_cancel_transfer, 126 obsd_clear_transfer_priv, 127 128 obsd_handle_events, 129 130 obsd_clock_gettime, 131 sizeof(struct device_priv), 132 sizeof(struct handle_priv), 133 0, /* transfer_priv_size */ 134 0, /* add_iso_packet_size */ 135 }; 136 137 #define DEVPATH "/dev/" 138 #define USBDEV DEVPATH "usb" 139 140 int 141 obsd_get_device_list(struct libusb_context * ctx, 142 struct discovered_devs **discdevs) 143 { 144 struct discovered_devs *ddd; 145 struct libusb_device *dev; 146 struct device_priv *dpriv; 147 struct usb_device_info di; 148 struct usb_device_ddesc dd; 149 unsigned long session_id; 150 char devices[USB_MAX_DEVICES]; 151 char busnode[16]; 152 char *udevname; 153 int fd, addr, i, j; 154 155 usbi_dbg(""); 156 157 for (i = 0; i < 8; i++) { 158 snprintf(busnode, sizeof(busnode), USBDEV "%d", i); 159 160 if ((fd = open(busnode, O_RDWR)) < 0) { 161 if (errno != ENOENT && errno != ENXIO) 162 usbi_err(ctx, "could not open %s", busnode); 163 continue; 164 } 165 166 bzero(devices, sizeof(devices)); 167 for (addr = 1; addr < USB_MAX_DEVICES; addr++) { 168 if (devices[addr]) 169 continue; 170 171 di.udi_addr = addr; 172 if (ioctl(fd, USB_DEVICEINFO, &di) < 0) 173 continue; 174 175 /* 176 * XXX If ugen(4) is attached to the USB device 177 * it will be used. 178 */ 179 udevname = NULL; 180 for (j = 0; j < USB_MAX_DEVNAMES; j++) 181 if (!strncmp("ugen", di.udi_devnames[j], 4)) { 182 udevname = strdup(di.udi_devnames[j]); 183 break; 184 } 185 186 session_id = (di.udi_bus << 8 | di.udi_addr); 187 dev = usbi_get_device_by_session_id(ctx, session_id); 188 189 if (dev == NULL) { 190 dev = usbi_alloc_device(ctx, session_id); 191 if (dev == NULL) { 192 close(fd); 193 return (LIBUSB_ERROR_NO_MEM); 194 } 195 196 dev->bus_number = di.udi_bus; 197 dev->device_address = di.udi_addr; 198 dev->speed = di.udi_speed; 199 200 dpriv = (struct device_priv *)dev->os_priv; 201 dpriv->fd = -1; 202 dpriv->cdesc = NULL; 203 dpriv->devname = udevname; 204 205 dd.udd_bus = di.udi_bus; 206 dd.udd_addr = di.udi_addr; 207 if (ioctl(fd, USB_DEVICE_GET_DDESC, &dd) < 0) { 208 libusb_unref_device(dev); 209 continue; 210 } 211 dpriv->ddesc = dd.udd_desc; 212 213 if (_cache_active_config_descriptor(dev)) { 214 libusb_unref_device(dev); 215 continue; 216 } 217 218 if (usbi_sanitize_device(dev)) 219 libusb_unref_device(dev); 220 } 221 222 ddd = discovered_devs_append(*discdevs, dev); 223 if (ddd == NULL) { 224 close(fd); 225 return (LIBUSB_ERROR_NO_MEM); 226 } 227 228 *discdevs = ddd; 229 devices[addr] = 1; 230 } 231 232 close(fd); 233 } 234 235 return (LIBUSB_SUCCESS); 236 } 237 238 int 239 obsd_open(struct libusb_device_handle *handle) 240 { 241 struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv; 242 struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; 243 char devnode[16]; 244 245 if (dpriv->devname) { 246 /* 247 * Only open ugen(4) attached devices read-write, all 248 * read-only operations are done through the bus node. 249 */ 250 snprintf(devnode, sizeof(devnode), DEVPATH "%s.00", 251 dpriv->devname); 252 dpriv->fd = open(devnode, O_RDWR); 253 if (dpriv->fd < 0) 254 return _errno_to_libusb(errno); 255 256 usbi_dbg("open %s: fd %d", devnode, dpriv->fd); 257 } 258 259 if (pipe(hpriv->pipe) < 0) 260 return _errno_to_libusb(errno); 261 262 return usbi_add_pollfd(HANDLE_CTX(handle), hpriv->pipe[0], POLLIN); 263 } 264 265 void 266 obsd_close(struct libusb_device_handle *handle) 267 { 268 struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv; 269 struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; 270 271 if (dpriv->devname) { 272 usbi_dbg("close: fd %d", dpriv->fd); 273 274 close(dpriv->fd); 275 dpriv->fd = -1; 276 } 277 278 usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->pipe[0]); 279 280 close(hpriv->pipe[0]); 281 close(hpriv->pipe[1]); 282 } 283 284 int 285 obsd_get_device_descriptor(struct libusb_device *dev, unsigned char *buf, 286 int *host_endian) 287 { 288 struct device_priv *dpriv = (struct device_priv *)dev->os_priv; 289 290 usbi_dbg(""); 291 292 memcpy(buf, &dpriv->ddesc, DEVICE_DESC_LENGTH); 293 294 *host_endian = 0; 295 296 return (LIBUSB_SUCCESS); 297 } 298 299 int 300 obsd_get_active_config_descriptor(struct libusb_device *dev, 301 unsigned char *buf, size_t len, int *host_endian) 302 { 303 struct device_priv *dpriv = (struct device_priv *)dev->os_priv; 304 usb_config_descriptor_t *ucd = (usb_config_descriptor_t *)dpriv->cdesc; 305 306 len = MIN(len, UGETW(ucd->wTotalLength)); 307 308 usbi_dbg("len %d", len); 309 310 memcpy(buf, dpriv->cdesc, len); 311 312 *host_endian = 0; 313 314 return (len); 315 } 316 317 int 318 obsd_get_config_descriptor(struct libusb_device *dev, uint8_t idx, 319 unsigned char *buf, size_t len, int *host_endian) 320 { 321 struct usb_device_fdesc udf; 322 int fd, err; 323 324 if ((fd = _bus_open(dev->bus_number)) < 0) 325 return _errno_to_libusb(errno); 326 327 udf.udf_bus = dev->bus_number; 328 udf.udf_addr = dev->device_address; 329 udf.udf_config_index = idx; 330 udf.udf_size = len; 331 udf.udf_data = buf; 332 333 usbi_dbg("index %d, len %d", udf.udf_config_index, len); 334 335 if (ioctl(fd, USB_DEVICE_GET_FDESC, &udf) < 0) { 336 err = errno; 337 close(fd); 338 return _errno_to_libusb(err); 339 } 340 close(fd); 341 342 *host_endian = 0; 343 344 return (len); 345 } 346 347 int 348 obsd_get_configuration(struct libusb_device_handle *handle, int *config) 349 { 350 struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; 351 usb_config_descriptor_t *ucd = (usb_config_descriptor_t *)dpriv->cdesc; 352 353 *config = ucd->bConfigurationValue; 354 355 usbi_dbg("bConfigurationValue %d", *config); 356 357 return (LIBUSB_SUCCESS); 358 } 359 360 int 361 obsd_set_configuration(struct libusb_device_handle *handle, int config) 362 { 363 struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; 364 365 if (dpriv->devname == NULL) 366 return (LIBUSB_ERROR_NOT_SUPPORTED); 367 368 usbi_dbg("bConfigurationValue %d", config); 369 370 if (ioctl(dpriv->fd, USB_SET_CONFIG, &config) < 0) 371 return _errno_to_libusb(errno); 372 373 return _cache_active_config_descriptor(handle->dev); 374 } 375 376 int 377 obsd_claim_interface(struct libusb_device_handle *handle, int iface) 378 { 379 struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv; 380 int i; 381 382 for (i = 0; i < USB_MAX_ENDPOINTS; i++) 383 hpriv->endpoints[i] = -1; 384 385 return (LIBUSB_SUCCESS); 386 } 387 388 int 389 obsd_release_interface(struct libusb_device_handle *handle, int iface) 390 { 391 struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv; 392 int i; 393 394 for (i = 0; i < USB_MAX_ENDPOINTS; i++) 395 if (hpriv->endpoints[i] >= 0) 396 close(hpriv->endpoints[i]); 397 398 return (LIBUSB_SUCCESS); 399 } 400 401 int 402 obsd_set_interface_altsetting(struct libusb_device_handle *handle, int iface, 403 int altsetting) 404 { 405 struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; 406 struct usb_alt_interface intf; 407 408 if (dpriv->devname == NULL) 409 return (LIBUSB_ERROR_NOT_SUPPORTED); 410 411 usbi_dbg("iface %d, setting %d", iface, altsetting); 412 413 memset(&intf, 0, sizeof(intf)); 414 415 intf.uai_interface_index = iface; 416 intf.uai_alt_no = altsetting; 417 418 if (ioctl(dpriv->fd, USB_SET_ALTINTERFACE, &intf) < 0) 419 return _errno_to_libusb(errno); 420 421 return (LIBUSB_SUCCESS); 422 } 423 424 int 425 obsd_clear_halt(struct libusb_device_handle *handle, unsigned char endpoint) 426 { 427 struct usb_ctl_request req; 428 int fd, err; 429 430 if ((fd = _bus_open(handle->dev->bus_number)) < 0) 431 return _errno_to_libusb(errno); 432 433 usbi_dbg(""); 434 435 req.ucr_addr = handle->dev->device_address; 436 req.ucr_request.bmRequestType = UT_WRITE_ENDPOINT; 437 req.ucr_request.bRequest = UR_CLEAR_FEATURE; 438 USETW(req.ucr_request.wValue, UF_ENDPOINT_HALT); 439 USETW(req.ucr_request.wIndex, endpoint); 440 USETW(req.ucr_request.wLength, 0); 441 442 if (ioctl(fd, USB_REQUEST, &req) < 0) { 443 err = errno; 444 close(fd); 445 return _errno_to_libusb(err); 446 } 447 close(fd); 448 449 return (LIBUSB_SUCCESS); 450 } 451 452 int 453 obsd_reset_device(struct libusb_device_handle *handle) 454 { 455 usbi_dbg(""); 456 457 return (LIBUSB_ERROR_NOT_SUPPORTED); 458 } 459 460 void 461 obsd_destroy_device(struct libusb_device *dev) 462 { 463 struct device_priv *dpriv = (struct device_priv *)dev->os_priv; 464 465 usbi_dbg(""); 466 467 free(dpriv->cdesc); 468 free(dpriv->devname); 469 } 470 471 int 472 obsd_submit_transfer(struct usbi_transfer *itransfer) 473 { 474 struct libusb_transfer *transfer; 475 struct handle_priv *hpriv; 476 int err = 0; 477 478 usbi_dbg(""); 479 480 transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); 481 hpriv = (struct handle_priv *)transfer->dev_handle->os_priv; 482 483 switch (transfer->type) { 484 case LIBUSB_TRANSFER_TYPE_CONTROL: 485 err = _sync_control_transfer(itransfer); 486 break; 487 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: 488 if (IS_XFEROUT(transfer)) { 489 /* Isochronous write is not supported */ 490 err = LIBUSB_ERROR_NOT_SUPPORTED; 491 break; 492 } 493 err = _sync_gen_transfer(itransfer); 494 break; 495 case LIBUSB_TRANSFER_TYPE_BULK: 496 case LIBUSB_TRANSFER_TYPE_INTERRUPT: 497 if (IS_XFEROUT(transfer) && 498 transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) { 499 err = LIBUSB_ERROR_NOT_SUPPORTED; 500 break; 501 } 502 err = _sync_gen_transfer(itransfer); 503 break; 504 } 505 506 if (err) 507 return (err); 508 509 if (write(hpriv->pipe[1], &itransfer, sizeof(itransfer)) < 0) 510 return _errno_to_libusb(errno); 511 512 return (LIBUSB_SUCCESS); 513 } 514 515 int 516 obsd_cancel_transfer(struct usbi_transfer *itransfer) 517 { 518 usbi_dbg(""); 519 520 return (LIBUSB_ERROR_NOT_SUPPORTED); 521 } 522 523 void 524 obsd_clear_transfer_priv(struct usbi_transfer *itransfer) 525 { 526 usbi_dbg(""); 527 528 /* Nothing to do */ 529 } 530 531 int 532 obsd_handle_events(struct libusb_context *ctx, struct pollfd *fds, nfds_t nfds, 533 int num_ready) 534 { 535 struct libusb_device_handle *handle; 536 struct handle_priv *hpriv = NULL; 537 struct usbi_transfer *itransfer; 538 struct pollfd *pollfd; 539 int i, err = 0; 540 541 usbi_dbg(""); 542 543 pthread_mutex_lock(&ctx->open_devs_lock); 544 for (i = 0; i < nfds && num_ready > 0; i++) { 545 pollfd = &fds[i]; 546 547 if (!pollfd->revents) 548 continue; 549 550 hpriv = NULL; 551 num_ready--; 552 list_for_each_entry(handle, &ctx->open_devs, list, 553 struct libusb_device_handle) { 554 hpriv = (struct handle_priv *)handle->os_priv; 555 556 if (hpriv->pipe[0] == pollfd->fd) 557 break; 558 559 hpriv = NULL; 560 } 561 562 if (NULL == hpriv) { 563 usbi_dbg("fd %d is not an event pipe!", pollfd->fd); 564 err = ENOENT; 565 break; 566 } 567 568 if (pollfd->revents & POLLERR) { 569 usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->pipe[0]); 570 usbi_handle_disconnect(handle); 571 continue; 572 } 573 574 if (read(hpriv->pipe[0], &itransfer, sizeof(itransfer)) < 0) { 575 err = errno; 576 break; 577 } 578 579 if ((err = usbi_handle_transfer_completion(itransfer, 580 LIBUSB_TRANSFER_COMPLETED))) 581 break; 582 } 583 pthread_mutex_unlock(&ctx->open_devs_lock); 584 585 if (err) 586 return _errno_to_libusb(err); 587 588 return (LIBUSB_SUCCESS); 589 } 590 591 int 592 obsd_clock_gettime(int clkid, struct timespec *tp) 593 { 594 usbi_dbg("clock %d", clkid); 595 596 if (clkid == USBI_CLOCK_REALTIME) 597 return clock_gettime(CLOCK_REALTIME, tp); 598 599 if (clkid == USBI_CLOCK_MONOTONIC) 600 return clock_gettime(CLOCK_MONOTONIC, tp); 601 602 return (LIBUSB_ERROR_INVALID_PARAM); 603 } 604 605 int 606 _errno_to_libusb(int err) 607 { 608 usbi_dbg("error: %s (%d)", strerror(err), err); 609 610 switch (err) { 611 case EIO: 612 return (LIBUSB_ERROR_IO); 613 case EACCES: 614 return (LIBUSB_ERROR_ACCESS); 615 case ENOENT: 616 return (LIBUSB_ERROR_NO_DEVICE); 617 case ENOMEM: 618 return (LIBUSB_ERROR_NO_MEM); 619 case ETIMEDOUT: 620 return (LIBUSB_ERROR_TIMEOUT); 621 } 622 623 return (LIBUSB_ERROR_OTHER); 624 } 625 626 int 627 _cache_active_config_descriptor(struct libusb_device *dev) 628 { 629 struct device_priv *dpriv = (struct device_priv *)dev->os_priv; 630 struct usb_device_cdesc udc; 631 struct usb_device_fdesc udf; 632 unsigned char* buf; 633 int fd, len, err; 634 635 if ((fd = _bus_open(dev->bus_number)) < 0) 636 return _errno_to_libusb(errno); 637 638 usbi_dbg("fd %d, addr %d", fd, dev->device_address); 639 640 udc.udc_bus = dev->bus_number; 641 udc.udc_addr = dev->device_address; 642 udc.udc_config_index = USB_CURRENT_CONFIG_INDEX; 643 if (ioctl(fd, USB_DEVICE_GET_CDESC, &udc) < 0) { 644 err = errno; 645 close(fd); 646 return _errno_to_libusb(errno); 647 } 648 649 usbi_dbg("active bLength %d", udc.udc_desc.bLength); 650 651 len = UGETW(udc.udc_desc.wTotalLength); 652 buf = malloc(len); 653 if (buf == NULL) 654 return (LIBUSB_ERROR_NO_MEM); 655 656 udf.udf_bus = dev->bus_number; 657 udf.udf_addr = dev->device_address; 658 udf.udf_config_index = udc.udc_config_index; 659 udf.udf_size = len; 660 udf.udf_data = buf; 661 662 usbi_dbg("index %d, len %d", udf.udf_config_index, len); 663 664 if (ioctl(fd, USB_DEVICE_GET_FDESC, &udf) < 0) { 665 err = errno; 666 close(fd); 667 free(buf); 668 return _errno_to_libusb(err); 669 } 670 close(fd); 671 672 if (dpriv->cdesc) 673 free(dpriv->cdesc); 674 dpriv->cdesc = buf; 675 676 return (LIBUSB_SUCCESS); 677 } 678 679 int 680 _sync_control_transfer(struct usbi_transfer *itransfer) 681 { 682 struct libusb_transfer *transfer; 683 struct libusb_control_setup *setup; 684 struct device_priv *dpriv; 685 struct usb_ctl_request req; 686 687 transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); 688 dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv; 689 setup = (struct libusb_control_setup *)transfer->buffer; 690 691 usbi_dbg("type %x request %x value %x index %d length %d timeout %d", 692 setup->bmRequestType, setup->bRequest, 693 libusb_le16_to_cpu(setup->wValue), 694 libusb_le16_to_cpu(setup->wIndex), 695 libusb_le16_to_cpu(setup->wLength), transfer->timeout); 696 697 req.ucr_addr = transfer->dev_handle->dev->device_address; 698 req.ucr_request.bmRequestType = setup->bmRequestType; 699 req.ucr_request.bRequest = setup->bRequest; 700 /* Don't use USETW, libusbx already deals with the endianness */ 701 (*(uint16_t *)req.ucr_request.wValue) = setup->wValue; 702 (*(uint16_t *)req.ucr_request.wIndex) = setup->wIndex; 703 (*(uint16_t *)req.ucr_request.wLength) = setup->wLength; 704 req.ucr_data = transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE; 705 706 if ((transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) == 0) 707 req.ucr_flags = USBD_SHORT_XFER_OK; 708 709 if (dpriv->devname == NULL) { 710 /* 711 * XXX If the device is not attached to ugen(4) it is 712 * XXX still possible to submit a control transfer but 713 * XXX with the default timeout only. 714 */ 715 int fd, err; 716 717 if ((fd = _bus_open(transfer->dev_handle->dev->bus_number)) < 0) 718 return _errno_to_libusb(errno); 719 720 if ((ioctl(fd, USB_REQUEST, &req)) < 0) { 721 err = errno; 722 close(fd); 723 return _errno_to_libusb(err); 724 } 725 close(fd); 726 } else { 727 if ((ioctl(dpriv->fd, USB_SET_TIMEOUT, &transfer->timeout)) < 0) 728 return _errno_to_libusb(errno); 729 730 if ((ioctl(dpriv->fd, USB_DO_REQUEST, &req)) < 0) 731 return _errno_to_libusb(errno); 732 } 733 734 itransfer->transferred = req.ucr_actlen; 735 736 usbi_dbg("transferred %d", itransfer->transferred); 737 738 return (0); 739 } 740 741 int 742 _access_endpoint(struct libusb_transfer *transfer) 743 { 744 struct handle_priv *hpriv; 745 struct device_priv *dpriv; 746 char devnode[16]; 747 int fd, endpt; 748 mode_t mode; 749 750 hpriv = (struct handle_priv *)transfer->dev_handle->os_priv; 751 dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv; 752 753 endpt = UE_GET_ADDR(transfer->endpoint); 754 mode = IS_XFERIN(transfer) ? O_RDONLY : O_WRONLY; 755 756 usbi_dbg("endpoint %d mode %d", endpt, mode); 757 758 if (hpriv->endpoints[endpt] < 0) { 759 /* Pick the right endpoint node */ 760 snprintf(devnode, sizeof(devnode), DEVPATH "%s.%02d", 761 dpriv->devname, endpt); 762 763 /* We may need to read/write to the same endpoint later. */ 764 if (((fd = open(devnode, O_RDWR)) < 0) && (errno == ENXIO)) 765 if ((fd = open(devnode, mode)) < 0) 766 return (-1); 767 768 hpriv->endpoints[endpt] = fd; 769 } 770 771 return (hpriv->endpoints[endpt]); 772 } 773 774 int 775 _sync_gen_transfer(struct usbi_transfer *itransfer) 776 { 777 struct libusb_transfer *transfer; 778 struct device_priv *dpriv; 779 int fd, nr = 1; 780 781 transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); 782 dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv; 783 784 if (dpriv->devname == NULL) 785 return (LIBUSB_ERROR_NOT_SUPPORTED); 786 787 /* 788 * Bulk, Interrupt or Isochronous transfer depends on the 789 * endpoint and thus the node to open. 790 */ 791 if ((fd = _access_endpoint(transfer)) < 0) 792 return _errno_to_libusb(errno); 793 794 if ((ioctl(fd, USB_SET_TIMEOUT, &transfer->timeout)) < 0) 795 return _errno_to_libusb(errno); 796 797 if (IS_XFERIN(transfer)) { 798 if ((transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) == 0) 799 if ((ioctl(fd, USB_SET_SHORT_XFER, &nr)) < 0) 800 return _errno_to_libusb(errno); 801 802 nr = read(fd, transfer->buffer, transfer->length); 803 } else { 804 nr = write(fd, transfer->buffer, transfer->length); 805 } 806 807 if (nr < 0) 808 return _errno_to_libusb(errno); 809 810 itransfer->transferred = nr; 811 812 return (0); 813 } 814 815 int 816 _bus_open(int number) 817 { 818 char busnode[16]; 819 820 snprintf(busnode, sizeof(busnode), USBDEV "%d", number); 821 822 return open(busnode, O_RDWR); 823 } 824