blob: 9ea0c02bcbb3e7e695941c6227dcedf14775ed35 [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,
340 const char *attr, char *dst, size_t len, bool is_debug)
341{
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,
Lars-Peter Clausenf0d8ff42016-07-04 10:41:53 +0200346 dst, len, is_debug);
Paul Cercueil3069e3b2015-11-26 16:01:25 +0100347}
348
349static ssize_t usb_write_dev_attr(const struct iio_device *dev,
350 const char *attr, const char *src, size_t len, bool is_debug)
351{
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,
Lars-Peter Clausenf0d8ff42016-07-04 10:41:53 +0200356 src, len, is_debug);
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 Cercueilbb10bd42016-10-31 15:31:36 +0100539 if (ep_type == LIBUSB_ENDPOINT_IN)
540 ep = io_ctx->ep->addr_in;
541 else
542 ep = io_ctx->ep->addr_out;
543
Lars-Peter Clausene5c04e02016-06-22 16:52:36 +0200544 /*
545 * For cancellation support the check whether the buffer has already been
546 * cancelled and the allocation as well as the assignment of the new
547 * transfer needs to happen in one atomic step. Otherwise it is possible
548 * that the cancellation is missed and transfer is not aborted.
549 */
550 iio_mutex_lock(io_ctx->lock);
551 if (io_ctx->cancelled) {
552 ret = -EBADF;
553 goto unlock;
554 }
555
Lars-Peter Clausenee508922016-04-22 15:38:20 +0200556 transfer = libusb_alloc_transfer(0);
Lars-Peter Clausene5c04e02016-06-22 16:52:36 +0200557 if (!transfer) {
558 ret = -ENOMEM;
559 goto unlock;
560 }
Lars-Peter Clausenee508922016-04-22 15:38:20 +0200561
562 transfer->user_data = &completed;
563
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100564 libusb_fill_bulk_transfer(transfer, pdata->hdl, ep,
Lars-Peter Clausenee508922016-04-22 15:38:20 +0200565 (unsigned char *) data, (int) len, sync_transfer_cb,
566 &completed, pdata->timeout_ms);
567 transfer->type = LIBUSB_TRANSFER_TYPE_BULK;
568
569 ret = libusb_submit_transfer(transfer);
Paul Cercueil1f987912016-09-28 10:44:10 +0200570 if (ret) {
571 ret = -(int) libusb_to_errno(ret);
Lars-Peter Clausenee508922016-04-22 15:38:20 +0200572 libusb_free_transfer(transfer);
Lars-Peter Clausene5c04e02016-06-22 16:52:36 +0200573 goto unlock;
Lars-Peter Clausenee508922016-04-22 15:38:20 +0200574 }
575
Lars-Peter Clausene5c04e02016-06-22 16:52:36 +0200576 io_ctx->transfer = transfer;
577unlock:
578 iio_mutex_unlock(io_ctx->lock);
579 if (ret)
580 return ret;
581
Lars-Peter Clausenee508922016-04-22 15:38:20 +0200582 while (!completed) {
583 ret = libusb_handle_events_completed(pdata->ctx, &completed);
584 if (ret < 0) {
585 if (ret == LIBUSB_ERROR_INTERRUPTED)
586 continue;
587 libusb_cancel_transfer(transfer);
588 continue;
589 }
590 }
591
592 switch (transfer->status) {
593 case LIBUSB_TRANSFER_COMPLETED:
594 *transferred = transfer->actual_length;
595 ret = 0;
596 break;
597 case LIBUSB_TRANSFER_TIMED_OUT:
598 ret = -ETIMEDOUT;
599 break;
600 case LIBUSB_TRANSFER_STALL:
601 ret = -EPIPE;
602 break;
603 case LIBUSB_TRANSFER_NO_DEVICE:
604 ret = -ENODEV;
605 break;
606 case LIBUSB_TRANSFER_CANCELLED:
607 ret = -EBADF;
608 break;
609 default:
610 ret = -EIO;
611 break;
612 }
613
Lars-Peter Clausene5c04e02016-06-22 16:52:36 +0200614 /* Same as above. This needs to be atomic in regards to usb_cancel(). */
615 iio_mutex_lock(io_ctx->lock);
616 io_ctx->transfer = NULL;
617 iio_mutex_unlock(io_ctx->lock);
618
Lars-Peter Clausenee508922016-04-22 15:38:20 +0200619 libusb_free_transfer(transfer);
620
621 return ret;
622}
623
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200624static ssize_t write_data_sync(struct iio_context_pdata *pdata,
Lars-Peter Clausen2767d4d2016-06-23 14:19:02 +0200625 void *ep, const char *data, size_t len)
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200626{
627 int transferred, ret;
628
Lars-Peter Clausen2767d4d2016-06-23 14:19:02 +0200629 ret = usb_sync_transfer(pdata, ep, LIBUSB_ENDPOINT_OUT, (char *) data,
630 len, &transferred);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200631 if (ret)
Paul Cercueil1f987912016-09-28 10:44:10 +0200632 return ret;
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200633 else
Lars-Peter Clausen8ba0d5b2016-02-17 11:30:23 +0100634 return (size_t) transferred != len ? -EIO : (ssize_t) len;
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200635}
636
637static ssize_t read_data_sync(struct iio_context_pdata *pdata,
Lars-Peter Clausen2767d4d2016-06-23 14:19:02 +0200638 void *ep, char *buf, size_t len)
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200639{
640 int transferred, ret;
641
Lars-Peter Clausen2767d4d2016-06-23 14:19:02 +0200642 ret = usb_sync_transfer(pdata, ep, LIBUSB_ENDPOINT_IN, buf, len,
643 &transferred);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200644 if (ret)
Paul Cercueil1f987912016-09-28 10:44:10 +0200645 return ret;
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200646 else
647 return transferred;
648}
649
Lars-Peter Clausen09a59d72016-02-03 15:27:04 +0100650static const struct iiod_client_ops usb_iiod_client_ops = {
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200651 .write = write_data_sync,
652 .read = read_data_sync,
653 .read_line = read_data_sync,
654};
655
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100656static int usb_verify_eps(const struct libusb_interface_descriptor *iface)
Paul Cercueil4213a432016-02-09 14:00:40 +0100657{
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100658 unsigned int i, eps = iface->bNumEndpoints;
Paul Cercueil4213a432016-02-09 14:00:40 +0100659
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100660 /* Check that we have an even number of endpoints, and that input/output
661 * endpoints are interleaved */
Paul Cercueil4213a432016-02-09 14:00:40 +0100662
663 if (eps < 2 || eps % 2)
664 return -EINVAL;
665
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100666 for (i = 0; i < eps; i += 2) {
667 if (!(iface->endpoint[i + 0].bEndpointAddress
668 & LIBUSB_ENDPOINT_IN))
Paul Cercueil4213a432016-02-09 14:00:40 +0100669 return -EINVAL;
670
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100671 if (iface->endpoint[i + 1].bEndpointAddress
672 & LIBUSB_ENDPOINT_IN)
Paul Cercueil4213a432016-02-09 14:00:40 +0100673 return -EINVAL;
674 }
675
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100676 return 0;
Paul Cercueil4213a432016-02-09 14:00:40 +0100677}
678
Paul Cercueilc4751d62016-11-25 11:22:18 +0100679static int usb_populate_context_attrs(struct iio_context *ctx,
680 libusb_device *dev, libusb_device_handle *hdl)
681{
682 struct libusb_device_descriptor dev_desc;
683 char buffer[64];
684 unsigned int i;
685 int ret;
686
687 struct {
688 const char *attr;
689 uint8_t idx;
690 } attrs[3];
691
692 libusb_get_device_descriptor(dev, &dev_desc);
693
694 attrs[0].attr = "usb,vendor";
695 attrs[0].idx = dev_desc.iManufacturer;
696 attrs[1].attr = "usb,product";
697 attrs[1].idx = dev_desc.iProduct;
698 attrs[2].attr = "usb,serial";
699 attrs[2].idx = dev_desc.iSerialNumber;
700
Paul Cercueil9c9a5562017-01-24 10:48:31 +0100701 iio_snprintf(buffer, sizeof(buffer), "%04hx", dev_desc.idVendor);
Paul Cercueilc4751d62016-11-25 11:22:18 +0100702 ret = iio_context_add_attr(ctx, "usb,idVendor", buffer);
703 if (ret < 0)
704 return ret;
705
Paul Cercueil9c9a5562017-01-24 10:48:31 +0100706 iio_snprintf(buffer, sizeof(buffer), "%04hx", dev_desc.idProduct);
Paul Cercueilc4751d62016-11-25 11:22:18 +0100707 ret = iio_context_add_attr(ctx, "usb,idProduct", buffer);
708 if (ret < 0)
709 return ret;
710
Paul Cercueil9c9a5562017-01-24 10:48:31 +0100711 iio_snprintf(buffer, sizeof(buffer), "%1hhx.%1hhx",
Paul Cercueil1a970d32017-01-09 13:28:22 +0100712 (unsigned char)((dev_desc.bcdUSB >> 8) & 0xf),
713 (unsigned char)((dev_desc.bcdUSB >> 4) & 0xf));
Paul Cercueilc4751d62016-11-25 11:22:18 +0100714 ret = iio_context_add_attr(ctx, "usb,release", buffer);
715 if (ret < 0)
716 return ret;
717
718 for (i = 0; i < ARRAY_SIZE(attrs); i++) {
719 if (attrs[i].idx) {
720 ret = libusb_get_string_descriptor_ascii(hdl,
721 attrs[i].idx, (unsigned char *) buffer,
722 sizeof(buffer));
723 if (ret < 0)
724 return -(int) libusb_to_errno(ret);
725
726 ret = iio_context_add_attr(ctx, attrs[i].attr, buffer);
727 if (ret < 0)
728 return ret;
729 }
730 }
731
732 return 0;
733}
734
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100735struct iio_context * usb_create_context(unsigned int bus,
736 unsigned int address, unsigned int interface)
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200737{
738 libusb_context *usb_ctx;
739 libusb_device_handle *hdl;
Paul Cercueil4213a432016-02-09 14:00:40 +0100740 const struct libusb_interface_descriptor *iface;
Paul Cercueil0d6fee32016-11-25 11:25:46 +0100741 libusb_device *usb_dev;
Paul Cercueil4213a432016-02-09 14:00:40 +0100742 struct libusb_config_descriptor *conf_desc;
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100743 libusb_device **device_list;
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200744 struct iio_context *ctx;
745 struct iio_context_pdata *pdata;
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100746 char err_str[1024];
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200747 unsigned int i;
748 int ret;
749
Lars-Peter Clausend1be8382016-02-24 11:13:45 +0100750 pdata = zalloc(sizeof(*pdata));
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200751 if (!pdata) {
752 ERROR("Unable to allocate pdata\n");
753 ret = -ENOMEM;
754 goto err_set_errno;
755 }
756
757 pdata->lock = iio_mutex_create();
758 if (!pdata->lock) {
759 ERROR("Unable to create mutex\n");
760 ret = -ENOMEM;
761 goto err_free_pdata;
762 }
763
Paul Cercueil4213a432016-02-09 14:00:40 +0100764 pdata->ep_lock = iio_mutex_create();
765 if (!pdata->ep_lock) {
Paul Cercueil4acd6042015-11-30 12:10:43 +0100766 ERROR("Unable to create mutex\n");
767 ret = -ENOMEM;
768 goto err_destroy_mutex;
769 }
770
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200771 pdata->iiod_client = iiod_client_new(pdata, pdata->lock,
772 &usb_iiod_client_ops);
773 if (!pdata->iiod_client) {
774 ERROR("Unable to create IIOD client\n");
775 ret = -errno;
Paul Cercueil4213a432016-02-09 14:00:40 +0100776 goto err_destroy_ep_mutex;
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200777 }
778
779 ret = libusb_init(&usb_ctx);
780 if (ret) {
Paul Cercueil463fc782015-12-04 16:04:12 +0100781 ret = -(int) libusb_to_errno(ret);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200782 ERROR("Unable to init libusb: %i\n", ret);
Paul Cercueil4acd6042015-11-30 12:10:43 +0100783 goto err_destroy_iiod_client;
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200784 }
785
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100786 libusb_get_device_list(usb_ctx, &device_list);
787
788 usb_dev = NULL;
789
790 for (i = 0; device_list[i]; i++) {
Paul Cercueil0d6fee32016-11-25 11:25:46 +0100791 libusb_device *dev = device_list[i];
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100792
793 if (bus == libusb_get_bus_number(dev) &&
794 address == libusb_get_device_address(dev)) {
795 usb_dev = dev;
Lars-Peter Clausen158bb022017-01-10 18:00:35 +0100796
797 ret = libusb_open(usb_dev, &hdl);
798 /*
799 * Workaround for libusb on Windows >= 8.1. A device
800 * might appear twice in the list with one device being
801 * bogus and only partially initialized. libusb_open()
802 * returns LIBUSB_ERROR_NOT_SUPPORTED for such devices,
803 * which should never happen for normal devices. So if
804 * we find such a device skip it and keep looking.
805 */
806 if (ret == LIBUSB_ERROR_NOT_SUPPORTED) {
807 WARNING("Skipping broken USB device. Please upgrade libusb.\n");
808 usb_dev = NULL;
809 continue;
810 }
811
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100812 break;
813 }
814 }
815
816 libusb_free_device_list(device_list, true);
817
818 if (!usb_dev)
819 goto err_libusb_exit;
820
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100821 if (ret) {
822 ret = -(int) libusb_to_errno(ret);
823 ERROR("Unable to open device\n");
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200824 goto err_libusb_exit;
825 }
826
Robin Getz89c3efd2016-12-26 22:37:12 -0500827#if defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION >= 0x01000016)
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200828 libusb_set_auto_detach_kernel_driver(hdl, true);
Robin Getz89c3efd2016-12-26 22:37:12 -0500829#endif
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200830
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100831 ret = libusb_claim_interface(hdl, interface);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200832 if (ret) {
Paul Cercueil463fc782015-12-04 16:04:12 +0100833 ret = -(int) libusb_to_errno(ret);
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100834 ERROR("Unable to claim interface %u: %i\n", interface, ret);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200835 goto err_libusb_close;
836 }
837
Paul Cercueil4213a432016-02-09 14:00:40 +0100838 ret = libusb_get_active_config_descriptor(usb_dev, &conf_desc);
839 if (ret) {
840 ret = -(int) libusb_to_errno(ret);
841 ERROR("Unable to get config descriptor: %i\n", ret);
842 goto err_libusb_close;
843 }
844
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100845 iface = &conf_desc->interface[interface].altsetting[0];
Paul Cercueil4213a432016-02-09 14:00:40 +0100846
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100847 ret = usb_verify_eps(iface);
848 if (ret) {
Paul Cercueil4213a432016-02-09 14:00:40 +0100849 ERROR("Invalid configuration of endpoints\n");
850 goto err_free_config_descriptor;
851 }
852
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100853 pdata->nb_ep_couples = iface->bNumEndpoints / 2;
Paul Cercueil4213a432016-02-09 14:00:40 +0100854
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100855 DEBUG("Found %hhu usable i/o endpoint couples\n", pdata->nb_ep_couples);
Paul Cercueil4213a432016-02-09 14:00:40 +0100856
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100857 pdata->io_endpoints = calloc(pdata->nb_ep_couples,
858 sizeof(*pdata->io_endpoints));
859 if (!pdata->io_endpoints) {
860 ERROR("Unable to allocate endpoints\n");
861 ret = -ENOMEM;
862 goto err_free_config_descriptor;
863 }
864
865 for (i = 0; i < pdata->nb_ep_couples; i++) {
866 struct iio_usb_ep_couple *ep = &pdata->io_endpoints[i];
867
868 ep->addr_in = iface->endpoint[i * 2 + 0].bEndpointAddress;
869 ep->addr_out = iface->endpoint[i * 2 + 1].bEndpointAddress;
870 ep->pipe_id = i;
871
872 DEBUG("Couple %i with endpoints 0x%x / 0x%x\n", i,
873 ep->addr_in, ep->addr_out);
874
875 ep->lock = iio_mutex_create();
876 if (!ep->lock) {
877 ERROR("Unable to create mutex\n");
Paul Cercueil4213a432016-02-09 14:00:40 +0100878 ret = -ENOMEM;
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100879 goto err_free_endpoints;
Paul Cercueil4213a432016-02-09 14:00:40 +0100880 }
881 }
882
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200883 pdata->ctx = usb_ctx;
884 pdata->hdl = hdl;
Paul Cercueil7a988892015-12-03 12:39:20 +0100885 pdata->timeout_ms = DEFAULT_TIMEOUT_MS;
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100886 pdata->interface = interface;
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200887
Lars-Peter Clausene5c04e02016-06-22 16:52:36 +0200888 ret = usb_io_context_init(&pdata->io_ctx);
889 if (ret)
890 goto err_free_endpoints;
891
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100892 /* We reserve the first I/O endpoint couple for global operations */
893 pdata->io_ctx.ep = &pdata->io_endpoints[0];
Paul Cercueilcd31d842016-11-04 11:24:05 +0100894 pdata->io_ctx.ep->in_use = true;
Lars-Peter Clausenf0d8ff42016-07-04 10:41:53 +0200895
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100896 ret = usb_reset_pipes(pdata);
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100897 if (ret) {
898 iio_strerror(-ret, err_str, sizeof(err_str));
899 ERROR("Failed to reset pipes: %s\n", err_str);
Lars-Peter Clausene5c04e02016-06-22 16:52:36 +0200900 goto err_io_context_exit;
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100901 }
902
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100903 ret = usb_open_pipe(pdata, 0);
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100904 if (ret) {
905 iio_strerror(-ret, err_str, sizeof(err_str));
906 ERROR("Failed to open control pipe: %s\n", err_str);
Lars-Peter Clausene5c04e02016-06-22 16:52:36 +0200907 goto err_io_context_exit;
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100908 }
909
Lars-Peter Clausen2767d4d2016-06-23 14:19:02 +0200910 ctx = iiod_client_create_context(pdata->iiod_client, &pdata->io_ctx);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200911 if (!ctx)
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100912 goto err_reset_pipes;
Paul Cercueil4213a432016-02-09 14:00:40 +0100913
914 libusb_free_config_descriptor(conf_desc);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200915
916 ctx->name = "usb";
917 ctx->ops = &usb_ops;
918 ctx->pdata = pdata;
919
Paul Cercueil4acd6042015-11-30 12:10:43 +0100920 for (i = 0; i < ctx->nb_devices; i++) {
921 struct iio_device *dev = ctx->devices[i];
922
Lars-Peter Clausend1be8382016-02-24 11:13:45 +0100923 dev->pdata = zalloc(sizeof(*dev->pdata));
Paul Cercueil4acd6042015-11-30 12:10:43 +0100924 if (!dev->pdata) {
925 ERROR("Unable to allocate memory\n");
926 ret = -ENOMEM;
927 goto err_context_destroy;
928 }
Lars-Peter Clausene5c04e02016-06-22 16:52:36 +0200929
930 ret = usb_io_context_init(&dev->pdata->io_ctx);
931 if (ret)
932 goto err_context_destroy;
Paul Cercueil4acd6042015-11-30 12:10:43 +0100933 }
934
Paul Cercueilc4751d62016-11-25 11:22:18 +0100935 ret = usb_populate_context_attrs(ctx, usb_dev, hdl);
936 if (ret < 0)
937 goto err_context_destroy;
938
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200939 return ctx;
940
941err_context_destroy:
942 iio_context_destroy(ctx);
943 errno = -ret;
944 return NULL;
945
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100946err_reset_pipes:
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100947 usb_reset_pipes(pdata); /* Close everything */
Lars-Peter Clausene5c04e02016-06-22 16:52:36 +0200948err_io_context_exit:
949 usb_io_context_exit(&pdata->io_ctx);
Paul Cercueil4213a432016-02-09 14:00:40 +0100950err_free_endpoints:
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100951 for (i = 0; i < pdata->nb_ep_couples; i++)
Paul Cercueil4213a432016-02-09 14:00:40 +0100952 if (pdata->io_endpoints[i].lock)
953 iio_mutex_destroy(pdata->io_endpoints[i].lock);
954 if (pdata->io_endpoints)
955 free(pdata->io_endpoints);
956err_free_config_descriptor:
957 libusb_free_config_descriptor(conf_desc);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200958err_libusb_close:
959 libusb_close(hdl);
960err_libusb_exit:
961 libusb_exit(usb_ctx);
962err_destroy_iiod_client:
963 iiod_client_destroy(pdata->iiod_client);
Paul Cercueil4213a432016-02-09 14:00:40 +0100964err_destroy_ep_mutex:
965 iio_mutex_destroy(pdata->ep_lock);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200966err_destroy_mutex:
967 iio_mutex_destroy(pdata->lock);
968err_free_pdata:
969 free(pdata);
970err_set_errno:
971 errno = -ret;
972 return NULL;
973}
Lars-Peter Clausen60f1c9a2016-02-22 13:20:40 +0100974
975struct iio_context * usb_create_context_from_uri(const char *uri)
976{
Paul Cercueil370bb362016-04-20 11:50:10 +0200977 long bus, address, interface;
978 char *end;
979 const char *ptr;
Lars-Peter Clausen60f1c9a2016-02-22 13:20:40 +0100980
981 if (strncmp(uri, "usb:", sizeof("usb:") - 1) != 0)
Paul Cercueil370bb362016-04-20 11:50:10 +0200982 goto err_bad_uri;
Lars-Peter Clausen60f1c9a2016-02-22 13:20:40 +0100983
Paul Cercueil370bb362016-04-20 11:50:10 +0200984 ptr = (const char *) ((uintptr_t) uri + sizeof("usb:") - 1);
985 if (!isdigit(*ptr))
986 goto err_bad_uri;
Lars-Peter Clausen60f1c9a2016-02-22 13:20:40 +0100987
Paul Cercueil370bb362016-04-20 11:50:10 +0200988 bus = strtol(ptr, &end, 10);
989 if (ptr == end || *end != '.')
990 goto err_bad_uri;
991
992 ptr = (const char *) ((uintptr_t) end + 1);
993 if (!isdigit(*ptr))
994 goto err_bad_uri;
995
996 address = strtol(ptr, &end, 10);
Paul Cercueild24f8ac2016-04-20 14:19:29 +0200997 if (ptr == end)
Paul Cercueil370bb362016-04-20 11:50:10 +0200998 goto err_bad_uri;
999
Paul Cercueild24f8ac2016-04-20 14:19:29 +02001000 if (*end == '\0') {
1001 interface = 0;
1002 } else if (*end == '.') {
1003 ptr = (const char *) ((uintptr_t) end + 1);
1004 if (!isdigit(*ptr))
1005 goto err_bad_uri;
Paul Cercueil370bb362016-04-20 11:50:10 +02001006
Paul Cercueild24f8ac2016-04-20 14:19:29 +02001007 interface = strtol(ptr, &end, 10);
1008 if (ptr == end || *end != '\0')
1009 goto err_bad_uri;
1010 } else {
Paul Cercueil370bb362016-04-20 11:50:10 +02001011 goto err_bad_uri;
Paul Cercueild24f8ac2016-04-20 14:19:29 +02001012 }
Paul Cercueil370bb362016-04-20 11:50:10 +02001013
1014 if (bus < 0 || address < 0 || interface < 0)
1015 goto err_bad_uri;
1016
1017 return usb_create_context((unsigned int) bus,
1018 (unsigned int) address, (unsigned int) interface);
1019
1020err_bad_uri:
1021 ERROR("Bad URI: \'%s\'\n", uri);
Paul Cercueilacec87c2016-11-15 14:30:56 +01001022 errno = EINVAL;
Paul Cercueil370bb362016-04-20 11:50:10 +02001023 return NULL;
Lars-Peter Clausen60f1c9a2016-02-22 13:20:40 +01001024}
Lars-Peter Clausen794ba032016-04-25 15:07:00 +02001025
1026static int usb_fill_context_info(struct iio_context_info *info,
1027 struct libusb_device *dev, struct libusb_device_handle *hdl,
1028 unsigned int interface)
1029{
1030 struct libusb_device_descriptor desc;
Michael Hennerich75c13382016-11-15 13:12:51 +01001031 char manufacturer[64], product[64], serial[64];
Lars-Peter Clausen794ba032016-04-25 15:07:00 +02001032 char uri[sizeof("usb:127.255.255")];
1033 char description[sizeof(manufacturer) + sizeof(product) +
Michael Hennerich75c13382016-11-15 13:12:51 +01001034 sizeof(serial) + sizeof("0000:0000 ( ), serial=")];
Lars-Peter Clausen794ba032016-04-25 15:07:00 +02001035 int ret;
1036
1037 libusb_get_device_descriptor(dev, &desc);
1038
Paul Cercueil9c9a5562017-01-24 10:48:31 +01001039 iio_snprintf(uri, sizeof(uri), "usb:%d.%d.%u",
Lars-Peter Clausen794ba032016-04-25 15:07:00 +02001040 libusb_get_bus_number(dev), libusb_get_device_address(dev),
1041 interface);
1042
1043 if (desc.iManufacturer == 0) {
1044 manufacturer[0] = '\0';
1045 } else {
1046 ret = libusb_get_string_descriptor_ascii(hdl,
1047 desc.iManufacturer,
1048 (unsigned char *) manufacturer,
1049 sizeof(manufacturer));
1050 if (ret < 0)
1051 manufacturer[0] = '\0';
1052 }
1053
1054 if (desc.iProduct == 0) {
1055 product[0] = '\0';
1056 } else {
1057 ret = libusb_get_string_descriptor_ascii(hdl,
1058 desc.iProduct, (unsigned char *) product,
1059 sizeof(product));
1060 if (ret < 0)
1061 product[0] = '\0';
1062 }
1063
Michael Hennerich75c13382016-11-15 13:12:51 +01001064 if (desc.iSerialNumber == 0) {
1065 serial[0] = '\0';
1066 } else {
1067 ret = libusb_get_string_descriptor_ascii(hdl,
1068 desc.iSerialNumber, (unsigned char *) serial,
1069 sizeof(serial));
1070 if (ret < 0)
1071 serial[0] = '\0';
1072 }
1073
Paul Cercueil9c9a5562017-01-24 10:48:31 +01001074 iio_snprintf(description, sizeof(description),
Michael Hennerich75c13382016-11-15 13:12:51 +01001075 "%04x:%04x (%s %s), serial=%s", desc.idVendor,
1076 desc.idProduct, manufacturer, product, serial);
Lars-Peter Clausen794ba032016-04-25 15:07:00 +02001077
Paul Cercueilcaf0e712016-08-25 17:27:02 +02001078 info->uri = iio_strdup(uri);
Lars-Peter Clausen794ba032016-04-25 15:07:00 +02001079 if (!info->uri)
1080 return -ENOMEM;
1081
Paul Cercueilcaf0e712016-08-25 17:27:02 +02001082 info->description = iio_strdup(description);
Lars-Peter Clausen794ba032016-04-25 15:07:00 +02001083 if (!info->description)
1084 return -ENOMEM;
1085
1086 return 0;
1087}
1088
1089struct iio_scan_backend_context {
1090 libusb_context *ctx;
1091};
1092
1093struct iio_scan_backend_context * usb_context_scan_init(void)
1094{
1095 struct iio_scan_backend_context *ctx;
1096 int ret;
1097
1098 ctx = malloc(sizeof(*ctx));
1099 if (!ctx) {
1100 errno = ENOMEM;
1101 return NULL;
1102 }
1103
1104 ret = libusb_init(&ctx->ctx);
1105 if (ret) {
1106 free(ctx);
1107 errno = (int) libusb_to_errno(ret);
1108 return NULL;
1109 }
1110
1111 return ctx;
1112}
1113
1114void usb_context_scan_free(struct iio_scan_backend_context *ctx)
1115{
1116 libusb_exit(ctx->ctx);
1117 free(ctx);
1118}
1119
1120int usb_context_scan(struct iio_scan_backend_context *ctx,
1121 struct iio_scan_result *scan_result)
1122{
1123 struct iio_context_info **info;
1124 libusb_device **device_list;
1125 unsigned int i;
1126 int ret;
1127
1128 ret = libusb_get_device_list(ctx->ctx, &device_list);
1129 if (ret < 0)
1130 return -(int) libusb_to_errno(ret);
1131
1132 for (i = 0; device_list[i]; i++) {
1133 struct libusb_device_handle *hdl;
1134 struct libusb_device *dev = device_list[i];
1135 unsigned int interface = 0;
1136
1137 ret = libusb_open(dev, &hdl);
1138 if (ret)
1139 continue;
1140
1141 if (!iio_usb_match_device(dev, hdl, &interface)) {
1142 info = iio_scan_result_add(scan_result, 1);
1143 if (!info)
1144 ret = -ENOMEM;
1145 else
1146 ret = usb_fill_context_info(*info, dev, hdl,
1147 interface);
1148 }
1149
1150 libusb_close(hdl);
1151 if (ret < 0)
1152 goto cleanup_free_device_list;
1153 }
1154
1155 ret = 0;
1156
1157cleanup_free_device_list:
1158 libusb_free_device_list(device_list, true);
1159 return ret;
1160}