blob: 49af0ccc2f403764fd31c5609d071d552998cb97 [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>
Robin Getz549bc7a2020-01-17 14:40:33 -050025#include <libusb.h>
Paul Cercueile06f4ce2015-04-20 12:59:31 +020026#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 Clausen2f231e22018-10-25 11:11:23 +0200153#define USB_PIPE_CTRL_TIMEOUT 1000 /* These should not take long */
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100154
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
Robin Getz3c94d762018-10-25 12:40:13 -0400743#ifdef HAS_LIBUSB_GETVERSION
744 /*
745 * libusb_get_version was added 2012-04-17: v1.0.10,
746 * before LIBUSB_API_VERSION was added - Jan 8, 2014
747 * so, you can't use that to determine if it is here
748 */
749 {
750 struct libusb_version const *ver = libusb_get_version();
751 iio_snprintf(buffer, sizeof(buffer), "%i.%i.%i.%i%s",
752 ver->major, ver->minor, ver->micro,
753 ver->nano, ver->rc);
754 ret = iio_context_add_attr(ctx, "usb,libusb", buffer);
755 if (ret < 0)
756 return ret;
757 }
758#endif
Paul Cercueilc4751d62016-11-25 11:22:18 +0100759 return 0;
760}
761
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100762struct iio_context * usb_create_context(unsigned int bus,
763 unsigned int address, unsigned int interface)
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200764{
765 libusb_context *usb_ctx;
766 libusb_device_handle *hdl;
Paul Cercueil4213a432016-02-09 14:00:40 +0100767 const struct libusb_interface_descriptor *iface;
Paul Cercueil0d6fee32016-11-25 11:25:46 +0100768 libusb_device *usb_dev;
Paul Cercueil4213a432016-02-09 14:00:40 +0100769 struct libusb_config_descriptor *conf_desc;
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100770 libusb_device **device_list;
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200771 struct iio_context *ctx;
772 struct iio_context_pdata *pdata;
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100773 char err_str[1024];
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200774 unsigned int i;
775 int ret;
776
Lars-Peter Clausend1be8382016-02-24 11:13:45 +0100777 pdata = zalloc(sizeof(*pdata));
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200778 if (!pdata) {
779 ERROR("Unable to allocate pdata\n");
780 ret = -ENOMEM;
781 goto err_set_errno;
782 }
783
784 pdata->lock = iio_mutex_create();
785 if (!pdata->lock) {
786 ERROR("Unable to create mutex\n");
787 ret = -ENOMEM;
788 goto err_free_pdata;
789 }
790
Paul Cercueil4213a432016-02-09 14:00:40 +0100791 pdata->ep_lock = iio_mutex_create();
792 if (!pdata->ep_lock) {
Paul Cercueil4acd6042015-11-30 12:10:43 +0100793 ERROR("Unable to create mutex\n");
794 ret = -ENOMEM;
795 goto err_destroy_mutex;
796 }
797
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200798 pdata->iiod_client = iiod_client_new(pdata, pdata->lock,
799 &usb_iiod_client_ops);
800 if (!pdata->iiod_client) {
801 ERROR("Unable to create IIOD client\n");
802 ret = -errno;
Paul Cercueil4213a432016-02-09 14:00:40 +0100803 goto err_destroy_ep_mutex;
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200804 }
805
806 ret = libusb_init(&usb_ctx);
807 if (ret) {
Paul Cercueil463fc782015-12-04 16:04:12 +0100808 ret = -(int) libusb_to_errno(ret);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200809 ERROR("Unable to init libusb: %i\n", ret);
Paul Cercueil4acd6042015-11-30 12:10:43 +0100810 goto err_destroy_iiod_client;
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200811 }
812
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100813 libusb_get_device_list(usb_ctx, &device_list);
814
815 usb_dev = NULL;
816
817 for (i = 0; device_list[i]; i++) {
Paul Cercueil0d6fee32016-11-25 11:25:46 +0100818 libusb_device *dev = device_list[i];
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100819
820 if (bus == libusb_get_bus_number(dev) &&
821 address == libusb_get_device_address(dev)) {
822 usb_dev = dev;
Lars-Peter Clausen158bb022017-01-10 18:00:35 +0100823
824 ret = libusb_open(usb_dev, &hdl);
825 /*
826 * Workaround for libusb on Windows >= 8.1. A device
827 * might appear twice in the list with one device being
828 * bogus and only partially initialized. libusb_open()
829 * returns LIBUSB_ERROR_NOT_SUPPORTED for such devices,
830 * which should never happen for normal devices. So if
831 * we find such a device skip it and keep looking.
832 */
833 if (ret == LIBUSB_ERROR_NOT_SUPPORTED) {
834 WARNING("Skipping broken USB device. Please upgrade libusb.\n");
835 usb_dev = NULL;
836 continue;
837 }
838
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100839 break;
840 }
841 }
842
843 libusb_free_device_list(device_list, true);
844
Paul Cercueil7f6c90c2017-02-14 13:55:27 +0100845 if (!usb_dev) {
846 ret = -ENODEV;
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100847 goto err_libusb_exit;
Paul Cercueil7f6c90c2017-02-14 13:55:27 +0100848 }
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100849
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100850 if (ret) {
851 ret = -(int) libusb_to_errno(ret);
852 ERROR("Unable to open device\n");
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200853 goto err_libusb_exit;
854 }
855
Robin Getz89c3efd2016-12-26 22:37:12 -0500856#if defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION >= 0x01000016)
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200857 libusb_set_auto_detach_kernel_driver(hdl, true);
Robin Getz89c3efd2016-12-26 22:37:12 -0500858#endif
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200859
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100860 ret = libusb_claim_interface(hdl, interface);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200861 if (ret) {
Paul Cercueil463fc782015-12-04 16:04:12 +0100862 ret = -(int) libusb_to_errno(ret);
Robin Getz0855fd82018-10-26 10:56:30 -0400863 ERROR("Unable to claim interface %u:%u:%u: %i\n",
864 bus, address, interface, ret);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200865 goto err_libusb_close;
866 }
867
Paul Cercueil4213a432016-02-09 14:00:40 +0100868 ret = libusb_get_active_config_descriptor(usb_dev, &conf_desc);
869 if (ret) {
870 ret = -(int) libusb_to_errno(ret);
871 ERROR("Unable to get config descriptor: %i\n", ret);
872 goto err_libusb_close;
873 }
874
Lars-Peter Clausen7a8e6b52016-02-22 13:25:12 +0100875 iface = &conf_desc->interface[interface].altsetting[0];
Paul Cercueil4213a432016-02-09 14:00:40 +0100876
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100877 ret = usb_verify_eps(iface);
878 if (ret) {
Paul Cercueil4213a432016-02-09 14:00:40 +0100879 ERROR("Invalid configuration of endpoints\n");
880 goto err_free_config_descriptor;
881 }
882
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100883 pdata->nb_ep_couples = iface->bNumEndpoints / 2;
Paul Cercueil4213a432016-02-09 14:00:40 +0100884
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100885 DEBUG("Found %hhu usable i/o endpoint couples\n", pdata->nb_ep_couples);
Paul Cercueil4213a432016-02-09 14:00:40 +0100886
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100887 pdata->io_endpoints = calloc(pdata->nb_ep_couples,
888 sizeof(*pdata->io_endpoints));
889 if (!pdata->io_endpoints) {
890 ERROR("Unable to allocate endpoints\n");
891 ret = -ENOMEM;
892 goto err_free_config_descriptor;
893 }
894
895 for (i = 0; i < pdata->nb_ep_couples; i++) {
896 struct iio_usb_ep_couple *ep = &pdata->io_endpoints[i];
897
898 ep->addr_in = iface->endpoint[i * 2 + 0].bEndpointAddress;
899 ep->addr_out = iface->endpoint[i * 2 + 1].bEndpointAddress;
900 ep->pipe_id = i;
901
902 DEBUG("Couple %i with endpoints 0x%x / 0x%x\n", i,
903 ep->addr_in, ep->addr_out);
904
905 ep->lock = iio_mutex_create();
906 if (!ep->lock) {
907 ERROR("Unable to create mutex\n");
Paul Cercueil4213a432016-02-09 14:00:40 +0100908 ret = -ENOMEM;
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100909 goto err_free_endpoints;
Paul Cercueil4213a432016-02-09 14:00:40 +0100910 }
911 }
912
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200913 pdata->ctx = usb_ctx;
914 pdata->hdl = hdl;
Paul Cercueil7a988892015-12-03 12:39:20 +0100915 pdata->timeout_ms = DEFAULT_TIMEOUT_MS;
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100916 pdata->interface = interface;
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200917
Lars-Peter Clausene5c04e02016-06-22 16:52:36 +0200918 ret = usb_io_context_init(&pdata->io_ctx);
919 if (ret)
920 goto err_free_endpoints;
921
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100922 /* We reserve the first I/O endpoint couple for global operations */
923 pdata->io_ctx.ep = &pdata->io_endpoints[0];
Paul Cercueilcd31d842016-11-04 11:24:05 +0100924 pdata->io_ctx.ep->in_use = true;
Lars-Peter Clausenf0d8ff42016-07-04 10:41:53 +0200925
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100926 ret = usb_reset_pipes(pdata);
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100927 if (ret) {
928 iio_strerror(-ret, err_str, sizeof(err_str));
929 ERROR("Failed to reset pipes: %s\n", err_str);
Lars-Peter Clausene5c04e02016-06-22 16:52:36 +0200930 goto err_io_context_exit;
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100931 }
932
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100933 ret = usb_open_pipe(pdata, 0);
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100934 if (ret) {
935 iio_strerror(-ret, err_str, sizeof(err_str));
936 ERROR("Failed to open control pipe: %s\n", err_str);
Lars-Peter Clausene5c04e02016-06-22 16:52:36 +0200937 goto err_io_context_exit;
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100938 }
939
Lars-Peter Clausen2767d4d2016-06-23 14:19:02 +0200940 ctx = iiod_client_create_context(pdata->iiod_client, &pdata->io_ctx);
Paul Cercueilac5450a2017-01-27 18:34:56 +0100941 if (!ctx) {
942 ret = -errno;
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100943 goto err_reset_pipes;
Paul Cercueilac5450a2017-01-27 18:34:56 +0100944 }
Paul Cercueil4213a432016-02-09 14:00:40 +0100945
946 libusb_free_config_descriptor(conf_desc);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200947
948 ctx->name = "usb";
949 ctx->ops = &usb_ops;
950 ctx->pdata = pdata;
951
Paul Cercueil4acd6042015-11-30 12:10:43 +0100952 for (i = 0; i < ctx->nb_devices; i++) {
953 struct iio_device *dev = ctx->devices[i];
954
Lars-Peter Clausend1be8382016-02-24 11:13:45 +0100955 dev->pdata = zalloc(sizeof(*dev->pdata));
Paul Cercueil4acd6042015-11-30 12:10:43 +0100956 if (!dev->pdata) {
957 ERROR("Unable to allocate memory\n");
958 ret = -ENOMEM;
959 goto err_context_destroy;
960 }
Lars-Peter Clausene5c04e02016-06-22 16:52:36 +0200961
962 ret = usb_io_context_init(&dev->pdata->io_ctx);
963 if (ret)
964 goto err_context_destroy;
Paul Cercueil4acd6042015-11-30 12:10:43 +0100965 }
966
Paul Cercueilc4751d62016-11-25 11:22:18 +0100967 ret = usb_populate_context_attrs(ctx, usb_dev, hdl);
968 if (ret < 0)
969 goto err_context_destroy;
970
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200971 return ctx;
972
973err_context_destroy:
974 iio_context_destroy(ctx);
975 errno = -ret;
976 return NULL;
977
Lars-Peter Clausen2eba3632016-03-08 14:33:21 +0100978err_reset_pipes:
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100979 usb_reset_pipes(pdata); /* Close everything */
Lars-Peter Clausene5c04e02016-06-22 16:52:36 +0200980err_io_context_exit:
981 usb_io_context_exit(&pdata->io_ctx);
Paul Cercueil4213a432016-02-09 14:00:40 +0100982err_free_endpoints:
Paul Cercueilbb10bd42016-10-31 15:31:36 +0100983 for (i = 0; i < pdata->nb_ep_couples; i++)
Paul Cercueil4213a432016-02-09 14:00:40 +0100984 if (pdata->io_endpoints[i].lock)
985 iio_mutex_destroy(pdata->io_endpoints[i].lock);
986 if (pdata->io_endpoints)
987 free(pdata->io_endpoints);
988err_free_config_descriptor:
989 libusb_free_config_descriptor(conf_desc);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200990err_libusb_close:
991 libusb_close(hdl);
992err_libusb_exit:
993 libusb_exit(usb_ctx);
994err_destroy_iiod_client:
995 iiod_client_destroy(pdata->iiod_client);
Paul Cercueil4213a432016-02-09 14:00:40 +0100996err_destroy_ep_mutex:
997 iio_mutex_destroy(pdata->ep_lock);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200998err_destroy_mutex:
999 iio_mutex_destroy(pdata->lock);
1000err_free_pdata:
1001 free(pdata);
1002err_set_errno:
1003 errno = -ret;
1004 return NULL;
1005}
Lars-Peter Clausen60f1c9a2016-02-22 13:20:40 +01001006
1007struct iio_context * usb_create_context_from_uri(const char *uri)
1008{
Paul Cercueil370bb362016-04-20 11:50:10 +02001009 long bus, address, interface;
1010 char *end;
1011 const char *ptr;
Lars-Peter Clausen60f1c9a2016-02-22 13:20:40 +01001012
1013 if (strncmp(uri, "usb:", sizeof("usb:") - 1) != 0)
Paul Cercueil370bb362016-04-20 11:50:10 +02001014 goto err_bad_uri;
Lars-Peter Clausen60f1c9a2016-02-22 13:20:40 +01001015
Paul Cercueil370bb362016-04-20 11:50:10 +02001016 ptr = (const char *) ((uintptr_t) uri + sizeof("usb:") - 1);
1017 if (!isdigit(*ptr))
1018 goto err_bad_uri;
Lars-Peter Clausen60f1c9a2016-02-22 13:20:40 +01001019
Paul Cercueil370bb362016-04-20 11:50:10 +02001020 bus = strtol(ptr, &end, 10);
1021 if (ptr == end || *end != '.')
1022 goto err_bad_uri;
1023
1024 ptr = (const char *) ((uintptr_t) end + 1);
1025 if (!isdigit(*ptr))
1026 goto err_bad_uri;
1027
1028 address = strtol(ptr, &end, 10);
Paul Cercueild24f8ac2016-04-20 14:19:29 +02001029 if (ptr == end)
Paul Cercueil370bb362016-04-20 11:50:10 +02001030 goto err_bad_uri;
1031
Paul Cercueild24f8ac2016-04-20 14:19:29 +02001032 if (*end == '\0') {
1033 interface = 0;
1034 } else if (*end == '.') {
1035 ptr = (const char *) ((uintptr_t) end + 1);
1036 if (!isdigit(*ptr))
1037 goto err_bad_uri;
Paul Cercueil370bb362016-04-20 11:50:10 +02001038
Paul Cercueild24f8ac2016-04-20 14:19:29 +02001039 interface = strtol(ptr, &end, 10);
1040 if (ptr == end || *end != '\0')
1041 goto err_bad_uri;
1042 } else {
Paul Cercueil370bb362016-04-20 11:50:10 +02001043 goto err_bad_uri;
Paul Cercueild24f8ac2016-04-20 14:19:29 +02001044 }
Paul Cercueil370bb362016-04-20 11:50:10 +02001045
1046 if (bus < 0 || address < 0 || interface < 0)
1047 goto err_bad_uri;
1048
1049 return usb_create_context((unsigned int) bus,
1050 (unsigned int) address, (unsigned int) interface);
1051
1052err_bad_uri:
1053 ERROR("Bad URI: \'%s\'\n", uri);
Paul Cercueilacec87c2016-11-15 14:30:56 +01001054 errno = EINVAL;
Paul Cercueil370bb362016-04-20 11:50:10 +02001055 return NULL;
Lars-Peter Clausen60f1c9a2016-02-22 13:20:40 +01001056}
Lars-Peter Clausen794ba032016-04-25 15:07:00 +02001057
1058static int usb_fill_context_info(struct iio_context_info *info,
1059 struct libusb_device *dev, struct libusb_device_handle *hdl,
1060 unsigned int interface)
1061{
1062 struct libusb_device_descriptor desc;
Michael Hennerich75c13382016-11-15 13:12:51 +01001063 char manufacturer[64], product[64], serial[64];
Lars-Peter Clausen794ba032016-04-25 15:07:00 +02001064 char uri[sizeof("usb:127.255.255")];
1065 char description[sizeof(manufacturer) + sizeof(product) +
Michael Hennerich75c13382016-11-15 13:12:51 +01001066 sizeof(serial) + sizeof("0000:0000 ( ), serial=")];
Lars-Peter Clausen794ba032016-04-25 15:07:00 +02001067 int ret;
1068
1069 libusb_get_device_descriptor(dev, &desc);
1070
Paul Cercueil9c9a5562017-01-24 10:48:31 +01001071 iio_snprintf(uri, sizeof(uri), "usb:%d.%d.%u",
Lars-Peter Clausen794ba032016-04-25 15:07:00 +02001072 libusb_get_bus_number(dev), libusb_get_device_address(dev),
1073 interface);
1074
1075 if (desc.iManufacturer == 0) {
1076 manufacturer[0] = '\0';
1077 } else {
1078 ret = libusb_get_string_descriptor_ascii(hdl,
1079 desc.iManufacturer,
1080 (unsigned char *) manufacturer,
1081 sizeof(manufacturer));
1082 if (ret < 0)
1083 manufacturer[0] = '\0';
1084 }
1085
1086 if (desc.iProduct == 0) {
1087 product[0] = '\0';
1088 } else {
1089 ret = libusb_get_string_descriptor_ascii(hdl,
1090 desc.iProduct, (unsigned char *) product,
1091 sizeof(product));
1092 if (ret < 0)
1093 product[0] = '\0';
1094 }
1095
Michael Hennerich75c13382016-11-15 13:12:51 +01001096 if (desc.iSerialNumber == 0) {
1097 serial[0] = '\0';
1098 } else {
1099 ret = libusb_get_string_descriptor_ascii(hdl,
1100 desc.iSerialNumber, (unsigned char *) serial,
1101 sizeof(serial));
1102 if (ret < 0)
1103 serial[0] = '\0';
1104 }
1105
Paul Cercueil9c9a5562017-01-24 10:48:31 +01001106 iio_snprintf(description, sizeof(description),
Michael Hennerich75c13382016-11-15 13:12:51 +01001107 "%04x:%04x (%s %s), serial=%s", desc.idVendor,
1108 desc.idProduct, manufacturer, product, serial);
Lars-Peter Clausen794ba032016-04-25 15:07:00 +02001109
Paul Cercueilcaf0e712016-08-25 17:27:02 +02001110 info->uri = iio_strdup(uri);
Lars-Peter Clausen794ba032016-04-25 15:07:00 +02001111 if (!info->uri)
1112 return -ENOMEM;
1113
Paul Cercueilcaf0e712016-08-25 17:27:02 +02001114 info->description = iio_strdup(description);
Lars-Peter Clausen794ba032016-04-25 15:07:00 +02001115 if (!info->description)
1116 return -ENOMEM;
1117
1118 return 0;
1119}
1120
1121struct iio_scan_backend_context {
1122 libusb_context *ctx;
1123};
1124
1125struct iio_scan_backend_context * usb_context_scan_init(void)
1126{
1127 struct iio_scan_backend_context *ctx;
1128 int ret;
1129
1130 ctx = malloc(sizeof(*ctx));
1131 if (!ctx) {
1132 errno = ENOMEM;
1133 return NULL;
1134 }
1135
1136 ret = libusb_init(&ctx->ctx);
1137 if (ret) {
1138 free(ctx);
1139 errno = (int) libusb_to_errno(ret);
1140 return NULL;
1141 }
1142
1143 return ctx;
1144}
1145
1146void usb_context_scan_free(struct iio_scan_backend_context *ctx)
1147{
1148 libusb_exit(ctx->ctx);
1149 free(ctx);
1150}
1151
1152int usb_context_scan(struct iio_scan_backend_context *ctx,
1153 struct iio_scan_result *scan_result)
1154{
1155 struct iio_context_info **info;
1156 libusb_device **device_list;
1157 unsigned int i;
1158 int ret;
1159
1160 ret = libusb_get_device_list(ctx->ctx, &device_list);
1161 if (ret < 0)
1162 return -(int) libusb_to_errno(ret);
1163
1164 for (i = 0; device_list[i]; i++) {
1165 struct libusb_device_handle *hdl;
1166 struct libusb_device *dev = device_list[i];
1167 unsigned int interface = 0;
1168
1169 ret = libusb_open(dev, &hdl);
1170 if (ret)
1171 continue;
1172
1173 if (!iio_usb_match_device(dev, hdl, &interface)) {
1174 info = iio_scan_result_add(scan_result, 1);
1175 if (!info)
1176 ret = -ENOMEM;
1177 else
1178 ret = usb_fill_context_info(*info, dev, hdl,
1179 interface);
1180 }
1181
1182 libusb_close(hdl);
1183 if (ret < 0)
1184 goto cleanup_free_device_list;
1185 }
1186
1187 ret = 0;
1188
1189cleanup_free_device_list:
1190 libusb_free_device_list(device_list, true);
1191 return ret;
1192}