2 * Copyright © 2011-2013 Martin Pieuchot <mpi@openbsd.org>
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.
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.
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
22 #include <sys/types.h>
31 #include <dev/usb/usb.h>
36 char *devname; /* name of the ugen(4) node */
37 int fd; /* device file descriptor */
39 unsigned char *cdesc; /* active config descriptor */
40 usb_device_descriptor_t ddesc; /* usb device descriptor */
44 int pipe[2]; /* for event notification */
45 int endpoints[USB_MAX_ENDPOINTS];
51 static int obsd_get_device_list(struct libusb_context *,
52 struct discovered_devs **);
53 static int obsd_open(struct libusb_device_handle *);
54 static void obsd_close(struct libusb_device_handle *);
56 static int obsd_get_device_descriptor(struct libusb_device *, unsigned char *,
58 static int obsd_get_active_config_descriptor(struct libusb_device *,
59 unsigned char *, size_t, int *);
60 static int obsd_get_config_descriptor(struct libusb_device *, uint8_t,
61 unsigned char *, size_t, int *);
63 static int obsd_get_configuration(struct libusb_device_handle *, int *);
64 static int obsd_set_configuration(struct libusb_device_handle *, int);
66 static int obsd_claim_interface(struct libusb_device_handle *, int);
67 static int obsd_release_interface(struct libusb_device_handle *, int);
69 static int obsd_set_interface_altsetting(struct libusb_device_handle *, int,
71 static int obsd_clear_halt(struct libusb_device_handle *, unsigned char);
72 static int obsd_reset_device(struct libusb_device_handle *);
73 static void obsd_destroy_device(struct libusb_device *);
75 static int obsd_submit_transfer(struct usbi_transfer *);
76 static int obsd_cancel_transfer(struct usbi_transfer *);
77 static void obsd_clear_transfer_priv(struct usbi_transfer *);
78 static int obsd_handle_events(struct libusb_context *ctx, struct pollfd *,
80 static int obsd_clock_gettime(int, struct timespec *);
85 static int _errno_to_libusb(int);
86 static int _cache_active_config_descriptor(struct libusb_device *);
87 static int _sync_control_transfer(struct usbi_transfer *);
88 static int _sync_gen_transfer(struct usbi_transfer *);
89 static int _access_endpoint(struct libusb_transfer *);
91 static int _bus_open(int);
94 const struct usbi_os_backend openbsd_backend = {
95 "Synchronous OpenBSD backend",
96 USBI_CAP_HAS_POLLABLE_DEVICE_FD,
100 NULL, /* hotplug_poll */
104 obsd_get_device_descriptor,
105 obsd_get_active_config_descriptor,
106 obsd_get_config_descriptor,
107 NULL, /* get_config_descriptor_by_value() */
109 obsd_get_configuration,
110 obsd_set_configuration,
112 obsd_claim_interface,
113 obsd_release_interface,
115 obsd_set_interface_altsetting,
119 NULL, /* alloc_streams */
120 NULL, /* free_streams */
122 NULL, /* kernel_driver_active() */
123 NULL, /* detach_kernel_driver() */
124 NULL, /* attach_kernel_driver() */
128 obsd_submit_transfer,
129 obsd_cancel_transfer,
130 obsd_clear_transfer_priv,
135 sizeof(struct device_priv),
136 sizeof(struct handle_priv),
137 0, /* transfer_priv_size */
138 0, /* add_iso_packet_size */
141 #define DEVPATH "/dev/"
142 #define USBDEV DEVPATH "usb"
145 obsd_get_device_list(struct libusb_context * ctx,
146 struct discovered_devs **discdevs)
148 struct discovered_devs *ddd;
149 struct libusb_device *dev;
150 struct device_priv *dpriv;
151 struct usb_device_info di;
152 struct usb_device_ddesc dd;
153 unsigned long session_id;
154 char devices[USB_MAX_DEVICES];
161 for (i = 0; i < 8; i++) {
162 snprintf(busnode, sizeof(busnode), USBDEV "%d", i);
164 if ((fd = open(busnode, O_RDWR)) < 0) {
165 if (errno != ENOENT && errno != ENXIO)
166 usbi_err(ctx, "could not open %s", busnode);
170 bzero(devices, sizeof(devices));
171 for (addr = 1; addr < USB_MAX_DEVICES; addr++) {
176 if (ioctl(fd, USB_DEVICEINFO, &di) < 0)
180 * XXX If ugen(4) is attached to the USB device
184 for (j = 0; j < USB_MAX_DEVNAMES; j++)
185 if (!strncmp("ugen", di.udi_devnames[j], 4)) {
186 udevname = strdup(di.udi_devnames[j]);
190 session_id = (di.udi_bus << 8 | di.udi_addr);
191 dev = usbi_get_device_by_session_id(ctx, session_id);
194 dev = usbi_alloc_device(ctx, session_id);
197 return (LIBUSB_ERROR_NO_MEM);
200 dev->bus_number = di.udi_bus;
201 dev->device_address = di.udi_addr;
202 dev->speed = di.udi_speed;
204 dpriv = (struct device_priv *)dev->os_priv;
207 dpriv->devname = udevname;
209 dd.udd_bus = di.udi_bus;
210 dd.udd_addr = di.udi_addr;
211 if (ioctl(fd, USB_DEVICE_GET_DDESC, &dd) < 0) {
212 libusb_unref_device(dev);
215 dpriv->ddesc = dd.udd_desc;
217 if (_cache_active_config_descriptor(dev)) {
218 libusb_unref_device(dev);
222 if (usbi_sanitize_device(dev)) {
223 libusb_unref_device(dev);
228 ddd = discovered_devs_append(*discdevs, dev);
231 return (LIBUSB_ERROR_NO_MEM);
233 libusb_unref_device(dev);
242 return (LIBUSB_SUCCESS);
246 obsd_open(struct libusb_device_handle *handle)
248 struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv;
249 struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
252 if (dpriv->devname) {
254 * Only open ugen(4) attached devices read-write, all
255 * read-only operations are done through the bus node.
257 snprintf(devnode, sizeof(devnode), DEVPATH "%s.00",
259 dpriv->fd = open(devnode, O_RDWR);
261 return _errno_to_libusb(errno);
263 usbi_dbg("open %s: fd %d", devnode, dpriv->fd);
266 if (pipe(hpriv->pipe) < 0)
267 return _errno_to_libusb(errno);
269 return usbi_add_pollfd(HANDLE_CTX(handle), hpriv->pipe[0], POLLIN);
273 obsd_close(struct libusb_device_handle *handle)
275 struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv;
276 struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
278 if (dpriv->devname) {
279 usbi_dbg("close: fd %d", dpriv->fd);
285 usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->pipe[0]);
287 close(hpriv->pipe[0]);
288 close(hpriv->pipe[1]);
292 obsd_get_device_descriptor(struct libusb_device *dev, unsigned char *buf,
295 struct device_priv *dpriv = (struct device_priv *)dev->os_priv;
299 memcpy(buf, &dpriv->ddesc, DEVICE_DESC_LENGTH);
303 return (LIBUSB_SUCCESS);
307 obsd_get_active_config_descriptor(struct libusb_device *dev,
308 unsigned char *buf, size_t len, int *host_endian)
310 struct device_priv *dpriv = (struct device_priv *)dev->os_priv;
311 usb_config_descriptor_t *ucd = (usb_config_descriptor_t *)dpriv->cdesc;
313 len = MIN(len, UGETW(ucd->wTotalLength));
315 usbi_dbg("len %d", len);
317 memcpy(buf, dpriv->cdesc, len);
325 obsd_get_config_descriptor(struct libusb_device *dev, uint8_t idx,
326 unsigned char *buf, size_t len, int *host_endian)
328 struct usb_device_fdesc udf;
331 if ((fd = _bus_open(dev->bus_number)) < 0)
332 return _errno_to_libusb(errno);
334 udf.udf_bus = dev->bus_number;
335 udf.udf_addr = dev->device_address;
336 udf.udf_config_index = idx;
340 usbi_dbg("index %d, len %d", udf.udf_config_index, len);
342 if (ioctl(fd, USB_DEVICE_GET_FDESC, &udf) < 0) {
345 return _errno_to_libusb(err);
355 obsd_get_configuration(struct libusb_device_handle *handle, int *config)
357 struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
358 usb_config_descriptor_t *ucd = (usb_config_descriptor_t *)dpriv->cdesc;
360 *config = ucd->bConfigurationValue;
362 usbi_dbg("bConfigurationValue %d", *config);
364 return (LIBUSB_SUCCESS);
368 obsd_set_configuration(struct libusb_device_handle *handle, int config)
370 struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
372 if (dpriv->devname == NULL)
373 return (LIBUSB_ERROR_NOT_SUPPORTED);
375 usbi_dbg("bConfigurationValue %d", config);
377 if (ioctl(dpriv->fd, USB_SET_CONFIG, &config) < 0)
378 return _errno_to_libusb(errno);
380 return _cache_active_config_descriptor(handle->dev);
384 obsd_claim_interface(struct libusb_device_handle *handle, int iface)
386 struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv;
389 for (i = 0; i < USB_MAX_ENDPOINTS; i++)
390 hpriv->endpoints[i] = -1;
392 return (LIBUSB_SUCCESS);
396 obsd_release_interface(struct libusb_device_handle *handle, int iface)
398 struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv;
401 for (i = 0; i < USB_MAX_ENDPOINTS; i++)
402 if (hpriv->endpoints[i] >= 0)
403 close(hpriv->endpoints[i]);
405 return (LIBUSB_SUCCESS);
409 obsd_set_interface_altsetting(struct libusb_device_handle *handle, int iface,
412 struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
413 struct usb_alt_interface intf;
415 if (dpriv->devname == NULL)
416 return (LIBUSB_ERROR_NOT_SUPPORTED);
418 usbi_dbg("iface %d, setting %d", iface, altsetting);
420 memset(&intf, 0, sizeof(intf));
422 intf.uai_interface_index = iface;
423 intf.uai_alt_no = altsetting;
425 if (ioctl(dpriv->fd, USB_SET_ALTINTERFACE, &intf) < 0)
426 return _errno_to_libusb(errno);
428 return (LIBUSB_SUCCESS);
432 obsd_clear_halt(struct libusb_device_handle *handle, unsigned char endpoint)
434 struct usb_ctl_request req;
437 if ((fd = _bus_open(handle->dev->bus_number)) < 0)
438 return _errno_to_libusb(errno);
442 req.ucr_addr = handle->dev->device_address;
443 req.ucr_request.bmRequestType = UT_WRITE_ENDPOINT;
444 req.ucr_request.bRequest = UR_CLEAR_FEATURE;
445 USETW(req.ucr_request.wValue, UF_ENDPOINT_HALT);
446 USETW(req.ucr_request.wIndex, endpoint);
447 USETW(req.ucr_request.wLength, 0);
449 if (ioctl(fd, USB_REQUEST, &req) < 0) {
452 return _errno_to_libusb(err);
456 return (LIBUSB_SUCCESS);
460 obsd_reset_device(struct libusb_device_handle *handle)
464 return (LIBUSB_ERROR_NOT_SUPPORTED);
468 obsd_destroy_device(struct libusb_device *dev)
470 struct device_priv *dpriv = (struct device_priv *)dev->os_priv;
475 free(dpriv->devname);
479 obsd_submit_transfer(struct usbi_transfer *itransfer)
481 struct libusb_transfer *transfer;
482 struct handle_priv *hpriv;
487 transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
488 hpriv = (struct handle_priv *)transfer->dev_handle->os_priv;
490 switch (transfer->type) {
491 case LIBUSB_TRANSFER_TYPE_CONTROL:
492 err = _sync_control_transfer(itransfer);
494 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
495 if (IS_XFEROUT(transfer)) {
496 /* Isochronous write is not supported */
497 err = LIBUSB_ERROR_NOT_SUPPORTED;
500 err = _sync_gen_transfer(itransfer);
502 case LIBUSB_TRANSFER_TYPE_BULK:
503 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
504 if (IS_XFEROUT(transfer) &&
505 transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) {
506 err = LIBUSB_ERROR_NOT_SUPPORTED;
509 err = _sync_gen_transfer(itransfer);
511 case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
512 err = LIBUSB_ERROR_NOT_SUPPORTED;
519 if (write(hpriv->pipe[1], &itransfer, sizeof(itransfer)) < 0)
520 return _errno_to_libusb(errno);
522 return (LIBUSB_SUCCESS);
526 obsd_cancel_transfer(struct usbi_transfer *itransfer)
530 return (LIBUSB_ERROR_NOT_SUPPORTED);
534 obsd_clear_transfer_priv(struct usbi_transfer *itransfer)
542 obsd_handle_events(struct libusb_context *ctx, struct pollfd *fds, nfds_t nfds,
545 struct libusb_device_handle *handle;
546 struct handle_priv *hpriv = NULL;
547 struct usbi_transfer *itransfer;
548 struct pollfd *pollfd;
553 pthread_mutex_lock(&ctx->open_devs_lock);
554 for (i = 0; i < nfds && num_ready > 0; i++) {
557 if (!pollfd->revents)
562 list_for_each_entry(handle, &ctx->open_devs, list,
563 struct libusb_device_handle) {
564 hpriv = (struct handle_priv *)handle->os_priv;
566 if (hpriv->pipe[0] == pollfd->fd)
573 usbi_dbg("fd %d is not an event pipe!", pollfd->fd);
578 if (pollfd->revents & POLLERR) {
579 usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->pipe[0]);
580 usbi_handle_disconnect(handle);
584 if (read(hpriv->pipe[0], &itransfer, sizeof(itransfer)) < 0) {
589 if ((err = usbi_handle_transfer_completion(itransfer,
590 LIBUSB_TRANSFER_COMPLETED)))
593 pthread_mutex_unlock(&ctx->open_devs_lock);
596 return _errno_to_libusb(err);
598 return (LIBUSB_SUCCESS);
602 obsd_clock_gettime(int clkid, struct timespec *tp)
604 usbi_dbg("clock %d", clkid);
606 if (clkid == USBI_CLOCK_REALTIME)
607 return clock_gettime(CLOCK_REALTIME, tp);
609 if (clkid == USBI_CLOCK_MONOTONIC)
610 return clock_gettime(CLOCK_MONOTONIC, tp);
612 return (LIBUSB_ERROR_INVALID_PARAM);
616 _errno_to_libusb(int err)
618 usbi_dbg("error: %s (%d)", strerror(err), err);
622 return (LIBUSB_ERROR_IO);
624 return (LIBUSB_ERROR_ACCESS);
626 return (LIBUSB_ERROR_NO_DEVICE);
628 return (LIBUSB_ERROR_NO_MEM);
630 return (LIBUSB_ERROR_TIMEOUT);
633 return (LIBUSB_ERROR_OTHER);
637 _cache_active_config_descriptor(struct libusb_device *dev)
639 struct device_priv *dpriv = (struct device_priv *)dev->os_priv;
640 struct usb_device_cdesc udc;
641 struct usb_device_fdesc udf;
645 if ((fd = _bus_open(dev->bus_number)) < 0)
646 return _errno_to_libusb(errno);
648 usbi_dbg("fd %d, addr %d", fd, dev->device_address);
650 udc.udc_bus = dev->bus_number;
651 udc.udc_addr = dev->device_address;
652 udc.udc_config_index = USB_CURRENT_CONFIG_INDEX;
653 if (ioctl(fd, USB_DEVICE_GET_CDESC, &udc) < 0) {
656 return _errno_to_libusb(errno);
659 usbi_dbg("active bLength %d", udc.udc_desc.bLength);
661 len = UGETW(udc.udc_desc.wTotalLength);
664 return (LIBUSB_ERROR_NO_MEM);
666 udf.udf_bus = dev->bus_number;
667 udf.udf_addr = dev->device_address;
668 udf.udf_config_index = udc.udc_config_index;
672 usbi_dbg("index %d, len %d", udf.udf_config_index, len);
674 if (ioctl(fd, USB_DEVICE_GET_FDESC, &udf) < 0) {
678 return _errno_to_libusb(err);
686 return (LIBUSB_SUCCESS);
690 _sync_control_transfer(struct usbi_transfer *itransfer)
692 struct libusb_transfer *transfer;
693 struct libusb_control_setup *setup;
694 struct device_priv *dpriv;
695 struct usb_ctl_request req;
697 transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
698 dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv;
699 setup = (struct libusb_control_setup *)transfer->buffer;
701 usbi_dbg("type %x request %x value %x index %d length %d timeout %d",
702 setup->bmRequestType, setup->bRequest,
703 libusb_le16_to_cpu(setup->wValue),
704 libusb_le16_to_cpu(setup->wIndex),
705 libusb_le16_to_cpu(setup->wLength), transfer->timeout);
707 req.ucr_addr = transfer->dev_handle->dev->device_address;
708 req.ucr_request.bmRequestType = setup->bmRequestType;
709 req.ucr_request.bRequest = setup->bRequest;
710 /* Don't use USETW, libusb already deals with the endianness */
711 (*(uint16_t *)req.ucr_request.wValue) = setup->wValue;
712 (*(uint16_t *)req.ucr_request.wIndex) = setup->wIndex;
713 (*(uint16_t *)req.ucr_request.wLength) = setup->wLength;
714 req.ucr_data = transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE;
716 if ((transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) == 0)
717 req.ucr_flags = USBD_SHORT_XFER_OK;
719 if (dpriv->devname == NULL) {
721 * XXX If the device is not attached to ugen(4) it is
722 * XXX still possible to submit a control transfer but
723 * XXX with the default timeout only.
727 if ((fd = _bus_open(transfer->dev_handle->dev->bus_number)) < 0)
728 return _errno_to_libusb(errno);
730 if ((ioctl(fd, USB_REQUEST, &req)) < 0) {
733 return _errno_to_libusb(err);
737 if ((ioctl(dpriv->fd, USB_SET_TIMEOUT, &transfer->timeout)) < 0)
738 return _errno_to_libusb(errno);
740 if ((ioctl(dpriv->fd, USB_DO_REQUEST, &req)) < 0)
741 return _errno_to_libusb(errno);
744 itransfer->transferred = req.ucr_actlen;
746 usbi_dbg("transferred %d", itransfer->transferred);
752 _access_endpoint(struct libusb_transfer *transfer)
754 struct handle_priv *hpriv;
755 struct device_priv *dpriv;
760 hpriv = (struct handle_priv *)transfer->dev_handle->os_priv;
761 dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv;
763 endpt = UE_GET_ADDR(transfer->endpoint);
764 mode = IS_XFERIN(transfer) ? O_RDONLY : O_WRONLY;
766 usbi_dbg("endpoint %d mode %d", endpt, mode);
768 if (hpriv->endpoints[endpt] < 0) {
769 /* Pick the right endpoint node */
770 snprintf(devnode, sizeof(devnode), DEVPATH "%s.%02d",
771 dpriv->devname, endpt);
773 /* We may need to read/write to the same endpoint later. */
774 if (((fd = open(devnode, O_RDWR)) < 0) && (errno == ENXIO))
775 if ((fd = open(devnode, mode)) < 0)
778 hpriv->endpoints[endpt] = fd;
781 return (hpriv->endpoints[endpt]);
785 _sync_gen_transfer(struct usbi_transfer *itransfer)
787 struct libusb_transfer *transfer;
788 struct device_priv *dpriv;
791 transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
792 dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv;
794 if (dpriv->devname == NULL)
795 return (LIBUSB_ERROR_NOT_SUPPORTED);
798 * Bulk, Interrupt or Isochronous transfer depends on the
799 * endpoint and thus the node to open.
801 if ((fd = _access_endpoint(transfer)) < 0)
802 return _errno_to_libusb(errno);
804 if ((ioctl(fd, USB_SET_TIMEOUT, &transfer->timeout)) < 0)
805 return _errno_to_libusb(errno);
807 if (IS_XFERIN(transfer)) {
808 if ((transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) == 0)
809 if ((ioctl(fd, USB_SET_SHORT_XFER, &nr)) < 0)
810 return _errno_to_libusb(errno);
812 nr = read(fd, transfer->buffer, transfer->length);
814 nr = write(fd, transfer->buffer, transfer->length);
818 return _errno_to_libusb(errno);
820 itransfer->transferred = nr;
826 _bus_open(int number)
830 snprintf(busnode, sizeof(busnode), USBDEV "%d", number);
832 return open(busnode, O_RDWR);