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