1 /* 2 * Copyright (c) 2011 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 devnode[16]; 36 int fd; 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 *, int); 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 const struct usbi_os_backend openbsd_backend = { 91 "Synchronous OpenBSD backend", 92 NULL, /* init() */ 93 NULL, /* exit() */ 94 obsd_get_device_list, 95 obsd_open, 96 obsd_close, 97 98 obsd_get_device_descriptor, 99 obsd_get_active_config_descriptor, 100 obsd_get_config_descriptor, 101 102 obsd_get_configuration, 103 obsd_set_configuration, 104 105 obsd_claim_interface, 106 obsd_release_interface, 107 108 obsd_set_interface_altsetting, 109 obsd_clear_halt, 110 obsd_reset_device, 111 112 NULL, /* kernel_driver_active() */ 113 NULL, /* detach_kernel_driver() */ 114 NULL, /* attach_kernel_driver() */ 115 116 obsd_destroy_device, 117 118 obsd_submit_transfer, 119 obsd_cancel_transfer, 120 obsd_clear_transfer_priv, 121 122 obsd_handle_events, 123 124 obsd_clock_gettime, 125 sizeof(struct device_priv), 126 sizeof(struct handle_priv), 127 0, /* transfer_priv_size */ 128 0, /* add_iso_packet_size */ 129 }; 130 131 int 132 obsd_get_device_list(struct libusb_context * ctx, 133 struct discovered_devs **discdevs) 134 { 135 struct libusb_device *dev; 136 struct device_priv *dpriv; 137 struct usb_device_info di; 138 unsigned long session_id; 139 char devnode[16]; 140 int fd, err, i; 141 142 usbi_dbg(""); 143 144 /* Only ugen(4) is supported */ 145 for (i = 0; i < USB_MAX_DEVICES; i++) { 146 /* Control endpoint is always .00 */ 147 snprintf(devnode, sizeof(devnode), "/dev/ugen%d.00", i); 148 149 if ((fd = open(devnode, O_RDONLY)) < 0) { 150 if (errno != ENOENT && errno != ENXIO) 151 usbi_err(ctx, "could not open %s", devnode); 152 continue; 153 } 154 155 if (ioctl(fd, USB_GET_DEVICEINFO, &di) < 0) 156 continue; 157 158 session_id = (di.udi_bus << 8 | di.udi_addr); 159 dev = usbi_get_device_by_session_id(ctx, session_id); 160 161 if (dev == NULL) { 162 dev = usbi_alloc_device(ctx, session_id); 163 if (dev == NULL) 164 return (LIBUSB_ERROR_NO_MEM); 165 166 dev->bus_number = di.udi_bus; 167 dev->device_address = di.udi_addr; 168 dev->speed = di.udi_speed; 169 170 dpriv = (struct device_priv *)dev->os_priv; 171 strlcpy(dpriv->devnode, devnode, sizeof(devnode)); 172 dpriv->fd = -1; 173 174 if (ioctl(fd, USB_GET_DEVICE_DESC, &dpriv->ddesc) < 0) { 175 err = errno; 176 goto error; 177 } 178 179 dpriv->cdesc = NULL; 180 if (_cache_active_config_descriptor(dev, fd)) { 181 err = errno; 182 goto error; 183 } 184 185 if ((err = usbi_sanitize_device(dev))) 186 goto error; 187 } 188 close(fd); 189 190 if (discovered_devs_append(*discdevs, dev) == NULL) 191 return (LIBUSB_ERROR_NO_MEM); 192 } 193 194 return (LIBUSB_SUCCESS); 195 196 error: 197 close(fd); 198 libusb_unref_device(dev); 199 return _errno_to_libusb(err); 200 } 201 202 int 203 obsd_open(struct libusb_device_handle *handle) 204 { 205 struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv; 206 struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; 207 208 dpriv->fd = open(dpriv->devnode, O_RDWR); 209 if (dpriv->fd < 0) { 210 dpriv->fd = open(dpriv->devnode, O_RDONLY); 211 if (dpriv->fd < 0) 212 return _errno_to_libusb(errno); 213 } 214 215 usbi_dbg("open %s: fd %d", dpriv->devnode, dpriv->fd); 216 217 if (pipe(hpriv->pipe) < 0) 218 return _errno_to_libusb(errno); 219 220 return usbi_add_pollfd(HANDLE_CTX(handle), hpriv->pipe[0], POLLIN); 221 } 222 223 void 224 obsd_close(struct libusb_device_handle *handle) 225 { 226 struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv; 227 struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; 228 229 usbi_dbg("close: fd %d", dpriv->fd); 230 231 close(dpriv->fd); 232 dpriv->fd = -1; 233 234 usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->pipe[0]); 235 236 close(hpriv->pipe[0]); 237 close(hpriv->pipe[1]); 238 } 239 240 int 241 obsd_get_device_descriptor(struct libusb_device *dev, unsigned char *buf, 242 int *host_endian) 243 { 244 struct device_priv *dpriv = (struct device_priv *)dev->os_priv; 245 246 usbi_dbg(""); 247 248 memcpy(buf, &dpriv->ddesc, DEVICE_DESC_LENGTH); 249 250 *host_endian = 0; 251 252 return (LIBUSB_SUCCESS); 253 } 254 255 int 256 obsd_get_active_config_descriptor(struct libusb_device *dev, 257 unsigned char *buf, size_t len, int *host_endian) 258 { 259 struct device_priv *dpriv = (struct device_priv *)dev->os_priv; 260 usb_config_descriptor_t *ucd; 261 262 ucd = (usb_config_descriptor_t *) dpriv->cdesc; 263 len = MIN(len, UGETW(ucd->wTotalLength)); 264 265 usbi_dbg("len %d", len); 266 267 memcpy(buf, dpriv->cdesc, len); 268 269 *host_endian = 0; 270 271 return (LIBUSB_SUCCESS); 272 } 273 274 int 275 obsd_get_config_descriptor(struct libusb_device *dev, uint8_t idx, 276 unsigned char *buf, size_t len, int *host_endian) 277 { 278 struct device_priv *dpriv = (struct device_priv *)dev->os_priv; 279 struct usb_full_desc ufd; 280 int fd, err; 281 282 usbi_dbg("index %d, len %d", idx, len); 283 284 /* A config descriptor may be requested before opening the device */ 285 if (dpriv->fd >= 0) { 286 fd = dpriv->fd; 287 } else { 288 fd = open(dpriv->devnode, O_RDONLY); 289 if (fd < 0) 290 return _errno_to_libusb(errno); 291 } 292 293 ufd.ufd_config_index = idx; 294 ufd.ufd_size = len; 295 ufd.ufd_data = buf; 296 297 if ((ioctl(fd, USB_GET_FULL_DESC, &ufd)) < 0) { 298 err = errno; 299 if (dpriv->fd < 0) 300 close(fd); 301 return _errno_to_libusb(err); 302 } 303 304 if (dpriv->fd < 0) 305 close(fd); 306 307 *host_endian = 0; 308 309 return (LIBUSB_SUCCESS); 310 } 311 312 int 313 obsd_get_configuration(struct libusb_device_handle *handle, int *config) 314 { 315 struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; 316 317 usbi_dbg(""); 318 319 if (ioctl(dpriv->fd, USB_GET_CONFIG, config) < 0) 320 return _errno_to_libusb(errno); 321 322 usbi_dbg("configuration %d", *config); 323 324 return (LIBUSB_SUCCESS); 325 } 326 327 int 328 obsd_set_configuration(struct libusb_device_handle *handle, int config) 329 { 330 struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; 331 332 usbi_dbg("configuration %d", config); 333 334 if (ioctl(dpriv->fd, USB_SET_CONFIG, &config) < 0) 335 return _errno_to_libusb(errno); 336 337 return _cache_active_config_descriptor(handle->dev, dpriv->fd); 338 } 339 340 int 341 obsd_claim_interface(struct libusb_device_handle *handle, int iface) 342 { 343 struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv; 344 int i; 345 346 for (i = 0; i < USB_MAX_ENDPOINTS; i++) 347 hpriv->endpoints[i] = -1; 348 349 return (LIBUSB_SUCCESS); 350 } 351 352 int 353 obsd_release_interface(struct libusb_device_handle *handle, int iface) 354 { 355 struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv; 356 int i; 357 358 for (i = 0; i < USB_MAX_ENDPOINTS; i++) 359 if (hpriv->endpoints[i] >= 0) 360 close(hpriv->endpoints[i]); 361 362 return (LIBUSB_SUCCESS); 363 } 364 365 int 366 obsd_set_interface_altsetting(struct libusb_device_handle *handle, int iface, 367 int altsetting) 368 { 369 struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; 370 struct usb_alt_interface intf; 371 372 usbi_dbg("iface %d, setting %d", iface, altsetting); 373 374 memset(&intf, 0, sizeof(intf)); 375 376 intf.uai_interface_index = iface; 377 intf.uai_alt_no = altsetting; 378 379 if (ioctl(dpriv->fd, USB_SET_ALTINTERFACE, &intf) < 0) 380 return _errno_to_libusb(errno); 381 382 return (LIBUSB_SUCCESS); 383 } 384 385 int 386 obsd_clear_halt(struct libusb_device_handle *handle, unsigned char endpoint) 387 { 388 struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; 389 struct usb_ctl_request req; 390 391 usbi_dbg(""); 392 393 req.ucr_request.bmRequestType = UT_WRITE_ENDPOINT; 394 req.ucr_request.bRequest = UR_CLEAR_FEATURE; 395 USETW(req.ucr_request.wValue, UF_ENDPOINT_HALT); 396 USETW(req.ucr_request.wIndex, endpoint); 397 USETW(req.ucr_request.wLength, 0); 398 399 if (ioctl(dpriv->fd, USB_DO_REQUEST, &req) < 0) 400 return _errno_to_libusb(errno); 401 402 return (LIBUSB_SUCCESS); 403 } 404 405 int 406 obsd_reset_device(struct libusb_device_handle *handle) 407 { 408 usbi_dbg(""); 409 410 return (LIBUSB_ERROR_NOT_SUPPORTED); 411 } 412 413 void 414 obsd_destroy_device(struct libusb_device *dev) 415 { 416 struct device_priv *dpriv = (struct device_priv *)dev->os_priv; 417 418 usbi_dbg(""); 419 420 free(dpriv->cdesc); 421 } 422 423 int 424 obsd_submit_transfer(struct usbi_transfer *itransfer) 425 { 426 struct libusb_transfer *transfer; 427 struct handle_priv *hpriv; 428 int err = 0; 429 430 usbi_dbg(""); 431 432 transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); 433 hpriv = (struct handle_priv *)transfer->dev_handle->os_priv; 434 435 switch (transfer->type) { 436 case LIBUSB_TRANSFER_TYPE_CONTROL: 437 err = _sync_control_transfer(itransfer); 438 break; 439 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: 440 if (IS_XFEROUT(transfer)) { 441 /* Isochronous write is not supported */ 442 err = LIBUSB_ERROR_NOT_SUPPORTED; 443 break; 444 } 445 err = _sync_gen_transfer(itransfer); 446 break; 447 case LIBUSB_TRANSFER_TYPE_BULK: 448 case LIBUSB_TRANSFER_TYPE_INTERRUPT: 449 if (IS_XFEROUT(transfer) && 450 transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) { 451 err = LIBUSB_ERROR_NOT_SUPPORTED; 452 break; 453 } 454 err = _sync_gen_transfer(itransfer); 455 break; 456 } 457 458 if (err) 459 return (err); 460 461 if (write(hpriv->pipe[1], &itransfer, sizeof(itransfer)) < 0) 462 return _errno_to_libusb(errno); 463 464 return (LIBUSB_SUCCESS); 465 } 466 467 int 468 obsd_cancel_transfer(struct usbi_transfer *itransfer) 469 { 470 usbi_dbg(""); 471 472 return (LIBUSB_ERROR_NOT_SUPPORTED); 473 } 474 475 void 476 obsd_clear_transfer_priv(struct usbi_transfer *itransfer) 477 { 478 usbi_dbg(""); 479 480 /* Nothing to do */ 481 } 482 483 int 484 obsd_handle_events(struct libusb_context *ctx, struct pollfd *fds, nfds_t nfds, 485 int num_ready) 486 { 487 struct libusb_device_handle *handle; 488 struct handle_priv *hpriv = NULL; 489 struct usbi_transfer *itransfer; 490 struct pollfd *pollfd; 491 int i, err = 0; 492 493 usbi_dbg(""); 494 495 pthread_mutex_lock(&ctx->open_devs_lock); 496 for (i = 0; i < nfds && num_ready > 0; i++) { 497 pollfd = &fds[i]; 498 499 if (!pollfd->revents) 500 continue; 501 502 hpriv = NULL; 503 num_ready--; 504 list_for_each_entry(handle, &ctx->open_devs, list, 505 struct libusb_device_handle) { 506 hpriv = (struct handle_priv *)handle->os_priv; 507 508 if (hpriv->pipe[0] == pollfd->fd) 509 break; 510 511 hpriv = NULL; 512 } 513 514 if (NULL == hpriv) { 515 usbi_dbg("fd %d is not an event pipe!", pollfd->fd); 516 err = ENOENT; 517 break; 518 } 519 520 if (pollfd->revents & POLLERR) { 521 usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->pipe[0]); 522 usbi_handle_disconnect(handle); 523 continue; 524 } 525 526 if (read(hpriv->pipe[0], &itransfer, sizeof(itransfer)) < 0) { 527 err = errno; 528 break; 529 } 530 531 if ((err = usbi_handle_transfer_completion(itransfer, 532 LIBUSB_TRANSFER_COMPLETED))) 533 break; 534 } 535 pthread_mutex_unlock(&ctx->open_devs_lock); 536 537 if (err) 538 return _errno_to_libusb(err); 539 540 return (LIBUSB_SUCCESS); 541 } 542 543 int 544 obsd_clock_gettime(int clkid, struct timespec *tp) 545 { 546 usbi_dbg("clock %d", clkid); 547 548 if (clkid == USBI_CLOCK_REALTIME) 549 return clock_gettime(CLOCK_REALTIME, tp); 550 551 if (clkid == USBI_CLOCK_MONOTONIC) 552 return clock_gettime(CLOCK_MONOTONIC, tp); 553 554 return (LIBUSB_ERROR_INVALID_PARAM); 555 } 556 557 int 558 _errno_to_libusb(int err) 559 { 560 switch (err) { 561 case EIO: 562 return (LIBUSB_ERROR_IO); 563 case EACCES: 564 return (LIBUSB_ERROR_ACCESS); 565 case ENOENT: 566 return (LIBUSB_ERROR_NO_DEVICE); 567 case ENOMEM: 568 return (LIBUSB_ERROR_NO_MEM); 569 } 570 571 usbi_dbg("error: %s", strerror(err)); 572 573 return (LIBUSB_ERROR_OTHER); 574 } 575 576 int 577 _cache_active_config_descriptor(struct libusb_device *dev, int fd) 578 { 579 struct device_priv *dpriv = (struct device_priv *)dev->os_priv; 580 struct usb_config_desc ucd; 581 struct usb_full_desc ufd; 582 unsigned char* buf; 583 int len; 584 585 usbi_dbg("fd %d", fd); 586 587 ucd.ucd_config_index = USB_CURRENT_CONFIG_INDEX; 588 589 if ((ioctl(fd, USB_GET_CONFIG_DESC, &ucd)) < 0) 590 return _errno_to_libusb(errno); 591 592 usbi_dbg("active bLength %d", ucd.ucd_desc.bLength); 593 594 len = UGETW(ucd.ucd_desc.wTotalLength); 595 buf = malloc(len); 596 if (buf == NULL) 597 return (LIBUSB_ERROR_NO_MEM); 598 599 ufd.ufd_config_index = ucd.ucd_config_index; 600 ufd.ufd_size = len; 601 ufd.ufd_data = buf; 602 603 usbi_dbg("index %d, len %d", ufd.ufd_config_index, len); 604 605 if ((ioctl(fd, USB_GET_FULL_DESC, &ufd)) < 0) { 606 free(buf); 607 return _errno_to_libusb(errno); 608 } 609 610 if (dpriv->cdesc) 611 free(dpriv->cdesc); 612 dpriv->cdesc = buf; 613 614 return (0); 615 } 616 617 int 618 _sync_control_transfer(struct usbi_transfer *itransfer) 619 { 620 struct libusb_transfer *transfer; 621 struct libusb_control_setup *setup; 622 struct device_priv *dpriv; 623 struct usb_ctl_request req; 624 625 transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); 626 dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv; 627 setup = (struct libusb_control_setup *)transfer->buffer; 628 629 usbi_dbg("type %d request %d value %d index %d length %d timeout %d", 630 setup->bmRequestType, setup->bRequest, 631 libusb_le16_to_cpu(setup->wValue), 632 libusb_le16_to_cpu(setup->wIndex), 633 libusb_le16_to_cpu(setup->wLength), transfer->timeout); 634 635 req.ucr_request.bmRequestType = setup->bmRequestType; 636 req.ucr_request.bRequest = setup->bRequest; 637 /* Don't use USETW, libusb already deals with the endianness */ 638 (*(uint16_t *)req.ucr_request.wValue) = setup->wValue; 639 (*(uint16_t *)req.ucr_request.wIndex) = setup->wIndex; 640 (*(uint16_t *)req.ucr_request.wLength) = setup->wLength; 641 req.ucr_data = transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE; 642 643 if ((transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) == 0) 644 req.ucr_flags = USBD_SHORT_XFER_OK; 645 646 if ((ioctl(dpriv->fd, USB_SET_TIMEOUT, &transfer->timeout)) < 0) 647 return _errno_to_libusb(errno); 648 649 if ((ioctl(dpriv->fd, USB_DO_REQUEST, &req)) < 0) 650 return _errno_to_libusb(errno); 651 652 itransfer->transferred = req.ucr_actlen; 653 654 usbi_dbg("transferred %d", itransfer->transferred); 655 656 return (0); 657 } 658 659 int 660 _access_endpoint(struct libusb_transfer *transfer) 661 { 662 struct handle_priv *hpriv; 663 struct device_priv *dpriv; 664 char *s, devnode[16]; 665 int fd, endpt; 666 mode_t mode; 667 668 hpriv = (struct handle_priv *)transfer->dev_handle->os_priv; 669 dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv; 670 671 endpt = UE_GET_ADDR(transfer->endpoint); 672 mode = IS_XFERIN(transfer) ? O_RDONLY : O_WRONLY; 673 674 usbi_dbg("endpoint %d mode %d", endpt, mode); 675 676 if (hpriv->endpoints[endpt] < 0) { 677 /* Pick the right node given the control one */ 678 strlcpy(devnode, dpriv->devnode, sizeof(devnode)); 679 s = strchr(devnode, '.'); 680 snprintf(s, 4, ".%02d", endpt); 681 682 /* We may need to read/write to the same endpoint later. */ 683 if (((fd = open(devnode, O_RDWR)) < 0) && (errno == ENXIO)) 684 if ((fd = open(devnode, mode)) < 0) 685 return (-1); 686 687 hpriv->endpoints[endpt] = fd; 688 } 689 690 return (hpriv->endpoints[endpt]); 691 } 692 693 int 694 _sync_gen_transfer(struct usbi_transfer *itransfer) 695 { 696 struct libusb_transfer *transfer; 697 int fd, nr = 1; 698 699 transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); 700 701 /* 702 * Bulk, Interrupt or Isochronous transfer depends on the 703 * endpoint and thus the node to open. 704 */ 705 if ((fd = _access_endpoint(transfer)) < 0) 706 return _errno_to_libusb(errno); 707 708 if ((ioctl(fd, USB_SET_TIMEOUT, &transfer->timeout)) < 0) 709 return _errno_to_libusb(errno); 710 711 if (IS_XFERIN(transfer)) { 712 if ((transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) == 0) 713 if ((ioctl(fd, USB_SET_SHORT_XFER, &nr)) < 0) 714 return _errno_to_libusb(errno); 715 716 nr = read(fd, transfer->buffer, transfer->length); 717 } else { 718 nr = write(fd, transfer->buffer, transfer->length); 719 } 720 721 if (nr < 0) 722 return _errno_to_libusb(errno); 723 724 itransfer->transferred = nr; 725 726 return (0); 727 } 728