blob: 9946a7fa0a43f98c6cc9030940536d0fa12ab02d [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
23#include <errno.h>
24#include <libusb-1.0/libusb.h>
25#include <stdbool.h>
26#include <string.h>
27
Paul Cercueil3c1e7852015-12-04 16:14:28 +010028#ifdef ERROR
29#undef ERROR
30#endif
31
32#include "debug.h"
33
Paul Cercueile06f4ce2015-04-20 12:59:31 +020034#define DEFAULT_TIMEOUT_MS 5000
35
36/* Endpoint for non-streaming operations */
37#define EP_OPS 1
38
Paul Cercueil4213a432016-02-09 14:00:40 +010039struct iio_usb_io_endpoint {
40 unsigned char address;
41 bool in_use;
Paul Cercueil4acd6042015-11-30 12:10:43 +010042
Paul Cercueil4213a432016-02-09 14:00:40 +010043 struct iio_mutex *lock;
44};
Paul Cercueil4acd6042015-11-30 12:10:43 +010045
Paul Cercueile06f4ce2015-04-20 12:59:31 +020046struct iio_context_pdata {
47 libusb_context *ctx;
48 libusb_device_handle *hdl;
49
50 struct iiod_client *iiod_client;
51
52 /* Lock for non-streaming operations */
53 struct iio_mutex *lock;
Paul Cercueil4acd6042015-11-30 12:10:43 +010054
Paul Cercueil4213a432016-02-09 14:00:40 +010055 /* Lock for endpoint reservation */
56 struct iio_mutex *ep_lock;
57
58 struct iio_usb_io_endpoint *io_endpoints;
59 unsigned int nb_io_endpoints;
Paul Cercueil7a988892015-12-03 12:39:20 +010060
61 unsigned int timeout_ms;
Paul Cercueil4acd6042015-11-30 12:10:43 +010062};
63
64struct iio_device_pdata {
65 bool is_tx;
66 struct iio_mutex *lock;
67
68 bool opened;
69 unsigned int ep;
Paul Cercueile06f4ce2015-04-20 12:59:31 +020070};
71
72static const unsigned int libusb_to_errno_codes[] = {
73 [- LIBUSB_ERROR_INVALID_PARAM] = EINVAL,
74 [- LIBUSB_ERROR_ACCESS] = EACCES,
75 [- LIBUSB_ERROR_NO_DEVICE] = ENODEV,
76 [- LIBUSB_ERROR_NOT_FOUND] = ENXIO,
77 [- LIBUSB_ERROR_BUSY] = EBUSY,
78 [- LIBUSB_ERROR_TIMEOUT] = ETIMEDOUT,
79 [- LIBUSB_ERROR_OVERFLOW] = EIO,
80 [- LIBUSB_ERROR_PIPE] = EPIPE,
81 [- LIBUSB_ERROR_INTERRUPTED] = EINTR,
82 [- LIBUSB_ERROR_NO_MEM] = ENOMEM,
83 [- LIBUSB_ERROR_NOT_SUPPORTED] = ENOSYS,
84};
85
86static unsigned int libusb_to_errno(int error)
87{
88 switch ((enum libusb_error) error) {
89 case LIBUSB_ERROR_INVALID_PARAM:
90 case LIBUSB_ERROR_ACCESS:
91 case LIBUSB_ERROR_NO_DEVICE:
92 case LIBUSB_ERROR_NOT_FOUND:
93 case LIBUSB_ERROR_BUSY:
94 case LIBUSB_ERROR_TIMEOUT:
95 case LIBUSB_ERROR_PIPE:
96 case LIBUSB_ERROR_INTERRUPTED:
97 case LIBUSB_ERROR_NO_MEM:
98 case LIBUSB_ERROR_NOT_SUPPORTED:
99 return libusb_to_errno_codes[- (int) error];
100 case LIBUSB_ERROR_IO:
101 case LIBUSB_ERROR_OTHER:
102 case LIBUSB_ERROR_OVERFLOW:
103 default:
104 return EIO;
105 }
106}
107
Paul Cercueilc11737c2015-11-26 14:44:46 +0100108static int usb_get_version(const struct iio_context *ctx,
109 unsigned int *major, unsigned int *minor, char git_tag[8])
110{
111 return iiod_client_get_version(ctx->pdata->iiod_client,
112 EP_OPS, major, minor, git_tag);
113}
114
Paul Cercueila5e4aa42016-02-09 13:31:01 +0100115static unsigned int usb_calculate_remote_timeout(unsigned int timeout)
116{
117 /* XXX(pcercuei): We currently hardcode timeout / 2 for the backend used
118 * by the remote. Is there something better to do here? */
119 return timeout / 2;
120}
121
Paul Cercueil4213a432016-02-09 14:00:40 +0100122static int usb_reserve_ep_unlocked(const struct iio_device *dev)
123{
124 struct iio_context_pdata *pdata = dev->ctx->pdata;
125 unsigned int i;
126
127 for (i = 0; i < pdata->nb_io_endpoints; i++) {
128 struct iio_usb_io_endpoint *ep = &pdata->io_endpoints[i];
129
130 if (!ep->in_use) {
131 ep->in_use = true;
132
133 dev->pdata->ep = ep->address;
134 dev->pdata->lock = ep->lock;
135 return 0;
136 }
137 }
138
139 return -EBUSY;
140}
141
142static void usb_free_ep_unlocked(const struct iio_device *dev)
143{
144 struct iio_context_pdata *pdata = dev->ctx->pdata;
145 unsigned int i;
146
147 for (i = 0; i < pdata->nb_io_endpoints; i++) {
148 struct iio_usb_io_endpoint *ep = &pdata->io_endpoints[i];
149
150 if (ep->lock == dev->pdata->lock) {
151 ep->in_use = false;
152 return;
153 }
154 }
155}
156
Paul Cercueil4acd6042015-11-30 12:10:43 +0100157static int usb_open(const struct iio_device *dev,
158 size_t samples_count, bool cyclic)
159{
Paul Cercueila5e4aa42016-02-09 13:31:01 +0100160 struct iio_context_pdata *ctx_pdata = dev->ctx->pdata;
Paul Cercueil4acd6042015-11-30 12:10:43 +0100161 struct iio_device_pdata *pdata = dev->pdata;
162 int ret = -EBUSY;
163
Paul Cercueil4213a432016-02-09 14:00:40 +0100164 iio_mutex_lock(ctx_pdata->ep_lock);
Paul Cercueil4acd6042015-11-30 12:10:43 +0100165
Paul Cercueila5e4aa42016-02-09 13:31:01 +0100166 if (pdata->opened)
167 goto out_unlock;
168
Paul Cercueil4213a432016-02-09 14:00:40 +0100169 ret = usb_reserve_ep_unlocked(dev);
170 if (ret)
171 goto out_unlock;
172
173 iio_mutex_lock(pdata->lock);
174
Paul Cercueila5e4aa42016-02-09 13:31:01 +0100175 ret = iiod_client_open_unlocked(ctx_pdata->iiod_client,
176 pdata->ep, dev, samples_count, cyclic);
177
178 if (!ret) {
179 unsigned int remote_timeout =
180 usb_calculate_remote_timeout(ctx_pdata->timeout_ms);
181
182 ret = iiod_client_set_timeout(ctx_pdata->iiod_client,
183 pdata->ep, remote_timeout);
Paul Cercueil4acd6042015-11-30 12:10:43 +0100184 }
185
Paul Cercueila5e4aa42016-02-09 13:31:01 +0100186 pdata->opened = !ret;
187
Paul Cercueil4acd6042015-11-30 12:10:43 +0100188 iio_mutex_unlock(pdata->lock);
Paul Cercueil4213a432016-02-09 14:00:40 +0100189
190 if (ret)
191 usb_free_ep_unlocked(dev);
192
193out_unlock:
194 iio_mutex_unlock(ctx_pdata->ep_lock);
Paul Cercueil4acd6042015-11-30 12:10:43 +0100195 return ret;
196}
197
198static int usb_close(const struct iio_device *dev)
199{
Paul Cercueil4213a432016-02-09 14:00:40 +0100200 struct iio_context_pdata *ctx_pdata = dev->ctx->pdata;
Paul Cercueil4acd6042015-11-30 12:10:43 +0100201 struct iio_device_pdata *pdata = dev->pdata;
202 int ret = -EBADF;
203
Paul Cercueil4213a432016-02-09 14:00:40 +0100204 iio_mutex_lock(ctx_pdata->ep_lock);
205 if (!pdata->opened)
206 goto out_unlock;
Paul Cercueil4acd6042015-11-30 12:10:43 +0100207
Paul Cercueil4213a432016-02-09 14:00:40 +0100208 iio_mutex_lock(pdata->lock);
209 ret = iiod_client_close_unlocked(ctx_pdata->iiod_client,
210 pdata->ep, dev);
211 pdata->opened = false;
212
213 usb_free_ep_unlocked(dev);
214
215out_unlock:
216 iio_mutex_unlock(ctx_pdata->ep_lock);
Paul Cercueil4acd6042015-11-30 12:10:43 +0100217 return ret;
218}
219
Paul Cercueil04841832015-12-02 11:58:33 +0100220static ssize_t usb_read(const struct iio_device *dev, void *dst, size_t len,
221 uint32_t *mask, size_t words)
222{
223 struct iio_device_pdata *pdata = dev->pdata;
224 ssize_t ret;
225
226 iio_mutex_lock(pdata->lock);
227 ret = iiod_client_read_unlocked(dev->ctx->pdata->iiod_client,
228 pdata->ep, dev, dst, len, mask, words);
229 iio_mutex_unlock(pdata->lock);
230
231 return ret;
232}
233
Paul Cercueile78e9882015-12-04 16:31:10 +0100234static ssize_t usb_write(const struct iio_device *dev,
235 const void *src, size_t len)
236{
237 struct iio_device_pdata *pdata = dev->pdata;
238 ssize_t ret;
239
240 iio_mutex_lock(pdata->lock);
241 ret = iiod_client_write_unlocked(dev->ctx->pdata->iiod_client,
242 pdata->ep, dev, src, len);
243 iio_mutex_unlock(pdata->lock);
244
245 return ret;
246}
247
Paul Cercueil3069e3b2015-11-26 16:01:25 +0100248static ssize_t usb_read_dev_attr(const struct iio_device *dev,
249 const char *attr, char *dst, size_t len, bool is_debug)
250{
251 struct iio_context_pdata *pdata = dev->ctx->pdata;
252
253 return iiod_client_read_attr(pdata->iiod_client, EP_OPS, dev,
254 NULL, attr, dst, len, is_debug);
255}
256
257static ssize_t usb_write_dev_attr(const struct iio_device *dev,
258 const char *attr, const char *src, size_t len, bool is_debug)
259{
260 struct iio_context_pdata *pdata = dev->ctx->pdata;
261
262 return iiod_client_write_attr(pdata->iiod_client, EP_OPS, dev,
263 NULL, attr, src, len, is_debug);
264}
265
266static ssize_t usb_read_chn_attr(const struct iio_channel *chn,
267 const char *attr, char *dst, size_t len)
268{
269 struct iio_context_pdata *pdata = chn->dev->ctx->pdata;
270
271 return iiod_client_read_attr(pdata->iiod_client, EP_OPS, chn->dev,
272 chn, attr, dst, len, false);
273}
274
275static ssize_t usb_write_chn_attr(const struct iio_channel *chn,
276 const char *attr, const char *src, size_t len)
277{
278 struct iio_context_pdata *pdata = chn->dev->ctx->pdata;
279
280 return iiod_client_write_attr(pdata->iiod_client, EP_OPS, chn->dev,
281 chn, attr, src, len, false);
282}
283
Paul Cercueil6c8337e2015-11-27 11:13:09 +0100284static int usb_set_kernel_buffers_count(const struct iio_device *dev,
285 unsigned int nb_blocks)
286{
287 struct iio_context_pdata *pdata = dev->ctx->pdata;
288
289 return iiod_client_set_kernel_buffers_count(pdata->iiod_client,
290 EP_OPS, dev, nb_blocks);
291}
292
Paul Cercueil7a988892015-12-03 12:39:20 +0100293static int usb_set_timeout(struct iio_context *ctx, unsigned int timeout)
294{
295 struct iio_context_pdata *pdata = ctx->pdata;
296 unsigned int remote_timeout = usb_calculate_remote_timeout(timeout);
297 int ret;
298
299 ret = iiod_client_set_timeout(pdata->iiod_client,
300 EP_OPS, remote_timeout);
Paul Cercueila5e4aa42016-02-09 13:31:01 +0100301 if (!ret)
302 pdata->timeout_ms = timeout;
Paul Cercueil7a988892015-12-03 12:39:20 +0100303
Paul Cercueil7a988892015-12-03 12:39:20 +0100304 return ret;
305}
306
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200307static void usb_shutdown(struct iio_context *ctx)
308{
Paul Cercueil4213a432016-02-09 14:00:40 +0100309 unsigned int i;
310
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200311 iio_mutex_destroy(ctx->pdata->lock);
Paul Cercueil4213a432016-02-09 14:00:40 +0100312 iio_mutex_destroy(ctx->pdata->ep_lock);
313
314 for (i = 0; i < ctx->pdata->nb_io_endpoints; i++)
315 if (ctx->pdata->io_endpoints[i].lock)
316 iio_mutex_destroy(ctx->pdata->io_endpoints[i].lock);
317 if (ctx->pdata->io_endpoints)
318 free(ctx->pdata->io_endpoints);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200319
Lars-Peter Clausen33c64312016-02-19 13:32:08 +0100320 for (i = 0; i < ctx->nb_devices; i++) {
321 struct iio_device *dev = ctx->devices[i];
322
323 free(dev->pdata);
324 }
325
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200326 iiod_client_destroy(ctx->pdata->iiod_client);
327
328 libusb_close(ctx->pdata->hdl);
329 libusb_exit(ctx->pdata->ctx);
Lars-Peter Clausen33c64312016-02-19 13:32:08 +0100330 free(ctx->pdata);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200331}
332
333static const struct iio_backend_ops usb_ops = {
Paul Cercueilc11737c2015-11-26 14:44:46 +0100334 .get_version = usb_get_version,
Paul Cercueil4acd6042015-11-30 12:10:43 +0100335 .open = usb_open,
336 .close = usb_close,
Paul Cercueil04841832015-12-02 11:58:33 +0100337 .read = usb_read,
Paul Cercueile78e9882015-12-04 16:31:10 +0100338 .write = usb_write,
Paul Cercueil3069e3b2015-11-26 16:01:25 +0100339 .read_device_attr = usb_read_dev_attr,
340 .read_channel_attr = usb_read_chn_attr,
341 .write_device_attr = usb_write_dev_attr,
342 .write_channel_attr = usb_write_chn_attr,
Paul Cercueil6c8337e2015-11-27 11:13:09 +0100343 .set_kernel_buffers_count = usb_set_kernel_buffers_count,
Paul Cercueil7a988892015-12-03 12:39:20 +0100344 .set_timeout = usb_set_timeout,
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200345 .shutdown = usb_shutdown,
346};
347
348static ssize_t write_data_sync(struct iio_context_pdata *pdata,
349 int ep, const char *data, size_t len)
350{
351 int transferred, ret;
352
353 ret = libusb_bulk_transfer(pdata->hdl, ep | LIBUSB_ENDPOINT_OUT,
Lars-Peter Clausen8ba0d5b2016-02-17 11:30:23 +0100354 (unsigned char *) data, (int) len,
Paul Cercueile10d19a2016-02-09 13:30:12 +0100355 &transferred, pdata->timeout_ms);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200356 if (ret)
Paul Cercueil463fc782015-12-04 16:04:12 +0100357 return -(int) libusb_to_errno(ret);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200358 else
Lars-Peter Clausen8ba0d5b2016-02-17 11:30:23 +0100359 return (size_t) transferred != len ? -EIO : (ssize_t) len;
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200360}
361
362static ssize_t read_data_sync(struct iio_context_pdata *pdata,
363 int ep, char *buf, size_t len)
364{
365 int transferred, ret;
366
367 ret = libusb_bulk_transfer(pdata->hdl, ep | LIBUSB_ENDPOINT_IN,
Lars-Peter Clausen8ba0d5b2016-02-17 11:30:23 +0100368 (unsigned char *) buf, (int) len, &transferred, pdata->timeout_ms);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200369 if (ret)
Paul Cercueil463fc782015-12-04 16:04:12 +0100370 return -(int) libusb_to_errno(ret);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200371 else
372 return transferred;
373}
374
Lars-Peter Clausen09a59d72016-02-03 15:27:04 +0100375static const struct iiod_client_ops usb_iiod_client_ops = {
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200376 .write = write_data_sync,
377 .read = read_data_sync,
378 .read_line = read_data_sync,
379};
380
Paul Cercueil4213a432016-02-09 14:00:40 +0100381static int usb_count_io_eps(const struct libusb_interface_descriptor *iface)
382{
383 unsigned int eps = iface->bNumEndpoints;
384 unsigned int i, curr;
385
386 /* Check that for a number of endpoints X provided by the interface, we
387 * have the input and output endpoints in the address range [1, ... X/2]
388 * and that each input endpoint has a corresponding output endpoint at
389 * the same address. */
390
391 if (eps < 2 || eps % 2)
392 return -EINVAL;
393
394 for (curr = 1; curr < (eps / 2) + 1; curr++) {
395 bool found_in = false, found_out = false;
396
397 for (i = 0; !found_in && i < eps; i++)
398 found_in = iface->endpoint[i].bEndpointAddress ==
Paul Cercueil6733c4e2016-02-12 15:09:35 +0100399 (LIBUSB_ENDPOINT_IN | curr);
Paul Cercueil4213a432016-02-09 14:00:40 +0100400 if (!found_in)
401 return -EINVAL;
402
403 for (i = 0; !found_out && i < eps; i++)
404 found_out = iface->endpoint[i].bEndpointAddress ==
Paul Cercueil6733c4e2016-02-12 15:09:35 +0100405 (LIBUSB_ENDPOINT_OUT | curr);
Paul Cercueil4213a432016-02-09 14:00:40 +0100406 if (!found_out)
407 return -EINVAL;
408 }
409
410 /* -1: we reserve the first I/O endpoint couple for global operations */
411 return (int) curr - 1;
412}
413
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200414struct iio_context * usb_create_context(unsigned short vid, unsigned short pid)
415{
416 libusb_context *usb_ctx;
Paul Cercueil4213a432016-02-09 14:00:40 +0100417 libusb_device *usb_dev;
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200418 libusb_device_handle *hdl;
Paul Cercueil4213a432016-02-09 14:00:40 +0100419 const struct libusb_interface_descriptor *iface;
420 struct libusb_config_descriptor *conf_desc;
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200421 struct iio_context *ctx;
422 struct iio_context_pdata *pdata;
423 unsigned int i;
424 int ret;
425
426 pdata = calloc(1, sizeof(*pdata));
427 if (!pdata) {
428 ERROR("Unable to allocate pdata\n");
429 ret = -ENOMEM;
430 goto err_set_errno;
431 }
432
433 pdata->lock = iio_mutex_create();
434 if (!pdata->lock) {
435 ERROR("Unable to create mutex\n");
436 ret = -ENOMEM;
437 goto err_free_pdata;
438 }
439
Paul Cercueil4213a432016-02-09 14:00:40 +0100440 pdata->ep_lock = iio_mutex_create();
441 if (!pdata->ep_lock) {
Paul Cercueil4acd6042015-11-30 12:10:43 +0100442 ERROR("Unable to create mutex\n");
443 ret = -ENOMEM;
444 goto err_destroy_mutex;
445 }
446
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200447 pdata->iiod_client = iiod_client_new(pdata, pdata->lock,
448 &usb_iiod_client_ops);
449 if (!pdata->iiod_client) {
450 ERROR("Unable to create IIOD client\n");
451 ret = -errno;
Paul Cercueil4213a432016-02-09 14:00:40 +0100452 goto err_destroy_ep_mutex;
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200453 }
454
455 ret = libusb_init(&usb_ctx);
456 if (ret) {
Paul Cercueil463fc782015-12-04 16:04:12 +0100457 ret = -(int) libusb_to_errno(ret);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200458 ERROR("Unable to init libusb: %i\n", ret);
Paul Cercueil4acd6042015-11-30 12:10:43 +0100459 goto err_destroy_iiod_client;
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200460 }
461
462 hdl = libusb_open_device_with_vid_pid(usb_ctx, vid, pid);
463 if (!hdl) {
464 ERROR("Unable to find device 0x%04hx:0x%04hx\n", vid, pid);
465 ret = -ENODEV;
466 goto err_libusb_exit;
467 }
468
469 libusb_set_auto_detach_kernel_driver(hdl, true);
470
471 ret = libusb_claim_interface(hdl, 0);
472 if (ret) {
Paul Cercueil463fc782015-12-04 16:04:12 +0100473 ret = -(int) libusb_to_errno(ret);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200474 ERROR("Unable to claim interface 0: %i\n", ret);
475 goto err_libusb_close;
476 }
477
Paul Cercueil4213a432016-02-09 14:00:40 +0100478 usb_dev = libusb_get_device(hdl);
479
480 ret = libusb_get_active_config_descriptor(usb_dev, &conf_desc);
481 if (ret) {
482 ret = -(int) libusb_to_errno(ret);
483 ERROR("Unable to get config descriptor: %i\n", ret);
484 goto err_libusb_close;
485 }
486
487 iface = &conf_desc->interface[0].altsetting[0];
488
489 ret = usb_count_io_eps(iface);
490 if (ret < 0) {
491 ERROR("Invalid configuration of endpoints\n");
492 goto err_free_config_descriptor;
493 }
494
495 pdata->nb_io_endpoints = ret;
496
497 DEBUG("Found %hhu usable i/o endpoints\n", pdata->nb_io_endpoints);
498
499 if (pdata->nb_io_endpoints) {
500 pdata->io_endpoints = calloc(pdata->nb_io_endpoints,
501 sizeof(*pdata->io_endpoints));
502 if (!pdata->io_endpoints) {
503 ERROR("Unable to allocate endpoints\n");
504 ret = -ENOMEM;
505 goto err_free_config_descriptor;
506 }
507
508 for (i = 0; i < pdata->nb_io_endpoints; i++) {
509 struct iio_usb_io_endpoint *ep =
510 &pdata->io_endpoints[i];
511
512 /* +2: endpoints start at number 1, and we skip the
513 * endpoint #1 that we reserve for global operations */
514 ep->address = i + 2;
515
516 ep->lock = iio_mutex_create();
517 if (!ep->lock) {
518 ERROR("Unable to create mutex\n");
519 ret = -ENOMEM;
520 goto err_free_endpoints;
521 }
522 }
523 }
524
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200525 pdata->ctx = usb_ctx;
526 pdata->hdl = hdl;
Paul Cercueil7a988892015-12-03 12:39:20 +0100527 pdata->timeout_ms = DEFAULT_TIMEOUT_MS;
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200528
529 ctx = iiod_client_create_context(pdata->iiod_client, EP_OPS);
530 if (!ctx)
Paul Cercueil4213a432016-02-09 14:00:40 +0100531 goto err_free_endpoints;
532
533 libusb_free_config_descriptor(conf_desc);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200534
535 ctx->name = "usb";
536 ctx->ops = &usb_ops;
537 ctx->pdata = pdata;
538
539 DEBUG("Initializing context...\n");
540 ret = iio_context_init(ctx);
541 if (ret < 0)
542 goto err_context_destroy;
543
Paul Cercueil4acd6042015-11-30 12:10:43 +0100544 for (i = 0; i < ctx->nb_devices; i++) {
545 struct iio_device *dev = ctx->devices[i];
546
547 dev->pdata = calloc(1, sizeof(*dev->pdata));
548 if (!dev->pdata) {
549 ERROR("Unable to allocate memory\n");
550 ret = -ENOMEM;
551 goto err_context_destroy;
552 }
553
554 dev->pdata->is_tx = iio_device_is_tx(dev);
Paul Cercueil4acd6042015-11-30 12:10:43 +0100555 }
556
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200557 return ctx;
558
559err_context_destroy:
560 iio_context_destroy(ctx);
561 errno = -ret;
562 return NULL;
563
Paul Cercueil4213a432016-02-09 14:00:40 +0100564err_free_endpoints:
565 for (i = 0; i < pdata->nb_io_endpoints; i++)
566 if (pdata->io_endpoints[i].lock)
567 iio_mutex_destroy(pdata->io_endpoints[i].lock);
568 if (pdata->io_endpoints)
569 free(pdata->io_endpoints);
570err_free_config_descriptor:
571 libusb_free_config_descriptor(conf_desc);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200572err_libusb_close:
573 libusb_close(hdl);
574err_libusb_exit:
575 libusb_exit(usb_ctx);
576err_destroy_iiod_client:
577 iiod_client_destroy(pdata->iiod_client);
Paul Cercueil4213a432016-02-09 14:00:40 +0100578err_destroy_ep_mutex:
579 iio_mutex_destroy(pdata->ep_lock);
Paul Cercueile06f4ce2015-04-20 12:59:31 +0200580err_destroy_mutex:
581 iio_mutex_destroy(pdata->lock);
582err_free_pdata:
583 free(pdata);
584err_set_errno:
585 errno = -ret;
586 return NULL;
587}