blob: df467f0cc996dbbe8e5b73a8d67e192aa085fcdc [file] [log] [blame]
Paul Cercueile06f4ce2015-04-20 12:59:31 +02001/*
2 * libiio - Library for interfacing industrial I/O (IIO) devices
3 *
4 * Copyright (C) 2015 Analog Devices, Inc.
5 * Author: Paul Cercueil <paul.cercueil@analog.com>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * */
18
Paul Cercueile06f4ce2015-04-20 12:59:31 +020019#include "iio-lock.h"
20#include "iio-private.h"
21#include "iiod-client.h"
22
Paul Cercueil370bb362016-04-20 11:50:10 +020023#include <ctype.h>
Paul Cercueile06f4ce2015-04-20 12:59:31 +020024#include <errno.h>
25#include <libusb-1.0/libusb.h>
26#include <stdbool.h>
27#include <string.h>
28
Paul Cercueil3c1e7852015-12-04 16:14:28 +010029#ifdef ERROR
30#undef ERROR
31#endif
32
33#include "debug.h"
34
Paul Cercueile06f4ce2015-04-20 12:59:31 +020035#define DEFAULT_TIMEOUT_MS 5000
36
37/* Endpoint for non-streaming operations */
38#define EP_OPS 1
39
Lars-Peter Clausen794ba032016-04-25 15:07:00 +020040#define IIO_INTERFACE_NAME "IIO"
41
Paul Cercueil4213a432016-02-09 14:00:40 +010042struct iio_usb_io_endpoint {
43 unsigned char address;
44 bool in_use;
Paul Cercueil4acd6042015-11-30 12:10:43 +010045
Paul Cercueil4213a432016-02-09 14:00:40 +010046 struct iio_mutex *lock;
47};
Paul Cercueil4acd6042015-11-30 12:10:43 +010048
Paul Cercueile06f4ce2015-04-20 12:59:31 +020049struct iio_context_pdata {
50 libusb_context *ctx;
51 libusb_device_handle *hdl;
52
53 struct iiod_client *iiod_client;
54
55 /* Lock for non-streaming operations */
56 struct iio_mutex *lock;
Paul Cercueil4acd6042015-11-30 12:10:43 +010057
Paul Cercueil4213a432016-02-09 14:00:40 +010058 /* Lock for endpoint reservation */
59 struct iio_mutex *ep_lock;
60
61 struct iio_usb_io_endpoint *io_endpoints;
62 unsigned int nb_io_endpoints;
Paul Cercueil7a988892015-12-03 12:39:20 +010063
64 unsigned int timeout_ms;
Paul Cercueil4acd6042015-11-30 12:10:43 +010065};
66
67struct iio_device_pdata {
Paul Cercueil4acd6042015-11-30 12:10:43 +010068 struct iio_mutex *lock;
69
70 bool opened;
71 unsigned int ep;
Paul Cercueile06f4ce2015-04-20 12:59:31 +020072};
73
74static const unsigned int libusb_to_errno_codes[] = {
75 [- LIBUSB_ERROR_INVALID_PARAM] = EINVAL,
76 [- LIBUSB_ERROR_ACCESS] = EACCES,
77 [- LIBUSB_ERROR_NO_DEVICE] = ENODEV,
78 [- LIBUSB_ERROR_NOT_FOUND] = ENXIO,
79 [- LIBUSB_ERROR_BUSY] = EBUSY,
80 [- LIBUSB_ERROR_TIMEOUT] = ETIMEDOUT,
81 [- LIBUSB_ERROR_OVERFLOW] = EIO,
82 [- LIBUSB_ERROR_PIPE] = EPIPE,
83 [- LIBUSB_ERROR_INTERRUPTED] = EINTR,
84 [- LIBUSB_ERROR_NO_MEM] = ENOMEM,
85 [- LIBUSB_ERROR_NOT_SUPPORTED] = ENOSYS,
86};
87
88static unsigned int libusb_to_errno(int error)
89{
90 switch ((enum libusb_error) error) {
91 case LIBUSB_ERROR_INVALID_PARAM:
92 case LIBUSB_ERROR_ACCESS:
93 case LIBUSB_ERROR_NO_DEVICE:
94 case LIBUSB_ERROR_NOT_FOUND:
95 case LIBUSB_ERROR_BUSY:
96 case LIBUSB_ERROR_TIMEOUT:
97 case LIBUSB_ERROR_PIPE:
98 case LIBUSB_ERROR_INTERRUPTED:
99 case LIBUSB_ERROR_NO_MEM:
100 case LIBUSB_ERROR_NOT_SUPPORTED:
101 return libusb_to_errno_codes[- (int) error];
102 case LIBUSB_ERROR_IO:
103 case LIBUSB_ERROR_OTHER:
104 case LIBUSB_ERROR_OVERFLOW:
105 default:
106 return EIO;
107 }
108}
109
Paul Cercueilc11737c2015-11-26 14:44:46 +0100110static int usb_get_version(const struct iio_context *ctx,
111 unsigned int *major, unsigned int *minor, char git_tag[8])
112{
113 return iiod_client_get_version(ctx->pdata->iiod_client,
114 EP_OPS, major, minor, git_tag);
115}
116
Paul Cercueila5e4aa42016-02-09 13:31:01 +0100117static unsigned int usb_calculate_remote_timeout(unsigned int timeout)
118{
119 /* XXX(pcercuei): We currently hardcode timeout / 2 for the backend used
120 * by the remote. Is there something better to do here? */
121 return timeout / 2;
122}
123
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100124#define USB_PIPE_CTRL_TIMEOUT 200 /* These should not take long */
125
126#define IIO_USD_CMD_RESET_PIPES 0
127#define IIO_USD_CMD_OPEN_PIPE 1
128#define IIO_USD_CMD_CLOSE_PIPE 2
129
130static int usb_reset_pipes(libusb_device_handle *hdl)
131{
132 int ret;
133
134 ret = libusb_control_transfer(hdl, LIBUSB_REQUEST_TYPE_VENDOR |
135 LIBUSB_RECIPIENT_INTERFACE, IIO_USD_CMD_RESET_PIPES,
136 0, 0, NULL, 0, USB_PIPE_CTRL_TIMEOUT);
137 if (ret < 0)
Paul Cercueil67482202016-04-21 16:40:02 +0200138 return -(int) libusb_to_errno(ret);
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100139 return 0;
140}
141
142static int usb_open_pipe(libusb_device_handle *hdl, unsigned int ep)
143{
144 int ret;
145
146 ret = libusb_control_transfer(hdl, LIBUSB_REQUEST_TYPE_VENDOR |
147 LIBUSB_RECIPIENT_INTERFACE, IIO_USD_CMD_OPEN_PIPE,
148 ep - 1, 0, NULL, 0, USB_PIPE_CTRL_TIMEOUT);
149 if (ret < 0)
Paul Cercueil67482202016-04-21 16:40:02 +0200150 return -(int) libusb_to_errno(ret);
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100151 return 0;
152}
153
154static int usb_close_pipe(libusb_device_handle *hdl, unsigned int ep)
155{
156 int ret;
157
158 ret = libusb_control_transfer(hdl, LIBUSB_REQUEST_TYPE_VENDOR |
159 LIBUSB_RECIPIENT_INTERFACE, IIO_USD_CMD_CLOSE_PIPE,
160 ep - 1, 0, NULL, 0, USB_PIPE_CTRL_TIMEOUT);
161 if (ret < 0)
Paul Cercueil67482202016-04-21 16:40:02 +0200162 return -(int) libusb_to_errno(ret);
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100163 return 0;
164}
165
Paul Cercueil4213a432016-02-09 14:00:40 +0100166static int usb_reserve_ep_unlocked(const struct iio_device *dev)
167{
168 struct iio_context_pdata *pdata = dev->ctx->pdata;
169 unsigned int i;
170
171 for (i = 0; i < pdata->nb_io_endpoints; i++) {
172 struct iio_usb_io_endpoint *ep = &pdata->io_endpoints[i];
173
174 if (!ep->in_use) {
175 ep->in_use = true;
176
177 dev->pdata->ep = ep->address;
178 dev->pdata->lock = ep->lock;
179 return 0;
180 }
181 }
182
183 return -EBUSY;
184}
185
186static void usb_free_ep_unlocked(const struct iio_device *dev)
187{
188 struct iio_context_pdata *pdata = dev->ctx->pdata;
189 unsigned int i;
190
191 for (i = 0; i < pdata->nb_io_endpoints; i++) {
192 struct iio_usb_io_endpoint *ep = &pdata->io_endpoints[i];
193
194 if (ep->lock == dev->pdata->lock) {
195 ep->in_use = false;
196 return;
197 }
198 }
199}
200
Paul Cercueil4acd6042015-11-30 12:10:43 +0100201static int usb_open(const struct iio_device *dev,
202 size_t samples_count, bool cyclic)
203{
Paul Cercueila5e4aa42016-02-09 13:31:01 +0100204 struct iio_context_pdata *ctx_pdata = dev->ctx->pdata;
Paul Cercueil4acd6042015-11-30 12:10:43 +0100205 struct iio_device_pdata *pdata = dev->pdata;
206 int ret = -EBUSY;
207
Paul Cercueil4213a432016-02-09 14:00:40 +0100208 iio_mutex_lock(ctx_pdata->ep_lock);
Paul Cercueil4acd6042015-11-30 12:10:43 +0100209
Paul Cercueila5e4aa42016-02-09 13:31:01 +0100210 if (pdata->opened)
211 goto out_unlock;
212
Paul Cercueil4213a432016-02-09 14:00:40 +0100213 ret = usb_reserve_ep_unlocked(dev);
214 if (ret)
215 goto out_unlock;
216
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100217 ret = usb_open_pipe(ctx_pdata->hdl, pdata->ep);
218 if (ret) {
219 char err_str[1024];
220
221 iio_strerror(-ret, err_str, sizeof(err_str));
222 ERROR("Failed to open pipe: %s\n", err_str);
223 usb_free_ep_unlocked(dev);
224 goto out_unlock;
225 }
226
Paul Cercueil4213a432016-02-09 14:00:40 +0100227 iio_mutex_lock(pdata->lock);
228
Paul Cercueila5e4aa42016-02-09 13:31:01 +0100229 ret = iiod_client_open_unlocked(ctx_pdata->iiod_client,
230 pdata->ep, dev, samples_count, cyclic);
231
232 if (!ret) {
233 unsigned int remote_timeout =
234 usb_calculate_remote_timeout(ctx_pdata->timeout_ms);
235
236 ret = iiod_client_set_timeout(ctx_pdata->iiod_client,
237 pdata->ep, remote_timeout);
Paul Cercueil4acd6042015-11-30 12:10:43 +0100238 }
239
Paul Cercueila5e4aa42016-02-09 13:31:01 +0100240 pdata->opened = !ret;
241
Paul Cercueil4acd6042015-11-30 12:10:43 +0100242 iio_mutex_unlock(pdata->lock);
Paul Cercueil4213a432016-02-09 14:00:40 +0100243
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100244 if (ret) {
245 usb_close_pipe(ctx_pdata->hdl, pdata->ep);
Paul Cercueil4213a432016-02-09 14:00:40 +0100246 usb_free_ep_unlocked(dev);
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100247 }
Paul Cercueil4213a432016-02-09 14:00:40 +0100248
249out_unlock:
250 iio_mutex_unlock(ctx_pdata->ep_lock);
Paul Cercueil4acd6042015-11-30 12:10:43 +0100251 return ret;
252}
253
254static int usb_close(const struct iio_device *dev)
255{
Paul Cercueil4213a432016-02-09 14:00:40 +0100256 struct iio_context_pdata *ctx_pdata = dev->ctx->pdata;
Paul Cercueil4acd6042015-11-30 12:10:43 +0100257 struct iio_device_pdata *pdata = dev->pdata;
258 int ret = -EBADF;
259
Paul Cercueil4213a432016-02-09 14:00:40 +0100260 iio_mutex_lock(ctx_pdata->ep_lock);
261 if (!pdata->opened)
262 goto out_unlock;
Paul Cercueil4acd6042015-11-30 12:10:43 +0100263
Paul Cercueil4213a432016-02-09 14:00:40 +0100264 iio_mutex_lock(pdata->lock);
265 ret = iiod_client_close_unlocked(ctx_pdata->iiod_client,
266 pdata->ep, dev);
267 pdata->opened = false;
268
Paul Cercueil31492b32016-02-22 17:40:20 +0100269 iio_mutex_unlock(pdata->lock);
270
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100271 usb_close_pipe(ctx_pdata->hdl, pdata->ep);
272
Paul Cercueil4213a432016-02-09 14:00:40 +0100273 usb_free_ep_unlocked(dev);
274
275out_unlock:
276 iio_mutex_unlock(ctx_pdata->ep_lock);
Paul Cercueil4acd6042015-11-30 12:10:43 +0100277 return ret;
278}
279
Paul Cercueil04841832015-12-02 11:58:33 +0100280static ssize_t usb_read(const struct iio_device *dev, void *dst, size_t len,
281 uint32_t *mask, size_t words)
282{
283 struct iio_device_pdata *pdata = dev->pdata;
284 ssize_t ret;
285
286 iio_mutex_lock(pdata->lock);
287 ret = iiod_client_read_unlocked(dev->ctx->pdata->iiod_client,
288 pdata->ep, dev, dst, len, mask, words);
289 iio_mutex_unlock(pdata->lock);
290
291 return ret;
292}
293
Paul Cercueile78e9882015-12-04 16:31:10 +0100294static ssize_t usb_write(const struct iio_device *dev,
295 const void *src, size_t len)
296{
297 struct iio_device_pdata *pdata = dev->pdata;
298 ssize_t ret;
299
300 iio_mutex_lock(pdata->lock);
301 ret = iiod_client_write_unlocked(dev->ctx->pdata->iiod_client,
302 pdata->ep, dev, src, len);
303 iio_mutex_unlock(pdata->lock);
304
305 return ret;
306}
307
Paul Cercueil3069e3b2015-11-26 16:01:25 +0100308static ssize_t usb_read_dev_attr(const struct iio_device *dev,
309 const char *attr, char *dst, size_t len, bool is_debug)
310{
311 struct iio_context_pdata *pdata = dev->ctx->pdata;
312
313 return iiod_client_read_attr(pdata->iiod_client, EP_OPS, dev,
314 NULL, attr, dst, len, is_debug);
315}
316
317static ssize_t usb_write_dev_attr(const struct iio_device *dev,
318 const char *attr, const char *src, size_t len, bool is_debug)
319{
320 struct iio_context_pdata *pdata = dev->ctx->pdata;
321
322 return iiod_client_write_attr(pdata->iiod_client, EP_OPS, dev,
323 NULL, attr, src, len, is_debug);
324}
325
326static ssize_t usb_read_chn_attr(const struct iio_channel *chn,
327 const char *attr, char *dst, size_t len)
328{
329 struct iio_context_pdata *pdata = chn->dev->ctx->pdata;
330
331 return iiod_client_read_attr(pdata->iiod_client, EP_OPS, chn->dev,
332 chn, attr, dst, len, false);
333}
334
335static ssize_t usb_write_chn_attr(const struct iio_channel *chn,
336 const char *attr, const char *src, size_t len)
337{
338 struct iio_context_pdata *pdata = chn->dev->ctx->pdata;
339
340 return iiod_client_write_attr(pdata->iiod_client, EP_OPS, chn->dev,
341 chn, attr, src, len, false);
342}
343
Paul Cercueil6c8337e2015-11-27 11:13:09 +0100344static int usb_set_kernel_buffers_count(const struct iio_device *dev,
345 unsigned int nb_blocks)
346{
347 struct iio_context_pdata *pdata = dev->ctx->pdata;
348
349 return iiod_client_set_kernel_buffers_count(pdata->iiod_client,
350 EP_OPS, dev, nb_blocks);
351}
352
Paul Cercueil7a988892015-12-03 12:39:20 +0100353static int usb_set_timeout(struct iio_context *ctx, unsigned int timeout)
354{
355 struct iio_context_pdata *pdata = ctx->pdata;
356 unsigned int remote_timeout = usb_calculate_remote_timeout(timeout);
357 int ret;
358
359 ret = iiod_client_set_timeout(pdata->iiod_client,
360 EP_OPS, remote_timeout);
Paul Cercueila5e4aa42016-02-09 13:31:01 +0100361 if (!ret)
362 pdata->timeout_ms = timeout;
Paul Cercueil7a988892015-12-03 12:39:20 +0100363
Paul Cercueil7a988892015-12-03 12:39:20 +0100364 return ret;
365}
366
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200367static void usb_shutdown(struct iio_context *ctx)
368{
Paul Cercueil4213a432016-02-09 14:00:40 +0100369 unsigned int i;
370
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200371 iio_mutex_destroy(ctx->pdata->lock);
Paul Cercueil4213a432016-02-09 14:00:40 +0100372 iio_mutex_destroy(ctx->pdata->ep_lock);
373
374 for (i = 0; i < ctx->pdata->nb_io_endpoints; i++)
375 if (ctx->pdata->io_endpoints[i].lock)
376 iio_mutex_destroy(ctx->pdata->io_endpoints[i].lock);
377 if (ctx->pdata->io_endpoints)
378 free(ctx->pdata->io_endpoints);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200379
Lars-Peter Clausen33c64312016-02-19 13:32:08 +0100380 for (i = 0; i < ctx->nb_devices; i++) {
381 struct iio_device *dev = ctx->devices[i];
382
383 free(dev->pdata);
384 }
385
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200386 iiod_client_destroy(ctx->pdata->iiod_client);
387
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100388 usb_reset_pipes(ctx->pdata->hdl); /* Close everything */
389
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200390 libusb_close(ctx->pdata->hdl);
391 libusb_exit(ctx->pdata->ctx);
Lars-Peter Clausen33c64312016-02-19 13:32:08 +0100392 free(ctx->pdata);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200393}
394
Lars-Peter Clausen794ba032016-04-25 15:07:00 +0200395static int iio_usb_match_interface(const struct libusb_config_descriptor *desc,
396 struct libusb_device_handle *hdl, unsigned int interface)
397{
398 const struct libusb_interface *iface;
399 unsigned int i;
400
401 if (interface >= desc->bNumInterfaces)
402 return -EINVAL;
403
404 iface = &desc->interface[interface];
405
406 for (i = 0; i < (unsigned int) iface->num_altsetting; i++) {
407 const struct libusb_interface_descriptor *idesc =
408 &iface->altsetting[i];
409 char name[64];
410 int ret;
411
412 if (idesc->iInterface == 0)
413 continue;
414
415 ret = libusb_get_string_descriptor_ascii(hdl, idesc->iInterface,
416 (unsigned char *) name, sizeof(name));
417 if (ret < 0)
418 return ret;
419
420 if (!strcmp(name, IIO_INTERFACE_NAME))
421 return (int) i;
422 }
423
424 return -EPERM;
425}
426
427static int iio_usb_match_device(struct libusb_device *dev,
428 struct libusb_device_handle *hdl,
429 unsigned int *interface)
430{
431 struct libusb_config_descriptor *desc;
432 unsigned int i;
433 int ret;
434
435 ret = libusb_get_active_config_descriptor(dev, &desc);
436 if (ret)
437 return -(int) libusb_to_errno(ret);
438
439 for (i = 0, ret = -EPERM; ret == -EPERM &&
440 i < desc->bNumInterfaces; i++)
441 ret = iio_usb_match_interface(desc, hdl, i);
442
443 libusb_free_config_descriptor(desc);
444 if (ret < 0)
445 return ret;
446
447 DEBUG("Found IIO interface on device %u:%u using interface %u\n",
448 libusb_get_bus_number(dev),
449 libusb_get_device_address(dev), i - 1);
450
451 *interface = i - 1;
452 return ret;
453}
454
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200455static const struct iio_backend_ops usb_ops = {
Paul Cercueilc11737c2015-11-26 14:44:46 +0100456 .get_version = usb_get_version,
Paul Cercueil4acd6042015-11-30 12:10:43 +0100457 .open = usb_open,
458 .close = usb_close,
Paul Cercueil04841832015-12-02 11:58:33 +0100459 .read = usb_read,
Paul Cercueile78e9882015-12-04 16:31:10 +0100460 .write = usb_write,
Paul Cercueil3069e3b2015-11-26 16:01:25 +0100461 .read_device_attr = usb_read_dev_attr,
462 .read_channel_attr = usb_read_chn_attr,
463 .write_device_attr = usb_write_dev_attr,
464 .write_channel_attr = usb_write_chn_attr,
Paul Cercueil6c8337e2015-11-27 11:13:09 +0100465 .set_kernel_buffers_count = usb_set_kernel_buffers_count,
Paul Cercueil7a988892015-12-03 12:39:20 +0100466 .set_timeout = usb_set_timeout,
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200467 .shutdown = usb_shutdown,
468};
469
470static ssize_t write_data_sync(struct iio_context_pdata *pdata,
471 int ep, const char *data, size_t len)
472{
473 int transferred, ret;
474
475 ret = libusb_bulk_transfer(pdata->hdl, ep | LIBUSB_ENDPOINT_OUT,
Lars-Peter Clausen8ba0d5b2016-02-17 11:30:23 +0100476 (unsigned char *) data, (int) len,
Paul Cercueile10d19a2016-02-09 13:30:12 +0100477 &transferred, pdata->timeout_ms);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200478 if (ret)
Paul Cercueil463fc782015-12-04 16:04:12 +0100479 return -(int) libusb_to_errno(ret);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200480 else
Lars-Peter Clausen8ba0d5b2016-02-17 11:30:23 +0100481 return (size_t) transferred != len ? -EIO : (ssize_t) len;
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200482}
483
484static ssize_t read_data_sync(struct iio_context_pdata *pdata,
485 int ep, char *buf, size_t len)
486{
487 int transferred, ret;
488
489 ret = libusb_bulk_transfer(pdata->hdl, ep | LIBUSB_ENDPOINT_IN,
Lars-Peter Clausen8ba0d5b2016-02-17 11:30:23 +0100490 (unsigned char *) buf, (int) len, &transferred, pdata->timeout_ms);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200491 if (ret)
Paul Cercueil463fc782015-12-04 16:04:12 +0100492 return -(int) libusb_to_errno(ret);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200493 else
494 return transferred;
495}
496
Lars-Peter Clausen09a59d72016-02-03 15:27:04 +0100497static const struct iiod_client_ops usb_iiod_client_ops = {
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200498 .write = write_data_sync,
499 .read = read_data_sync,
500 .read_line = read_data_sync,
501};
502
Paul Cercueil4213a432016-02-09 14:00:40 +0100503static int usb_count_io_eps(const struct libusb_interface_descriptor *iface)
504{
505 unsigned int eps = iface->bNumEndpoints;
506 unsigned int i, curr;
507
508 /* Check that for a number of endpoints X provided by the interface, we
509 * have the input and output endpoints in the address range [1, ... X/2]
510 * and that each input endpoint has a corresponding output endpoint at
511 * the same address. */
512
513 if (eps < 2 || eps % 2)
514 return -EINVAL;
515
516 for (curr = 1; curr < (eps / 2) + 1; curr++) {
517 bool found_in = false, found_out = false;
518
519 for (i = 0; !found_in && i < eps; i++)
520 found_in = iface->endpoint[i].bEndpointAddress ==
Paul Cercueil6733c4e2016-02-12 15:09:35 +0100521 (LIBUSB_ENDPOINT_IN | curr);
Paul Cercueil4213a432016-02-09 14:00:40 +0100522 if (!found_in)
523 return -EINVAL;
524
525 for (i = 0; !found_out && i < eps; i++)
526 found_out = iface->endpoint[i].bEndpointAddress ==
Paul Cercueil6733c4e2016-02-12 15:09:35 +0100527 (LIBUSB_ENDPOINT_OUT | curr);
Paul Cercueil4213a432016-02-09 14:00:40 +0100528 if (!found_out)
529 return -EINVAL;
530 }
531
532 /* -1: we reserve the first I/O endpoint couple for global operations */
533 return (int) curr - 1;
534}
535
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100536struct iio_context * usb_create_context(unsigned int bus,
537 unsigned int address, unsigned int interface)
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200538{
539 libusb_context *usb_ctx;
540 libusb_device_handle *hdl;
Paul Cercueil4213a432016-02-09 14:00:40 +0100541 const struct libusb_interface_descriptor *iface;
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100542 libusb_device *dev, *usb_dev;
Paul Cercueil4213a432016-02-09 14:00:40 +0100543 struct libusb_config_descriptor *conf_desc;
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100544 libusb_device **device_list;
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200545 struct iio_context *ctx;
546 struct iio_context_pdata *pdata;
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100547 char err_str[1024];
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200548 unsigned int i;
549 int ret;
550
Lars-Peter Clausend1be8382016-02-24 11:13:45 +0100551 pdata = zalloc(sizeof(*pdata));
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200552 if (!pdata) {
553 ERROR("Unable to allocate pdata\n");
554 ret = -ENOMEM;
555 goto err_set_errno;
556 }
557
558 pdata->lock = iio_mutex_create();
559 if (!pdata->lock) {
560 ERROR("Unable to create mutex\n");
561 ret = -ENOMEM;
562 goto err_free_pdata;
563 }
564
Paul Cercueil4213a432016-02-09 14:00:40 +0100565 pdata->ep_lock = iio_mutex_create();
566 if (!pdata->ep_lock) {
Paul Cercueil4acd6042015-11-30 12:10:43 +0100567 ERROR("Unable to create mutex\n");
568 ret = -ENOMEM;
569 goto err_destroy_mutex;
570 }
571
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200572 pdata->iiod_client = iiod_client_new(pdata, pdata->lock,
573 &usb_iiod_client_ops);
574 if (!pdata->iiod_client) {
575 ERROR("Unable to create IIOD client\n");
576 ret = -errno;
Paul Cercueil4213a432016-02-09 14:00:40 +0100577 goto err_destroy_ep_mutex;
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200578 }
579
580 ret = libusb_init(&usb_ctx);
581 if (ret) {
Paul Cercueil463fc782015-12-04 16:04:12 +0100582 ret = -(int) libusb_to_errno(ret);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200583 ERROR("Unable to init libusb: %i\n", ret);
Paul Cercueil4acd6042015-11-30 12:10:43 +0100584 goto err_destroy_iiod_client;
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200585 }
586
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100587 libusb_get_device_list(usb_ctx, &device_list);
588
589 usb_dev = NULL;
590
591 for (i = 0; device_list[i]; i++) {
592 dev = device_list[i];
593
594 if (bus == libusb_get_bus_number(dev) &&
595 address == libusb_get_device_address(dev)) {
596 usb_dev = dev;
597 libusb_ref_device(usb_dev);
598 break;
599 }
600 }
601
602 libusb_free_device_list(device_list, true);
603
604 if (!usb_dev)
605 goto err_libusb_exit;
606
607 ret = libusb_open(usb_dev, &hdl);
608 libusb_unref_device(usb_dev); /* Open gets us a extra ref */
609 if (ret) {
610 ret = -(int) libusb_to_errno(ret);
611 ERROR("Unable to open device\n");
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200612 goto err_libusb_exit;
613 }
614
615 libusb_set_auto_detach_kernel_driver(hdl, true);
616
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100617 ret = libusb_claim_interface(hdl, interface);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200618 if (ret) {
Paul Cercueil463fc782015-12-04 16:04:12 +0100619 ret = -(int) libusb_to_errno(ret);
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100620 ERROR("Unable to claim interface %u: %i\n", interface, ret);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200621 goto err_libusb_close;
622 }
623
Paul Cercueil4213a432016-02-09 14:00:40 +0100624 ret = libusb_get_active_config_descriptor(usb_dev, &conf_desc);
625 if (ret) {
626 ret = -(int) libusb_to_errno(ret);
627 ERROR("Unable to get config descriptor: %i\n", ret);
628 goto err_libusb_close;
629 }
630
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100631 iface = &conf_desc->interface[interface].altsetting[0];
Paul Cercueil4213a432016-02-09 14:00:40 +0100632
633 ret = usb_count_io_eps(iface);
634 if (ret < 0) {
635 ERROR("Invalid configuration of endpoints\n");
636 goto err_free_config_descriptor;
637 }
638
639 pdata->nb_io_endpoints = ret;
640
641 DEBUG("Found %hhu usable i/o endpoints\n", pdata->nb_io_endpoints);
642
643 if (pdata->nb_io_endpoints) {
644 pdata->io_endpoints = calloc(pdata->nb_io_endpoints,
645 sizeof(*pdata->io_endpoints));
646 if (!pdata->io_endpoints) {
647 ERROR("Unable to allocate endpoints\n");
648 ret = -ENOMEM;
649 goto err_free_config_descriptor;
650 }
651
652 for (i = 0; i < pdata->nb_io_endpoints; i++) {
653 struct iio_usb_io_endpoint *ep =
654 &pdata->io_endpoints[i];
655
656 /* +2: endpoints start at number 1, and we skip the
657 * endpoint #1 that we reserve for global operations */
658 ep->address = i + 2;
659
660 ep->lock = iio_mutex_create();
661 if (!ep->lock) {
662 ERROR("Unable to create mutex\n");
663 ret = -ENOMEM;
664 goto err_free_endpoints;
665 }
666 }
667 }
668
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200669 pdata->ctx = usb_ctx;
670 pdata->hdl = hdl;
Paul Cercueil7a988892015-12-03 12:39:20 +0100671 pdata->timeout_ms = DEFAULT_TIMEOUT_MS;
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200672
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100673 ret = usb_reset_pipes(hdl);
674 if (ret) {
675 iio_strerror(-ret, err_str, sizeof(err_str));
676 ERROR("Failed to reset pipes: %s\n", err_str);
677 return NULL;
678 }
679
680 ret = usb_open_pipe(hdl, EP_OPS);
681 if (ret) {
682 iio_strerror(-ret, err_str, sizeof(err_str));
683 ERROR("Failed to open control pipe: %s\n", err_str);
684 return NULL;
685 }
686
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200687 ctx = iiod_client_create_context(pdata->iiod_client, EP_OPS);
688 if (!ctx)
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100689 goto err_reset_pipes;
Paul Cercueil4213a432016-02-09 14:00:40 +0100690
691 libusb_free_config_descriptor(conf_desc);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200692
693 ctx->name = "usb";
694 ctx->ops = &usb_ops;
695 ctx->pdata = pdata;
696
Paul Cercueil4acd6042015-11-30 12:10:43 +0100697 for (i = 0; i < ctx->nb_devices; i++) {
698 struct iio_device *dev = ctx->devices[i];
699
Lars-Peter Clausend1be8382016-02-24 11:13:45 +0100700 dev->pdata = zalloc(sizeof(*dev->pdata));
Paul Cercueil4acd6042015-11-30 12:10:43 +0100701 if (!dev->pdata) {
702 ERROR("Unable to allocate memory\n");
703 ret = -ENOMEM;
704 goto err_context_destroy;
705 }
Paul Cercueil4acd6042015-11-30 12:10:43 +0100706 }
707
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200708 return ctx;
709
710err_context_destroy:
711 iio_context_destroy(ctx);
712 errno = -ret;
713 return NULL;
714
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100715err_reset_pipes:
716 usb_reset_pipes(hdl); /* Close everything */
Paul Cercueil4213a432016-02-09 14:00:40 +0100717err_free_endpoints:
718 for (i = 0; i < pdata->nb_io_endpoints; i++)
719 if (pdata->io_endpoints[i].lock)
720 iio_mutex_destroy(pdata->io_endpoints[i].lock);
721 if (pdata->io_endpoints)
722 free(pdata->io_endpoints);
723err_free_config_descriptor:
724 libusb_free_config_descriptor(conf_desc);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200725err_libusb_close:
726 libusb_close(hdl);
727err_libusb_exit:
728 libusb_exit(usb_ctx);
729err_destroy_iiod_client:
730 iiod_client_destroy(pdata->iiod_client);
Paul Cercueil4213a432016-02-09 14:00:40 +0100731err_destroy_ep_mutex:
732 iio_mutex_destroy(pdata->ep_lock);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200733err_destroy_mutex:
734 iio_mutex_destroy(pdata->lock);
735err_free_pdata:
736 free(pdata);
737err_set_errno:
738 errno = -ret;
739 return NULL;
740}
Lars-Peter Clausen60f1c9a2016-02-22 13:20:40 +0100741
742struct iio_context * usb_create_context_from_uri(const char *uri)
743{
Paul Cercueil370bb362016-04-20 11:50:10 +0200744 long bus, address, interface;
745 char *end;
746 const char *ptr;
Lars-Peter Clausen60f1c9a2016-02-22 13:20:40 +0100747
748 if (strncmp(uri, "usb:", sizeof("usb:") - 1) != 0)
Paul Cercueil370bb362016-04-20 11:50:10 +0200749 goto err_bad_uri;
Lars-Peter Clausen60f1c9a2016-02-22 13:20:40 +0100750
Paul Cercueil370bb362016-04-20 11:50:10 +0200751 ptr = (const char *) ((uintptr_t) uri + sizeof("usb:") - 1);
752 if (!isdigit(*ptr))
753 goto err_bad_uri;
Lars-Peter Clausen60f1c9a2016-02-22 13:20:40 +0100754
Paul Cercueil370bb362016-04-20 11:50:10 +0200755 bus = strtol(ptr, &end, 10);
756 if (ptr == end || *end != '.')
757 goto err_bad_uri;
758
759 ptr = (const char *) ((uintptr_t) end + 1);
760 if (!isdigit(*ptr))
761 goto err_bad_uri;
762
763 address = strtol(ptr, &end, 10);
Paul Cercueild24f8ac2016-04-20 14:19:29 +0200764 if (ptr == end)
Paul Cercueil370bb362016-04-20 11:50:10 +0200765 goto err_bad_uri;
766
Paul Cercueild24f8ac2016-04-20 14:19:29 +0200767 if (*end == '\0') {
768 interface = 0;
769 } else if (*end == '.') {
770 ptr = (const char *) ((uintptr_t) end + 1);
771 if (!isdigit(*ptr))
772 goto err_bad_uri;
Paul Cercueil370bb362016-04-20 11:50:10 +0200773
Paul Cercueild24f8ac2016-04-20 14:19:29 +0200774 interface = strtol(ptr, &end, 10);
775 if (ptr == end || *end != '\0')
776 goto err_bad_uri;
777 } else {
Paul Cercueil370bb362016-04-20 11:50:10 +0200778 goto err_bad_uri;
Paul Cercueild24f8ac2016-04-20 14:19:29 +0200779 }
Paul Cercueil370bb362016-04-20 11:50:10 +0200780
781 if (bus < 0 || address < 0 || interface < 0)
782 goto err_bad_uri;
783
784 return usb_create_context((unsigned int) bus,
785 (unsigned int) address, (unsigned int) interface);
786
787err_bad_uri:
788 ERROR("Bad URI: \'%s\'\n", uri);
789 errno = -EINVAL;
790 return NULL;
Lars-Peter Clausen60f1c9a2016-02-22 13:20:40 +0100791}
Lars-Peter Clausen794ba032016-04-25 15:07:00 +0200792
793static int usb_fill_context_info(struct iio_context_info *info,
794 struct libusb_device *dev, struct libusb_device_handle *hdl,
795 unsigned int interface)
796{
797 struct libusb_device_descriptor desc;
798 char manufacturer[64], product[64];
799 char uri[sizeof("usb:127.255.255")];
800 char description[sizeof(manufacturer) + sizeof(product) +
801 sizeof("0000:0000 ( )")];
802 int ret;
803
804 libusb_get_device_descriptor(dev, &desc);
805
806 snprintf(uri, sizeof(uri), "usb:%d.%d.%u",
807 libusb_get_bus_number(dev), libusb_get_device_address(dev),
808 interface);
809
810 if (desc.iManufacturer == 0) {
811 manufacturer[0] = '\0';
812 } else {
813 ret = libusb_get_string_descriptor_ascii(hdl,
814 desc.iManufacturer,
815 (unsigned char *) manufacturer,
816 sizeof(manufacturer));
817 if (ret < 0)
818 manufacturer[0] = '\0';
819 }
820
821 if (desc.iProduct == 0) {
822 product[0] = '\0';
823 } else {
824 ret = libusb_get_string_descriptor_ascii(hdl,
825 desc.iProduct, (unsigned char *) product,
826 sizeof(product));
827 if (ret < 0)
828 product[0] = '\0';
829 }
830
831 snprintf(description, sizeof(description),
832 "%04x:%04x (%s %s)", desc.idVendor,
833 desc.idProduct, manufacturer, product);
834
835 info->uri = _strdup(uri);
836 if (!info->uri)
837 return -ENOMEM;
838
839 info->description = _strdup(description);
840 if (!info->description)
841 return -ENOMEM;
842
843 return 0;
844}
845
846struct iio_scan_backend_context {
847 libusb_context *ctx;
848};
849
850struct iio_scan_backend_context * usb_context_scan_init(void)
851{
852 struct iio_scan_backend_context *ctx;
853 int ret;
854
855 ctx = malloc(sizeof(*ctx));
856 if (!ctx) {
857 errno = ENOMEM;
858 return NULL;
859 }
860
861 ret = libusb_init(&ctx->ctx);
862 if (ret) {
863 free(ctx);
864 errno = (int) libusb_to_errno(ret);
865 return NULL;
866 }
867
868 return ctx;
869}
870
871void usb_context_scan_free(struct iio_scan_backend_context *ctx)
872{
873 libusb_exit(ctx->ctx);
874 free(ctx);
875}
876
877int usb_context_scan(struct iio_scan_backend_context *ctx,
878 struct iio_scan_result *scan_result)
879{
880 struct iio_context_info **info;
881 libusb_device **device_list;
882 unsigned int i;
883 int ret;
884
885 ret = libusb_get_device_list(ctx->ctx, &device_list);
886 if (ret < 0)
887 return -(int) libusb_to_errno(ret);
888
889 for (i = 0; device_list[i]; i++) {
890 struct libusb_device_handle *hdl;
891 struct libusb_device *dev = device_list[i];
892 unsigned int interface = 0;
893
894 ret = libusb_open(dev, &hdl);
895 if (ret)
896 continue;
897
898 if (!iio_usb_match_device(dev, hdl, &interface)) {
899 info = iio_scan_result_add(scan_result, 1);
900 if (!info)
901 ret = -ENOMEM;
902 else
903 ret = usb_fill_context_info(*info, dev, hdl,
904 interface);
905 }
906
907 libusb_close(hdl);
908 if (ret < 0)
909 goto cleanup_free_device_list;
910 }
911
912 ret = 0;
913
914cleanup_free_device_list:
915 libusb_free_device_list(device_list, true);
916 return ret;
917}