blob: 2a48744b57fb5639f6c41eb008455fc7097a6bc0 [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 Cercueilbb10bd42016-10-31 15:31:36 +010042struct iio_usb_ep_couple {
43 unsigned char addr_in, addr_out;
44 unsigned int pipe_id;
45 bool in_use;
46
47 struct iio_mutex *lock;
48};
49
Lars-Peter Clausenf0d8ff42016-07-04 10:41:53 +020050struct iio_usb_io_context {
Paul Cercueilbb10bd42016-10-31 15:31:36 +010051 struct iio_usb_ep_couple *ep;
Lars-Peter Clausene5c04e02016-06-22 16:52:36 +020052
53 struct iio_mutex *lock;
54 bool cancelled;
55 struct libusb_transfer *transfer;
Lars-Peter Clausenf0d8ff42016-07-04 10:41:53 +020056};
57
Paul Cercueile06f4ce2015-04-20 12:59:31 +020058struct iio_context_pdata {
59 libusb_context *ctx;
60 libusb_device_handle *hdl;
Paul Cercueilbb10bd42016-10-31 15:31:36 +010061 unsigned int interface;
Paul Cercueile06f4ce2015-04-20 12:59:31 +020062
63 struct iiod_client *iiod_client;
64
65 /* Lock for non-streaming operations */
66 struct iio_mutex *lock;
Paul Cercueil4acd6042015-11-30 12:10:43 +010067
Paul Cercueil4213a432016-02-09 14:00:40 +010068 /* Lock for endpoint reservation */
69 struct iio_mutex *ep_lock;
70
Paul Cercueilbb10bd42016-10-31 15:31:36 +010071 struct iio_usb_ep_couple *io_endpoints;
72 unsigned int nb_ep_couples;
Paul Cercueil7a988892015-12-03 12:39:20 +010073
74 unsigned int timeout_ms;
Lars-Peter Clausenf0d8ff42016-07-04 10:41:53 +020075
76 struct iio_usb_io_context io_ctx;
Paul Cercueil4acd6042015-11-30 12:10:43 +010077};
78
79struct iio_device_pdata {
Paul Cercueil4acd6042015-11-30 12:10:43 +010080 struct iio_mutex *lock;
81
82 bool opened;
Lars-Peter Clausenf0d8ff42016-07-04 10:41:53 +020083 struct iio_usb_io_context io_ctx;
Paul Cercueile06f4ce2015-04-20 12:59:31 +020084};
85
86static const unsigned int libusb_to_errno_codes[] = {
87 [- LIBUSB_ERROR_INVALID_PARAM] = EINVAL,
88 [- LIBUSB_ERROR_ACCESS] = EACCES,
89 [- LIBUSB_ERROR_NO_DEVICE] = ENODEV,
90 [- LIBUSB_ERROR_NOT_FOUND] = ENXIO,
91 [- LIBUSB_ERROR_BUSY] = EBUSY,
92 [- LIBUSB_ERROR_TIMEOUT] = ETIMEDOUT,
93 [- LIBUSB_ERROR_OVERFLOW] = EIO,
94 [- LIBUSB_ERROR_PIPE] = EPIPE,
95 [- LIBUSB_ERROR_INTERRUPTED] = EINTR,
96 [- LIBUSB_ERROR_NO_MEM] = ENOMEM,
97 [- LIBUSB_ERROR_NOT_SUPPORTED] = ENOSYS,
98};
99
100static unsigned int libusb_to_errno(int error)
101{
102 switch ((enum libusb_error) error) {
103 case LIBUSB_ERROR_INVALID_PARAM:
104 case LIBUSB_ERROR_ACCESS:
105 case LIBUSB_ERROR_NO_DEVICE:
106 case LIBUSB_ERROR_NOT_FOUND:
107 case LIBUSB_ERROR_BUSY:
108 case LIBUSB_ERROR_TIMEOUT:
109 case LIBUSB_ERROR_PIPE:
110 case LIBUSB_ERROR_INTERRUPTED:
111 case LIBUSB_ERROR_NO_MEM:
112 case LIBUSB_ERROR_NOT_SUPPORTED:
113 return libusb_to_errno_codes[- (int) error];
114 case LIBUSB_ERROR_IO:
115 case LIBUSB_ERROR_OTHER:
116 case LIBUSB_ERROR_OVERFLOW:
117 default:
118 return EIO;
119 }
120}
121
Lars-Peter Clausene5c04e02016-06-22 16:52:36 +0200122static int usb_io_context_init(struct iio_usb_io_context *io_ctx)
123{
124 io_ctx->lock = iio_mutex_create();
125 if (!io_ctx->lock)
126 return -ENOMEM;
127
128 return 0;
129}
130
131static void usb_io_context_exit(struct iio_usb_io_context *io_ctx)
132{
133 if (io_ctx->lock) {
134 iio_mutex_destroy(io_ctx->lock);
135 io_ctx->lock = NULL;
136 }
137}
138
Paul Cercueilc11737c2015-11-26 14:44:46 +0100139static int usb_get_version(const struct iio_context *ctx,
140 unsigned int *major, unsigned int *minor, char git_tag[8])
141{
142 return iiod_client_get_version(ctx->pdata->iiod_client,
Lars-Peter Clausen2767d4d2016-06-23 14:19:02 +0200143 &ctx->pdata->io_ctx, major, minor, git_tag);
Paul Cercueilc11737c2015-11-26 14:44:46 +0100144}
145
Paul Cercueila5e4aa42016-02-09 13:31:01 +0100146static unsigned int usb_calculate_remote_timeout(unsigned int timeout)
147{
148 /* XXX(pcercuei): We currently hardcode timeout / 2 for the backend used
149 * by the remote. Is there something better to do here? */
150 return timeout / 2;
151}
152
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100153#define USB_PIPE_CTRL_TIMEOUT 200 /* These should not take long */
154
155#define IIO_USD_CMD_RESET_PIPES 0
156#define IIO_USD_CMD_OPEN_PIPE 1
157#define IIO_USD_CMD_CLOSE_PIPE 2
158
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100159static int usb_reset_pipes(struct iio_context_pdata *pdata)
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100160{
161 int ret;
162
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100163 ret = libusb_control_transfer(pdata->hdl, LIBUSB_REQUEST_TYPE_VENDOR |
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100164 LIBUSB_RECIPIENT_INTERFACE, IIO_USD_CMD_RESET_PIPES,
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100165 0, pdata->interface, NULL, 0, USB_PIPE_CTRL_TIMEOUT);
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100166 if (ret < 0)
Paul Cercueil67482202016-04-21 16:40:02 +0200167 return -(int) libusb_to_errno(ret);
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100168 return 0;
169}
170
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100171static int usb_open_pipe(struct iio_context_pdata *pdata, unsigned int pipe_id)
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100172{
173 int ret;
174
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100175 ret = libusb_control_transfer(pdata->hdl, LIBUSB_REQUEST_TYPE_VENDOR |
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100176 LIBUSB_RECIPIENT_INTERFACE, IIO_USD_CMD_OPEN_PIPE,
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100177 pipe_id, pdata->interface, NULL, 0, USB_PIPE_CTRL_TIMEOUT);
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100178 if (ret < 0)
Paul Cercueil67482202016-04-21 16:40:02 +0200179 return -(int) libusb_to_errno(ret);
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100180 return 0;
181}
182
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100183static int usb_close_pipe(struct iio_context_pdata *pdata, unsigned int pipe_id)
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100184{
185 int ret;
186
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100187 ret = libusb_control_transfer(pdata->hdl, LIBUSB_REQUEST_TYPE_VENDOR |
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100188 LIBUSB_RECIPIENT_INTERFACE, IIO_USD_CMD_CLOSE_PIPE,
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100189 pipe_id, pdata->interface, NULL, 0, USB_PIPE_CTRL_TIMEOUT);
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100190 if (ret < 0)
Paul Cercueil67482202016-04-21 16:40:02 +0200191 return -(int) libusb_to_errno(ret);
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100192 return 0;
193}
194
Paul Cercueil4213a432016-02-09 14:00:40 +0100195static int usb_reserve_ep_unlocked(const struct iio_device *dev)
196{
197 struct iio_context_pdata *pdata = dev->ctx->pdata;
198 unsigned int i;
199
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100200 for (i = 0; i < pdata->nb_ep_couples; i++) {
201 struct iio_usb_ep_couple *ep = &pdata->io_endpoints[i];
Paul Cercueil4213a432016-02-09 14:00:40 +0100202
203 if (!ep->in_use) {
204 ep->in_use = true;
205
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100206 dev->pdata->io_ctx.ep = ep;
Paul Cercueil4213a432016-02-09 14:00:40 +0100207 dev->pdata->lock = ep->lock;
208 return 0;
209 }
210 }
211
212 return -EBUSY;
213}
214
215static void usb_free_ep_unlocked(const struct iio_device *dev)
216{
217 struct iio_context_pdata *pdata = dev->ctx->pdata;
218 unsigned int i;
219
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100220 for (i = 0; i < pdata->nb_ep_couples; i++) {
221 struct iio_usb_ep_couple *ep = &pdata->io_endpoints[i];
Paul Cercueil4213a432016-02-09 14:00:40 +0100222
223 if (ep->lock == dev->pdata->lock) {
224 ep->in_use = false;
225 return;
226 }
227 }
228}
229
Paul Cercueil4acd6042015-11-30 12:10:43 +0100230static int usb_open(const struct iio_device *dev,
231 size_t samples_count, bool cyclic)
232{
Paul Cercueila5e4aa42016-02-09 13:31:01 +0100233 struct iio_context_pdata *ctx_pdata = dev->ctx->pdata;
Paul Cercueil4acd6042015-11-30 12:10:43 +0100234 struct iio_device_pdata *pdata = dev->pdata;
235 int ret = -EBUSY;
236
Paul Cercueil4213a432016-02-09 14:00:40 +0100237 iio_mutex_lock(ctx_pdata->ep_lock);
Paul Cercueil4acd6042015-11-30 12:10:43 +0100238
Lars-Peter Clausene5c04e02016-06-22 16:52:36 +0200239 pdata->io_ctx.cancelled = false;
240
Paul Cercueila5e4aa42016-02-09 13:31:01 +0100241 if (pdata->opened)
242 goto out_unlock;
243
Paul Cercueil4213a432016-02-09 14:00:40 +0100244 ret = usb_reserve_ep_unlocked(dev);
245 if (ret)
246 goto out_unlock;
247
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100248 ret = usb_open_pipe(ctx_pdata, pdata->io_ctx.ep->pipe_id);
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100249 if (ret) {
250 char err_str[1024];
251
252 iio_strerror(-ret, err_str, sizeof(err_str));
253 ERROR("Failed to open pipe: %s\n", err_str);
254 usb_free_ep_unlocked(dev);
255 goto out_unlock;
256 }
257
Paul Cercueil4213a432016-02-09 14:00:40 +0100258 iio_mutex_lock(pdata->lock);
259
Lars-Peter Clausen2767d4d2016-06-23 14:19:02 +0200260 ret = iiod_client_open_unlocked(ctx_pdata->iiod_client, &pdata->io_ctx,
261 dev, samples_count, cyclic);
Paul Cercueila5e4aa42016-02-09 13:31:01 +0100262
263 if (!ret) {
264 unsigned int remote_timeout =
265 usb_calculate_remote_timeout(ctx_pdata->timeout_ms);
266
267 ret = iiod_client_set_timeout(ctx_pdata->iiod_client,
Lars-Peter Clausen2767d4d2016-06-23 14:19:02 +0200268 &pdata->io_ctx, remote_timeout);
Paul Cercueil4acd6042015-11-30 12:10:43 +0100269 }
270
Paul Cercueila5e4aa42016-02-09 13:31:01 +0100271 pdata->opened = !ret;
272
Paul Cercueil4acd6042015-11-30 12:10:43 +0100273 iio_mutex_unlock(pdata->lock);
Paul Cercueil4213a432016-02-09 14:00:40 +0100274
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100275 if (ret) {
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100276 usb_close_pipe(ctx_pdata, pdata->io_ctx.ep->pipe_id);
Paul Cercueil4213a432016-02-09 14:00:40 +0100277 usb_free_ep_unlocked(dev);
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100278 }
Paul Cercueil4213a432016-02-09 14:00:40 +0100279
280out_unlock:
281 iio_mutex_unlock(ctx_pdata->ep_lock);
Paul Cercueil4acd6042015-11-30 12:10:43 +0100282 return ret;
283}
284
285static int usb_close(const struct iio_device *dev)
286{
Paul Cercueil4213a432016-02-09 14:00:40 +0100287 struct iio_context_pdata *ctx_pdata = dev->ctx->pdata;
Paul Cercueil4acd6042015-11-30 12:10:43 +0100288 struct iio_device_pdata *pdata = dev->pdata;
289 int ret = -EBADF;
290
Paul Cercueil4213a432016-02-09 14:00:40 +0100291 iio_mutex_lock(ctx_pdata->ep_lock);
292 if (!pdata->opened)
293 goto out_unlock;
Paul Cercueil4acd6042015-11-30 12:10:43 +0100294
Paul Cercueil4213a432016-02-09 14:00:40 +0100295 iio_mutex_lock(pdata->lock);
Lars-Peter Clausen2767d4d2016-06-23 14:19:02 +0200296 ret = iiod_client_close_unlocked(ctx_pdata->iiod_client, &pdata->io_ctx,
297 dev);
Paul Cercueil4213a432016-02-09 14:00:40 +0100298 pdata->opened = false;
299
Paul Cercueil31492b32016-02-22 17:40:20 +0100300 iio_mutex_unlock(pdata->lock);
301
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100302 usb_close_pipe(ctx_pdata, pdata->io_ctx.ep->pipe_id);
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100303
Paul Cercueil4213a432016-02-09 14:00:40 +0100304 usb_free_ep_unlocked(dev);
305
306out_unlock:
307 iio_mutex_unlock(ctx_pdata->ep_lock);
Paul Cercueil4acd6042015-11-30 12:10:43 +0100308 return ret;
309}
310
Paul Cercueil04841832015-12-02 11:58:33 +0100311static ssize_t usb_read(const struct iio_device *dev, void *dst, size_t len,
312 uint32_t *mask, size_t words)
313{
314 struct iio_device_pdata *pdata = dev->pdata;
315 ssize_t ret;
316
317 iio_mutex_lock(pdata->lock);
318 ret = iiod_client_read_unlocked(dev->ctx->pdata->iiod_client,
Lars-Peter Clausen2767d4d2016-06-23 14:19:02 +0200319 &pdata->io_ctx, dev, dst, len, mask, words);
Paul Cercueil04841832015-12-02 11:58:33 +0100320 iio_mutex_unlock(pdata->lock);
321
322 return ret;
323}
324
Paul Cercueile78e9882015-12-04 16:31:10 +0100325static ssize_t usb_write(const struct iio_device *dev,
326 const void *src, size_t len)
327{
328 struct iio_device_pdata *pdata = dev->pdata;
329 ssize_t ret;
330
331 iio_mutex_lock(pdata->lock);
332 ret = iiod_client_write_unlocked(dev->ctx->pdata->iiod_client,
Lars-Peter Clausen2767d4d2016-06-23 14:19:02 +0200333 &pdata->io_ctx, dev, src, len);
Paul Cercueile78e9882015-12-04 16:31:10 +0100334 iio_mutex_unlock(pdata->lock);
335
336 return ret;
337}
338
Paul Cercueil3069e3b2015-11-26 16:01:25 +0100339static ssize_t usb_read_dev_attr(const struct iio_device *dev,
Matt Fornero81f04a52017-11-30 14:36:37 -0500340 const char *attr, char *dst, size_t len, enum iio_attr_type type)
Paul Cercueil3069e3b2015-11-26 16:01:25 +0100341{
342 struct iio_context_pdata *pdata = dev->ctx->pdata;
343
Lars-Peter Clausenf0d8ff42016-07-04 10:41:53 +0200344 return iiod_client_read_attr(pdata->iiod_client,
Lars-Peter Clausen2767d4d2016-06-23 14:19:02 +0200345 &pdata->io_ctx, dev, NULL, attr,
Matt Fornero81f04a52017-11-30 14:36:37 -0500346 dst, len, type);
Paul Cercueil3069e3b2015-11-26 16:01:25 +0100347}
348
349static ssize_t usb_write_dev_attr(const struct iio_device *dev,
Matt Fornero81f04a52017-11-30 14:36:37 -0500350 const char *attr, const char *src, size_t len, enum iio_attr_type type)
Paul Cercueil3069e3b2015-11-26 16:01:25 +0100351{
352 struct iio_context_pdata *pdata = dev->ctx->pdata;
353
Lars-Peter Clausenf0d8ff42016-07-04 10:41:53 +0200354 return iiod_client_write_attr(pdata->iiod_client,
Lars-Peter Clausen2767d4d2016-06-23 14:19:02 +0200355 &pdata->io_ctx, dev, NULL, attr,
Matt Fornero81f04a52017-11-30 14:36:37 -0500356 src, len, type);
Paul Cercueil3069e3b2015-11-26 16:01:25 +0100357}
358
359static ssize_t usb_read_chn_attr(const struct iio_channel *chn,
360 const char *attr, char *dst, size_t len)
361{
362 struct iio_context_pdata *pdata = chn->dev->ctx->pdata;
363
Lars-Peter Clausenf0d8ff42016-07-04 10:41:53 +0200364 return iiod_client_read_attr(pdata->iiod_client,
Lars-Peter Clausen2767d4d2016-06-23 14:19:02 +0200365 &pdata->io_ctx, chn->dev, chn, attr,
Lars-Peter Clausenf0d8ff42016-07-04 10:41:53 +0200366 dst, len, false);
Paul Cercueil3069e3b2015-11-26 16:01:25 +0100367}
368
369static ssize_t usb_write_chn_attr(const struct iio_channel *chn,
370 const char *attr, const char *src, size_t len)
371{
372 struct iio_context_pdata *pdata = chn->dev->ctx->pdata;
373
Lars-Peter Clausenf0d8ff42016-07-04 10:41:53 +0200374 return iiod_client_write_attr(pdata->iiod_client,
Lars-Peter Clausen2767d4d2016-06-23 14:19:02 +0200375 &pdata->io_ctx, chn->dev, chn, attr,
Lars-Peter Clausenf0d8ff42016-07-04 10:41:53 +0200376 src, len, false);
Paul Cercueil3069e3b2015-11-26 16:01:25 +0100377}
378
Paul Cercueil6c8337e2015-11-27 11:13:09 +0100379static int usb_set_kernel_buffers_count(const struct iio_device *dev,
380 unsigned int nb_blocks)
381{
382 struct iio_context_pdata *pdata = dev->ctx->pdata;
383
384 return iiod_client_set_kernel_buffers_count(pdata->iiod_client,
Lars-Peter Clausen2767d4d2016-06-23 14:19:02 +0200385 &pdata->io_ctx, dev, nb_blocks);
Paul Cercueil6c8337e2015-11-27 11:13:09 +0100386}
387
Paul Cercueil7a988892015-12-03 12:39:20 +0100388static int usb_set_timeout(struct iio_context *ctx, unsigned int timeout)
389{
390 struct iio_context_pdata *pdata = ctx->pdata;
391 unsigned int remote_timeout = usb_calculate_remote_timeout(timeout);
392 int ret;
393
394 ret = iiod_client_set_timeout(pdata->iiod_client,
Lars-Peter Clausen2767d4d2016-06-23 14:19:02 +0200395 &pdata->io_ctx, remote_timeout);
Paul Cercueila5e4aa42016-02-09 13:31:01 +0100396 if (!ret)
397 pdata->timeout_ms = timeout;
Paul Cercueil7a988892015-12-03 12:39:20 +0100398
Paul Cercueil7a988892015-12-03 12:39:20 +0100399 return ret;
400}
401
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200402static void usb_shutdown(struct iio_context *ctx)
403{
Paul Cercueil4213a432016-02-09 14:00:40 +0100404 unsigned int i;
405
Lars-Peter Clausene5c04e02016-06-22 16:52:36 +0200406 usb_io_context_exit(&ctx->pdata->io_ctx);
Paul Cercueile916d892016-08-01 16:00:49 +0200407
408 for (i = 0; i < ctx->nb_devices; i++)
409 usb_close(ctx->devices[i]);
410
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200411 iio_mutex_destroy(ctx->pdata->lock);
Paul Cercueil4213a432016-02-09 14:00:40 +0100412 iio_mutex_destroy(ctx->pdata->ep_lock);
413
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100414 for (i = 0; i < ctx->pdata->nb_ep_couples; i++)
Paul Cercueil4213a432016-02-09 14:00:40 +0100415 if (ctx->pdata->io_endpoints[i].lock)
416 iio_mutex_destroy(ctx->pdata->io_endpoints[i].lock);
417 if (ctx->pdata->io_endpoints)
418 free(ctx->pdata->io_endpoints);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200419
Lars-Peter Clausen33c64312016-02-19 13:32:08 +0100420 for (i = 0; i < ctx->nb_devices; i++) {
421 struct iio_device *dev = ctx->devices[i];
422
Lars-Peter Clausene5c04e02016-06-22 16:52:36 +0200423 usb_io_context_exit(&dev->pdata->io_ctx);
Lars-Peter Clausen33c64312016-02-19 13:32:08 +0100424 free(dev->pdata);
425 }
426
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200427 iiod_client_destroy(ctx->pdata->iiod_client);
428
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100429 usb_reset_pipes(ctx->pdata); /* Close everything */
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100430
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200431 libusb_close(ctx->pdata->hdl);
432 libusb_exit(ctx->pdata->ctx);
Lars-Peter Clausen33c64312016-02-19 13:32:08 +0100433 free(ctx->pdata);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200434}
435
Lars-Peter Clausen794ba032016-04-25 15:07:00 +0200436static int iio_usb_match_interface(const struct libusb_config_descriptor *desc,
437 struct libusb_device_handle *hdl, unsigned int interface)
438{
439 const struct libusb_interface *iface;
440 unsigned int i;
441
442 if (interface >= desc->bNumInterfaces)
443 return -EINVAL;
444
445 iface = &desc->interface[interface];
446
447 for (i = 0; i < (unsigned int) iface->num_altsetting; i++) {
448 const struct libusb_interface_descriptor *idesc =
449 &iface->altsetting[i];
450 char name[64];
451 int ret;
452
453 if (idesc->iInterface == 0)
454 continue;
455
456 ret = libusb_get_string_descriptor_ascii(hdl, idesc->iInterface,
457 (unsigned char *) name, sizeof(name));
458 if (ret < 0)
Paul Cercueil8e42de12016-11-25 11:27:04 +0100459 return -(int) libusb_to_errno(ret);
Lars-Peter Clausen794ba032016-04-25 15:07:00 +0200460
461 if (!strcmp(name, IIO_INTERFACE_NAME))
462 return (int) i;
463 }
464
465 return -EPERM;
466}
467
468static int iio_usb_match_device(struct libusb_device *dev,
469 struct libusb_device_handle *hdl,
470 unsigned int *interface)
471{
472 struct libusb_config_descriptor *desc;
473 unsigned int i;
474 int ret;
475
476 ret = libusb_get_active_config_descriptor(dev, &desc);
477 if (ret)
478 return -(int) libusb_to_errno(ret);
479
480 for (i = 0, ret = -EPERM; ret == -EPERM &&
481 i < desc->bNumInterfaces; i++)
482 ret = iio_usb_match_interface(desc, hdl, i);
483
484 libusb_free_config_descriptor(desc);
485 if (ret < 0)
486 return ret;
487
488 DEBUG("Found IIO interface on device %u:%u using interface %u\n",
489 libusb_get_bus_number(dev),
490 libusb_get_device_address(dev), i - 1);
491
492 *interface = i - 1;
493 return ret;
494}
495
Lars-Peter Clausene5c04e02016-06-22 16:52:36 +0200496static void usb_cancel(const struct iio_device *dev)
497{
498 struct iio_device_pdata *ppdata = dev->pdata;
499
500 iio_mutex_lock(ppdata->io_ctx.lock);
501 if (ppdata->io_ctx.transfer && !ppdata->io_ctx.cancelled)
502 libusb_cancel_transfer(ppdata->io_ctx.transfer);
503 ppdata->io_ctx.cancelled = true;
504 iio_mutex_unlock(ppdata->io_ctx.lock);
505}
506
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200507static const struct iio_backend_ops usb_ops = {
Paul Cercueilc11737c2015-11-26 14:44:46 +0100508 .get_version = usb_get_version,
Paul Cercueil4acd6042015-11-30 12:10:43 +0100509 .open = usb_open,
510 .close = usb_close,
Paul Cercueil04841832015-12-02 11:58:33 +0100511 .read = usb_read,
Paul Cercueile78e9882015-12-04 16:31:10 +0100512 .write = usb_write,
Paul Cercueil3069e3b2015-11-26 16:01:25 +0100513 .read_device_attr = usb_read_dev_attr,
514 .read_channel_attr = usb_read_chn_attr,
515 .write_device_attr = usb_write_dev_attr,
516 .write_channel_attr = usb_write_chn_attr,
Paul Cercueil6c8337e2015-11-27 11:13:09 +0100517 .set_kernel_buffers_count = usb_set_kernel_buffers_count,
Paul Cercueil7a988892015-12-03 12:39:20 +0100518 .set_timeout = usb_set_timeout,
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200519 .shutdown = usb_shutdown,
Lars-Peter Clausene5c04e02016-06-22 16:52:36 +0200520
521 .cancel = usb_cancel,
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200522};
523
Lars-Peter Clausenee508922016-04-22 15:38:20 +0200524static void LIBUSB_CALL sync_transfer_cb(struct libusb_transfer *transfer)
525{
526 int *completed = transfer->user_data;
527 *completed = 1;
528}
529
530static int usb_sync_transfer(struct iio_context_pdata *pdata,
531 struct iio_usb_io_context *io_ctx, unsigned int ep_type,
532 char *data, size_t len, int *transferred)
533{
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100534 unsigned int ep;
Lars-Peter Clausenee508922016-04-22 15:38:20 +0200535 struct libusb_transfer *transfer;
536 int completed = 0;
537 int ret;
538
Paul Cercueildb1681a2017-05-17 17:50:51 +0200539 /*
540 * If the size of the data to transfer is too big, the
541 * IOCTL_USBFS_SUBMITURB ioctl (called by libusb) might fail with
542 * errno set to ENOMEM, as the kernel might use contiguous allocation
543 * for the URB if the driver doesn't support scatter-gather.
544 * To prevent that, we support URBs of 1 MiB maximum. The iiod-client
545 * code will handle this properly and ask for a new transfer.
546 */
547 if (len > 1 * 1024 * 1024)
548 len = 1 * 1024 * 1024;
549
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100550 if (ep_type == LIBUSB_ENDPOINT_IN)
551 ep = io_ctx->ep->addr_in;
552 else
553 ep = io_ctx->ep->addr_out;
554
Lars-Peter Clausene5c04e02016-06-22 16:52:36 +0200555 /*
556 * For cancellation support the check whether the buffer has already been
557 * cancelled and the allocation as well as the assignment of the new
558 * transfer needs to happen in one atomic step. Otherwise it is possible
559 * that the cancellation is missed and transfer is not aborted.
560 */
561 iio_mutex_lock(io_ctx->lock);
562 if (io_ctx->cancelled) {
563 ret = -EBADF;
564 goto unlock;
565 }
566
Lars-Peter Clausenee508922016-04-22 15:38:20 +0200567 transfer = libusb_alloc_transfer(0);
Lars-Peter Clausene5c04e02016-06-22 16:52:36 +0200568 if (!transfer) {
569 ret = -ENOMEM;
570 goto unlock;
571 }
Lars-Peter Clausenee508922016-04-22 15:38:20 +0200572
573 transfer->user_data = &completed;
574
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100575 libusb_fill_bulk_transfer(transfer, pdata->hdl, ep,
Lars-Peter Clausenee508922016-04-22 15:38:20 +0200576 (unsigned char *) data, (int) len, sync_transfer_cb,
577 &completed, pdata->timeout_ms);
578 transfer->type = LIBUSB_TRANSFER_TYPE_BULK;
579
580 ret = libusb_submit_transfer(transfer);
Paul Cercueil1f987912016-09-28 10:44:10 +0200581 if (ret) {
582 ret = -(int) libusb_to_errno(ret);
Lars-Peter Clausenee508922016-04-22 15:38:20 +0200583 libusb_free_transfer(transfer);
Lars-Peter Clausene5c04e02016-06-22 16:52:36 +0200584 goto unlock;
Lars-Peter Clausenee508922016-04-22 15:38:20 +0200585 }
586
Lars-Peter Clausene5c04e02016-06-22 16:52:36 +0200587 io_ctx->transfer = transfer;
588unlock:
589 iio_mutex_unlock(io_ctx->lock);
590 if (ret)
591 return ret;
592
Lars-Peter Clausenee508922016-04-22 15:38:20 +0200593 while (!completed) {
594 ret = libusb_handle_events_completed(pdata->ctx, &completed);
595 if (ret < 0) {
596 if (ret == LIBUSB_ERROR_INTERRUPTED)
597 continue;
598 libusb_cancel_transfer(transfer);
599 continue;
600 }
601 }
602
603 switch (transfer->status) {
604 case LIBUSB_TRANSFER_COMPLETED:
605 *transferred = transfer->actual_length;
606 ret = 0;
607 break;
608 case LIBUSB_TRANSFER_TIMED_OUT:
609 ret = -ETIMEDOUT;
610 break;
611 case LIBUSB_TRANSFER_STALL:
612 ret = -EPIPE;
613 break;
614 case LIBUSB_TRANSFER_NO_DEVICE:
615 ret = -ENODEV;
616 break;
617 case LIBUSB_TRANSFER_CANCELLED:
618 ret = -EBADF;
619 break;
620 default:
621 ret = -EIO;
622 break;
623 }
624
Lars-Peter Clausene5c04e02016-06-22 16:52:36 +0200625 /* Same as above. This needs to be atomic in regards to usb_cancel(). */
626 iio_mutex_lock(io_ctx->lock);
627 io_ctx->transfer = NULL;
628 iio_mutex_unlock(io_ctx->lock);
629
Lars-Peter Clausenee508922016-04-22 15:38:20 +0200630 libusb_free_transfer(transfer);
631
632 return ret;
633}
634
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200635static ssize_t write_data_sync(struct iio_context_pdata *pdata,
Lars-Peter Clausen2767d4d2016-06-23 14:19:02 +0200636 void *ep, const char *data, size_t len)
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200637{
638 int transferred, ret;
639
Lars-Peter Clausen2767d4d2016-06-23 14:19:02 +0200640 ret = usb_sync_transfer(pdata, ep, LIBUSB_ENDPOINT_OUT, (char *) data,
641 len, &transferred);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200642 if (ret)
Paul Cercueil1f987912016-09-28 10:44:10 +0200643 return ret;
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200644 else
Paul Cercueil753edc02017-05-17 17:40:56 +0200645 return (ssize_t) transferred;
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200646}
647
648static ssize_t read_data_sync(struct iio_context_pdata *pdata,
Lars-Peter Clausen2767d4d2016-06-23 14:19:02 +0200649 void *ep, char *buf, size_t len)
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200650{
651 int transferred, ret;
652
Lars-Peter Clausen2767d4d2016-06-23 14:19:02 +0200653 ret = usb_sync_transfer(pdata, ep, LIBUSB_ENDPOINT_IN, buf, len,
654 &transferred);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200655 if (ret)
Paul Cercueil1f987912016-09-28 10:44:10 +0200656 return ret;
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200657 else
658 return transferred;
659}
660
Lars-Peter Clausen09a59d72016-02-03 15:27:04 +0100661static const struct iiod_client_ops usb_iiod_client_ops = {
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200662 .write = write_data_sync,
663 .read = read_data_sync,
664 .read_line = read_data_sync,
665};
666
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100667static int usb_verify_eps(const struct libusb_interface_descriptor *iface)
Paul Cercueil4213a432016-02-09 14:00:40 +0100668{
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100669 unsigned int i, eps = iface->bNumEndpoints;
Paul Cercueil4213a432016-02-09 14:00:40 +0100670
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100671 /* Check that we have an even number of endpoints, and that input/output
672 * endpoints are interleaved */
Paul Cercueil4213a432016-02-09 14:00:40 +0100673
674 if (eps < 2 || eps % 2)
675 return -EINVAL;
676
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100677 for (i = 0; i < eps; i += 2) {
678 if (!(iface->endpoint[i + 0].bEndpointAddress
679 & LIBUSB_ENDPOINT_IN))
Paul Cercueil4213a432016-02-09 14:00:40 +0100680 return -EINVAL;
681
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100682 if (iface->endpoint[i + 1].bEndpointAddress
683 & LIBUSB_ENDPOINT_IN)
Paul Cercueil4213a432016-02-09 14:00:40 +0100684 return -EINVAL;
685 }
686
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100687 return 0;
Paul Cercueil4213a432016-02-09 14:00:40 +0100688}
689
Paul Cercueilc4751d62016-11-25 11:22:18 +0100690static int usb_populate_context_attrs(struct iio_context *ctx,
691 libusb_device *dev, libusb_device_handle *hdl)
692{
693 struct libusb_device_descriptor dev_desc;
694 char buffer[64];
695 unsigned int i;
696 int ret;
697
698 struct {
699 const char *attr;
700 uint8_t idx;
701 } attrs[3];
702
703 libusb_get_device_descriptor(dev, &dev_desc);
704
705 attrs[0].attr = "usb,vendor";
706 attrs[0].idx = dev_desc.iManufacturer;
707 attrs[1].attr = "usb,product";
708 attrs[1].idx = dev_desc.iProduct;
709 attrs[2].attr = "usb,serial";
710 attrs[2].idx = dev_desc.iSerialNumber;
711
Paul Cercueil9c9a5562017-01-24 10:48:31 +0100712 iio_snprintf(buffer, sizeof(buffer), "%04hx", dev_desc.idVendor);
Paul Cercueilc4751d62016-11-25 11:22:18 +0100713 ret = iio_context_add_attr(ctx, "usb,idVendor", buffer);
714 if (ret < 0)
715 return ret;
716
Paul Cercueil9c9a5562017-01-24 10:48:31 +0100717 iio_snprintf(buffer, sizeof(buffer), "%04hx", dev_desc.idProduct);
Paul Cercueilc4751d62016-11-25 11:22:18 +0100718 ret = iio_context_add_attr(ctx, "usb,idProduct", buffer);
719 if (ret < 0)
720 return ret;
721
Paul Cercueil9c9a5562017-01-24 10:48:31 +0100722 iio_snprintf(buffer, sizeof(buffer), "%1hhx.%1hhx",
Paul Cercueil1a970d32017-01-09 13:28:22 +0100723 (unsigned char)((dev_desc.bcdUSB >> 8) & 0xf),
724 (unsigned char)((dev_desc.bcdUSB >> 4) & 0xf));
Paul Cercueilc4751d62016-11-25 11:22:18 +0100725 ret = iio_context_add_attr(ctx, "usb,release", buffer);
726 if (ret < 0)
727 return ret;
728
729 for (i = 0; i < ARRAY_SIZE(attrs); i++) {
730 if (attrs[i].idx) {
731 ret = libusb_get_string_descriptor_ascii(hdl,
732 attrs[i].idx, (unsigned char *) buffer,
733 sizeof(buffer));
734 if (ret < 0)
735 return -(int) libusb_to_errno(ret);
736
737 ret = iio_context_add_attr(ctx, attrs[i].attr, buffer);
738 if (ret < 0)
739 return ret;
740 }
741 }
742
743 return 0;
744}
745
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100746struct iio_context * usb_create_context(unsigned int bus,
747 unsigned int address, unsigned int interface)
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200748{
749 libusb_context *usb_ctx;
750 libusb_device_handle *hdl;
Paul Cercueil4213a432016-02-09 14:00:40 +0100751 const struct libusb_interface_descriptor *iface;
Paul Cercueil0d6fee32016-11-25 11:25:46 +0100752 libusb_device *usb_dev;
Paul Cercueil4213a432016-02-09 14:00:40 +0100753 struct libusb_config_descriptor *conf_desc;
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100754 libusb_device **device_list;
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200755 struct iio_context *ctx;
756 struct iio_context_pdata *pdata;
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100757 char err_str[1024];
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200758 unsigned int i;
759 int ret;
760
Lars-Peter Clausend1be8382016-02-24 11:13:45 +0100761 pdata = zalloc(sizeof(*pdata));
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200762 if (!pdata) {
763 ERROR("Unable to allocate pdata\n");
764 ret = -ENOMEM;
765 goto err_set_errno;
766 }
767
768 pdata->lock = iio_mutex_create();
769 if (!pdata->lock) {
770 ERROR("Unable to create mutex\n");
771 ret = -ENOMEM;
772 goto err_free_pdata;
773 }
774
Paul Cercueil4213a432016-02-09 14:00:40 +0100775 pdata->ep_lock = iio_mutex_create();
776 if (!pdata->ep_lock) {
Paul Cercueil4acd6042015-11-30 12:10:43 +0100777 ERROR("Unable to create mutex\n");
778 ret = -ENOMEM;
779 goto err_destroy_mutex;
780 }
781
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200782 pdata->iiod_client = iiod_client_new(pdata, pdata->lock,
783 &usb_iiod_client_ops);
784 if (!pdata->iiod_client) {
785 ERROR("Unable to create IIOD client\n");
786 ret = -errno;
Paul Cercueil4213a432016-02-09 14:00:40 +0100787 goto err_destroy_ep_mutex;
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200788 }
789
790 ret = libusb_init(&usb_ctx);
791 if (ret) {
Paul Cercueil463fc782015-12-04 16:04:12 +0100792 ret = -(int) libusb_to_errno(ret);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200793 ERROR("Unable to init libusb: %i\n", ret);
Paul Cercueil4acd6042015-11-30 12:10:43 +0100794 goto err_destroy_iiod_client;
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200795 }
796
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100797 libusb_get_device_list(usb_ctx, &device_list);
798
799 usb_dev = NULL;
800
801 for (i = 0; device_list[i]; i++) {
Paul Cercueil0d6fee32016-11-25 11:25:46 +0100802 libusb_device *dev = device_list[i];
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100803
804 if (bus == libusb_get_bus_number(dev) &&
805 address == libusb_get_device_address(dev)) {
806 usb_dev = dev;
Lars-Peter Clausen158bb022017-01-10 18:00:35 +0100807
808 ret = libusb_open(usb_dev, &hdl);
809 /*
810 * Workaround for libusb on Windows >= 8.1. A device
811 * might appear twice in the list with one device being
812 * bogus and only partially initialized. libusb_open()
813 * returns LIBUSB_ERROR_NOT_SUPPORTED for such devices,
814 * which should never happen for normal devices. So if
815 * we find such a device skip it and keep looking.
816 */
817 if (ret == LIBUSB_ERROR_NOT_SUPPORTED) {
818 WARNING("Skipping broken USB device. Please upgrade libusb.\n");
819 usb_dev = NULL;
820 continue;
821 }
822
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100823 break;
824 }
825 }
826
827 libusb_free_device_list(device_list, true);
828
Paul Cercueil7f6c90c2017-02-14 13:55:27 +0100829 if (!usb_dev) {
830 ret = -ENODEV;
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100831 goto err_libusb_exit;
Paul Cercueil7f6c90c2017-02-14 13:55:27 +0100832 }
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100833
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100834 if (ret) {
835 ret = -(int) libusb_to_errno(ret);
836 ERROR("Unable to open device\n");
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200837 goto err_libusb_exit;
838 }
839
Robin Getz89c3efd2016-12-26 22:37:12 -0500840#if defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION >= 0x01000016)
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200841 libusb_set_auto_detach_kernel_driver(hdl, true);
Robin Getz89c3efd2016-12-26 22:37:12 -0500842#endif
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200843
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100844 ret = libusb_claim_interface(hdl, interface);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200845 if (ret) {
Paul Cercueil463fc782015-12-04 16:04:12 +0100846 ret = -(int) libusb_to_errno(ret);
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100847 ERROR("Unable to claim interface %u: %i\n", interface, ret);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200848 goto err_libusb_close;
849 }
850
Paul Cercueil4213a432016-02-09 14:00:40 +0100851 ret = libusb_get_active_config_descriptor(usb_dev, &conf_desc);
852 if (ret) {
853 ret = -(int) libusb_to_errno(ret);
854 ERROR("Unable to get config descriptor: %i\n", ret);
855 goto err_libusb_close;
856 }
857
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100858 iface = &conf_desc->interface[interface].altsetting[0];
Paul Cercueil4213a432016-02-09 14:00:40 +0100859
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100860 ret = usb_verify_eps(iface);
861 if (ret) {
Paul Cercueil4213a432016-02-09 14:00:40 +0100862 ERROR("Invalid configuration of endpoints\n");
863 goto err_free_config_descriptor;
864 }
865
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100866 pdata->nb_ep_couples = iface->bNumEndpoints / 2;
Paul Cercueil4213a432016-02-09 14:00:40 +0100867
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100868 DEBUG("Found %hhu usable i/o endpoint couples\n", pdata->nb_ep_couples);
Paul Cercueil4213a432016-02-09 14:00:40 +0100869
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100870 pdata->io_endpoints = calloc(pdata->nb_ep_couples,
871 sizeof(*pdata->io_endpoints));
872 if (!pdata->io_endpoints) {
873 ERROR("Unable to allocate endpoints\n");
874 ret = -ENOMEM;
875 goto err_free_config_descriptor;
876 }
877
878 for (i = 0; i < pdata->nb_ep_couples; i++) {
879 struct iio_usb_ep_couple *ep = &pdata->io_endpoints[i];
880
881 ep->addr_in = iface->endpoint[i * 2 + 0].bEndpointAddress;
882 ep->addr_out = iface->endpoint[i * 2 + 1].bEndpointAddress;
883 ep->pipe_id = i;
884
885 DEBUG("Couple %i with endpoints 0x%x / 0x%x\n", i,
886 ep->addr_in, ep->addr_out);
887
888 ep->lock = iio_mutex_create();
889 if (!ep->lock) {
890 ERROR("Unable to create mutex\n");
Paul Cercueil4213a432016-02-09 14:00:40 +0100891 ret = -ENOMEM;
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100892 goto err_free_endpoints;
Paul Cercueil4213a432016-02-09 14:00:40 +0100893 }
894 }
895
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200896 pdata->ctx = usb_ctx;
897 pdata->hdl = hdl;
Paul Cercueil7a988892015-12-03 12:39:20 +0100898 pdata->timeout_ms = DEFAULT_TIMEOUT_MS;
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100899 pdata->interface = interface;
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200900
Lars-Peter Clausene5c04e02016-06-22 16:52:36 +0200901 ret = usb_io_context_init(&pdata->io_ctx);
902 if (ret)
903 goto err_free_endpoints;
904
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100905 /* We reserve the first I/O endpoint couple for global operations */
906 pdata->io_ctx.ep = &pdata->io_endpoints[0];
Paul Cercueilcd31d842016-11-04 11:24:05 +0100907 pdata->io_ctx.ep->in_use = true;
Lars-Peter Clausenf0d8ff42016-07-04 10:41:53 +0200908
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100909 ret = usb_reset_pipes(pdata);
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100910 if (ret) {
911 iio_strerror(-ret, err_str, sizeof(err_str));
912 ERROR("Failed to reset pipes: %s\n", err_str);
Lars-Peter Clausene5c04e02016-06-22 16:52:36 +0200913 goto err_io_context_exit;
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100914 }
915
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100916 ret = usb_open_pipe(pdata, 0);
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100917 if (ret) {
918 iio_strerror(-ret, err_str, sizeof(err_str));
919 ERROR("Failed to open control pipe: %s\n", err_str);
Lars-Peter Clausene5c04e02016-06-22 16:52:36 +0200920 goto err_io_context_exit;
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100921 }
922
Lars-Peter Clausen2767d4d2016-06-23 14:19:02 +0200923 ctx = iiod_client_create_context(pdata->iiod_client, &pdata->io_ctx);
Paul Cercueilac5450a2017-01-27 18:34:56 +0100924 if (!ctx) {
925 ret = -errno;
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100926 goto err_reset_pipes;
Paul Cercueilac5450a2017-01-27 18:34:56 +0100927 }
Paul Cercueil4213a432016-02-09 14:00:40 +0100928
929 libusb_free_config_descriptor(conf_desc);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200930
931 ctx->name = "usb";
932 ctx->ops = &usb_ops;
933 ctx->pdata = pdata;
934
Paul Cercueil4acd6042015-11-30 12:10:43 +0100935 for (i = 0; i < ctx->nb_devices; i++) {
936 struct iio_device *dev = ctx->devices[i];
937
Lars-Peter Clausend1be8382016-02-24 11:13:45 +0100938 dev->pdata = zalloc(sizeof(*dev->pdata));
Paul Cercueil4acd6042015-11-30 12:10:43 +0100939 if (!dev->pdata) {
940 ERROR("Unable to allocate memory\n");
941 ret = -ENOMEM;
942 goto err_context_destroy;
943 }
Lars-Peter Clausene5c04e02016-06-22 16:52:36 +0200944
945 ret = usb_io_context_init(&dev->pdata->io_ctx);
946 if (ret)
947 goto err_context_destroy;
Paul Cercueil4acd6042015-11-30 12:10:43 +0100948 }
949
Paul Cercueilc4751d62016-11-25 11:22:18 +0100950 ret = usb_populate_context_attrs(ctx, usb_dev, hdl);
951 if (ret < 0)
952 goto err_context_destroy;
953
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200954 return ctx;
955
956err_context_destroy:
957 iio_context_destroy(ctx);
958 errno = -ret;
959 return NULL;
960
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100961err_reset_pipes:
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100962 usb_reset_pipes(pdata); /* Close everything */
Lars-Peter Clausene5c04e02016-06-22 16:52:36 +0200963err_io_context_exit:
964 usb_io_context_exit(&pdata->io_ctx);
Paul Cercueil4213a432016-02-09 14:00:40 +0100965err_free_endpoints:
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100966 for (i = 0; i < pdata->nb_ep_couples; i++)
Paul Cercueil4213a432016-02-09 14:00:40 +0100967 if (pdata->io_endpoints[i].lock)
968 iio_mutex_destroy(pdata->io_endpoints[i].lock);
969 if (pdata->io_endpoints)
970 free(pdata->io_endpoints);
971err_free_config_descriptor:
972 libusb_free_config_descriptor(conf_desc);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200973err_libusb_close:
974 libusb_close(hdl);
975err_libusb_exit:
976 libusb_exit(usb_ctx);
977err_destroy_iiod_client:
978 iiod_client_destroy(pdata->iiod_client);
Paul Cercueil4213a432016-02-09 14:00:40 +0100979err_destroy_ep_mutex:
980 iio_mutex_destroy(pdata->ep_lock);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200981err_destroy_mutex:
982 iio_mutex_destroy(pdata->lock);
983err_free_pdata:
984 free(pdata);
985err_set_errno:
986 errno = -ret;
987 return NULL;
988}
Lars-Peter Clausen60f1c9a2016-02-22 13:20:40 +0100989
990struct iio_context * usb_create_context_from_uri(const char *uri)
991{
Paul Cercueil370bb362016-04-20 11:50:10 +0200992 long bus, address, interface;
993 char *end;
994 const char *ptr;
Lars-Peter Clausen60f1c9a2016-02-22 13:20:40 +0100995
996 if (strncmp(uri, "usb:", sizeof("usb:") - 1) != 0)
Paul Cercueil370bb362016-04-20 11:50:10 +0200997 goto err_bad_uri;
Lars-Peter Clausen60f1c9a2016-02-22 13:20:40 +0100998
Paul Cercueil370bb362016-04-20 11:50:10 +0200999 ptr = (const char *) ((uintptr_t) uri + sizeof("usb:") - 1);
1000 if (!isdigit(*ptr))
1001 goto err_bad_uri;
Lars-Peter Clausen60f1c9a2016-02-22 13:20:40 +01001002
Paul Cercueil370bb362016-04-20 11:50:10 +02001003 bus = strtol(ptr, &end, 10);
1004 if (ptr == end || *end != '.')
1005 goto err_bad_uri;
1006
1007 ptr = (const char *) ((uintptr_t) end + 1);
1008 if (!isdigit(*ptr))
1009 goto err_bad_uri;
1010
1011 address = strtol(ptr, &end, 10);
Paul Cercueild24f8ac2016-04-20 14:19:29 +02001012 if (ptr == end)
Paul Cercueil370bb362016-04-20 11:50:10 +02001013 goto err_bad_uri;
1014
Paul Cercueild24f8ac2016-04-20 14:19:29 +02001015 if (*end == '\0') {
1016 interface = 0;
1017 } else if (*end == '.') {
1018 ptr = (const char *) ((uintptr_t) end + 1);
1019 if (!isdigit(*ptr))
1020 goto err_bad_uri;
Paul Cercueil370bb362016-04-20 11:50:10 +02001021
Paul Cercueild24f8ac2016-04-20 14:19:29 +02001022 interface = strtol(ptr, &end, 10);
1023 if (ptr == end || *end != '\0')
1024 goto err_bad_uri;
1025 } else {
Paul Cercueil370bb362016-04-20 11:50:10 +02001026 goto err_bad_uri;
Paul Cercueild24f8ac2016-04-20 14:19:29 +02001027 }
Paul Cercueil370bb362016-04-20 11:50:10 +02001028
1029 if (bus < 0 || address < 0 || interface < 0)
1030 goto err_bad_uri;
1031
1032 return usb_create_context((unsigned int) bus,
1033 (unsigned int) address, (unsigned int) interface);
1034
1035err_bad_uri:
1036 ERROR("Bad URI: \'%s\'\n", uri);
Paul Cercueilacec87c2016-11-15 14:30:56 +01001037 errno = EINVAL;
Paul Cercueil370bb362016-04-20 11:50:10 +02001038 return NULL;
Lars-Peter Clausen60f1c9a2016-02-22 13:20:40 +01001039}
Lars-Peter Clausen794ba032016-04-25 15:07:00 +02001040
1041static int usb_fill_context_info(struct iio_context_info *info,
1042 struct libusb_device *dev, struct libusb_device_handle *hdl,
1043 unsigned int interface)
1044{
1045 struct libusb_device_descriptor desc;
Michael Hennerich75c13382016-11-15 13:12:51 +01001046 char manufacturer[64], product[64], serial[64];
Lars-Peter Clausen794ba032016-04-25 15:07:00 +02001047 char uri[sizeof("usb:127.255.255")];
1048 char description[sizeof(manufacturer) + sizeof(product) +
Michael Hennerich75c13382016-11-15 13:12:51 +01001049 sizeof(serial) + sizeof("0000:0000 ( ), serial=")];
Lars-Peter Clausen794ba032016-04-25 15:07:00 +02001050 int ret;
1051
1052 libusb_get_device_descriptor(dev, &desc);
1053
Paul Cercueil9c9a5562017-01-24 10:48:31 +01001054 iio_snprintf(uri, sizeof(uri), "usb:%d.%d.%u",
Lars-Peter Clausen794ba032016-04-25 15:07:00 +02001055 libusb_get_bus_number(dev), libusb_get_device_address(dev),
1056 interface);
1057
1058 if (desc.iManufacturer == 0) {
1059 manufacturer[0] = '\0';
1060 } else {
1061 ret = libusb_get_string_descriptor_ascii(hdl,
1062 desc.iManufacturer,
1063 (unsigned char *) manufacturer,
1064 sizeof(manufacturer));
1065 if (ret < 0)
1066 manufacturer[0] = '\0';
1067 }
1068
1069 if (desc.iProduct == 0) {
1070 product[0] = '\0';
1071 } else {
1072 ret = libusb_get_string_descriptor_ascii(hdl,
1073 desc.iProduct, (unsigned char *) product,
1074 sizeof(product));
1075 if (ret < 0)
1076 product[0] = '\0';
1077 }
1078
Michael Hennerich75c13382016-11-15 13:12:51 +01001079 if (desc.iSerialNumber == 0) {
1080 serial[0] = '\0';
1081 } else {
1082 ret = libusb_get_string_descriptor_ascii(hdl,
1083 desc.iSerialNumber, (unsigned char *) serial,
1084 sizeof(serial));
1085 if (ret < 0)
1086 serial[0] = '\0';
1087 }
1088
Paul Cercueil9c9a5562017-01-24 10:48:31 +01001089 iio_snprintf(description, sizeof(description),
Michael Hennerich75c13382016-11-15 13:12:51 +01001090 "%04x:%04x (%s %s), serial=%s", desc.idVendor,
1091 desc.idProduct, manufacturer, product, serial);
Lars-Peter Clausen794ba032016-04-25 15:07:00 +02001092
Paul Cercueilcaf0e712016-08-25 17:27:02 +02001093 info->uri = iio_strdup(uri);
Lars-Peter Clausen794ba032016-04-25 15:07:00 +02001094 if (!info->uri)
1095 return -ENOMEM;
1096
Paul Cercueilcaf0e712016-08-25 17:27:02 +02001097 info->description = iio_strdup(description);
Lars-Peter Clausen794ba032016-04-25 15:07:00 +02001098 if (!info->description)
1099 return -ENOMEM;
1100
1101 return 0;
1102}
1103
1104struct iio_scan_backend_context {
1105 libusb_context *ctx;
1106};
1107
1108struct iio_scan_backend_context * usb_context_scan_init(void)
1109{
1110 struct iio_scan_backend_context *ctx;
1111 int ret;
1112
1113 ctx = malloc(sizeof(*ctx));
1114 if (!ctx) {
1115 errno = ENOMEM;
1116 return NULL;
1117 }
1118
1119 ret = libusb_init(&ctx->ctx);
1120 if (ret) {
1121 free(ctx);
1122 errno = (int) libusb_to_errno(ret);
1123 return NULL;
1124 }
1125
1126 return ctx;
1127}
1128
1129void usb_context_scan_free(struct iio_scan_backend_context *ctx)
1130{
1131 libusb_exit(ctx->ctx);
1132 free(ctx);
1133}
1134
1135int usb_context_scan(struct iio_scan_backend_context *ctx,
1136 struct iio_scan_result *scan_result)
1137{
1138 struct iio_context_info **info;
1139 libusb_device **device_list;
1140 unsigned int i;
1141 int ret;
1142
1143 ret = libusb_get_device_list(ctx->ctx, &device_list);
1144 if (ret < 0)
1145 return -(int) libusb_to_errno(ret);
1146
1147 for (i = 0; device_list[i]; i++) {
1148 struct libusb_device_handle *hdl;
1149 struct libusb_device *dev = device_list[i];
1150 unsigned int interface = 0;
1151
1152 ret = libusb_open(dev, &hdl);
1153 if (ret)
1154 continue;
1155
1156 if (!iio_usb_match_device(dev, hdl, &interface)) {
1157 info = iio_scan_result_add(scan_result, 1);
1158 if (!info)
1159 ret = -ENOMEM;
1160 else
1161 ret = usb_fill_context_info(*info, dev, hdl,
1162 interface);
1163 }
1164
1165 libusb_close(hdl);
1166 if (ret < 0)
1167 goto cleanup_free_device_list;
1168 }
1169
1170 ret = 0;
1171
1172cleanup_free_device_list:
1173 libusb_free_device_list(device_list, true);
1174 return ret;
1175}