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