aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-06-26 18:46:08 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-06-26 18:46:08 -0400
commit23908db413eccd77084b09c9b0a4451dfb0524c0 (patch)
tree646f21a92496bdc04175e95642b0ecb2dc3dd09e /tools
parent8d7804a2f03dbd34940fcb426450c730adf29dae (diff)
parent53a20e9e378ecd52f0afa4b60f8f8c81b6f97c27 (diff)
Merge tag 'staging-4.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull staging driver updates from Greg KH: "Here's the big, really big, staging tree patches for 4.2-rc1. Loads of stuff in here, almost all just coding style fixes / churn, and a few new drivers as well, one of which I just disabled from the build a few minutes ago due to way too many build warnings. Other than the one "disable this driver" patch, all of these have been in linux-next for quite a while with no reported issues" * tag 'staging-4.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (1163 commits) staging: wilc1000: disable driver due to build warnings Staging: rts5208: fix CHANGE_LINK_STATE value Staging: sm750fb: ddk750_swi2c.c: Insert spaces before parenthesis Staging: sm750fb: ddk750_swi2c.c: Place braces on correct lines Staging: sm750fb: ddk750_swi2c.c: Insert spaces around operators Staging: sm750fb: ddk750_swi2c.c: Replace spaces with tabs Staging: sm750fb: ddk750_swi2c.h: Shorten lines to under 80 characters Staging: sm750fb: ddk750_swi2c.h: Replace spaces with tabs Staging: sm750fb: modedb.h: Shorten lines to under 80 characters Staging: sm750fb: modedb.h: Replace spaces with tabs staging: comedi: addi_apci_3120: rename 'this_board' variables staging: comedi: addi_apci_1516: rename 'this_board' variables staging: comedi: ni_atmio: cleanup ni_getboardtype() staging: comedi: vmk80xx: sanity check context used to get the boardinfo staging: comedi: vmk80xx: rename 'boardinfo' variables staging: comedi: dt3000: rename 'this_board' variables staging: comedi: adv_pci_dio: rename 'this_board' variables staging: comedi: cb_pcidas64: rename 'thisboard' variables staging: comedi: cb_pcidas: rename 'thisboard' variables staging: comedi: me4000: rename 'thisboard' variables ...
Diffstat (limited to 'tools')
-rw-r--r--tools/Makefile8
-rw-r--r--tools/iio/Makefile4
-rw-r--r--tools/iio/generic_buffer.c200
-rw-r--r--tools/iio/iio_event_monitor.c50
-rw-r--r--tools/iio/iio_utils.c469
-rw-r--r--tools/iio/iio_utils.h20
-rw-r--r--tools/iio/lsiio.c63
7 files changed, 610 insertions, 204 deletions
diff --git a/tools/Makefile b/tools/Makefile
index b113078fb7ad..d6f307dfb1a3 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -13,6 +13,7 @@ help:
13 @echo ' cpupower - a tool for all things x86 CPU power' 13 @echo ' cpupower - a tool for all things x86 CPU power'
14 @echo ' firewire - the userspace part of nosy, an IEEE-1394 traffic sniffer' 14 @echo ' firewire - the userspace part of nosy, an IEEE-1394 traffic sniffer'
15 @echo ' hv - tools used when in Hyper-V clients' 15 @echo ' hv - tools used when in Hyper-V clients'
16 @echo ' iio - IIO tools'
16 @echo ' lguest - a minimal 32-bit x86 hypervisor' 17 @echo ' lguest - a minimal 32-bit x86 hypervisor'
17 @echo ' perf - Linux performance measurement and analysis tool' 18 @echo ' perf - Linux performance measurement and analysis tool'
18 @echo ' selftests - various kernel selftests' 19 @echo ' selftests - various kernel selftests'
@@ -47,7 +48,7 @@ acpi: FORCE
47cpupower: FORCE 48cpupower: FORCE
48 $(call descend,power/$@) 49 $(call descend,power/$@)
49 50
50cgroup firewire hv guest usb virtio vm net: FORCE 51cgroup firewire hv guest usb virtio vm net iio: FORCE
51 $(call descend,$@) 52 $(call descend,$@)
52 53
53liblockdep: FORCE 54liblockdep: FORCE
@@ -108,7 +109,7 @@ acpi_clean:
108cpupower_clean: 109cpupower_clean:
109 $(call descend,power/cpupower,clean) 110 $(call descend,power/cpupower,clean)
110 111
111cgroup_clean hv_clean firewire_clean lguest_clean usb_clean virtio_clean vm_clean net_clean: 112cgroup_clean hv_clean firewire_clean lguest_clean usb_clean virtio_clean vm_clean net_clean iio_clean:
112 $(call descend,$(@:_clean=),clean) 113 $(call descend,$(@:_clean=),clean)
113 114
114liblockdep_clean: 115liblockdep_clean:
@@ -134,6 +135,7 @@ freefall_clean:
134 135
135clean: acpi_clean cgroup_clean cpupower_clean hv_clean firewire_clean lguest_clean \ 136clean: acpi_clean cgroup_clean cpupower_clean hv_clean firewire_clean lguest_clean \
136 perf_clean selftests_clean turbostat_clean usb_clean virtio_clean \ 137 perf_clean selftests_clean turbostat_clean usb_clean virtio_clean \
137 vm_clean net_clean x86_energy_perf_policy_clean tmon_clean freefall_clean 138 vm_clean net_clean iio_clean x86_energy_perf_policy_clean tmon_clean \
139 freefall_clean
138 140
139.PHONY: FORCE 141.PHONY: FORCE
diff --git a/tools/iio/Makefile b/tools/iio/Makefile
index bf7ae6d6612a..3a7a54f59713 100644
--- a/tools/iio/Makefile
+++ b/tools/iio/Makefile
@@ -1,5 +1,5 @@
1CC = gcc 1CC = $(CROSS_COMPILE)gcc
2CFLAGS = -Wall -g -D_GNU_SOURCE 2CFLAGS += -Wall -g -D_GNU_SOURCE
3 3
4all: iio_event_monitor lsiio generic_buffer 4all: iio_event_monitor lsiio generic_buffer
5 5
diff --git a/tools/iio/generic_buffer.c b/tools/iio/generic_buffer.c
index f805493be3eb..4eebb6616e5c 100644
--- a/tools/iio/generic_buffer.c
+++ b/tools/iio/generic_buffer.c
@@ -59,33 +59,80 @@ int size_from_channelarray(struct iio_channel_info *channels, int num_channels)
59 return bytes; 59 return bytes;
60} 60}
61 61
62void print2byte(int input, struct iio_channel_info *info) 62void print2byte(uint16_t input, struct iio_channel_info *info)
63{ 63{
64 /* First swap if incorrect endian */ 64 /* First swap if incorrect endian */
65 if (info->be) 65 if (info->be)
66 input = be16toh((uint16_t)input); 66 input = be16toh(input);
67 else 67 else
68 input = le16toh((uint16_t)input); 68 input = le16toh(input);
69 69
70 /* 70 /*
71 * Shift before conversion to avoid sign extension 71 * Shift before conversion to avoid sign extension
72 * of left aligned data 72 * of left aligned data
73 */ 73 */
74 input >>= info->shift; 74 input >>= info->shift;
75 input &= info->mask;
75 if (info->is_signed) { 76 if (info->is_signed) {
76 int16_t val = input; 77 int16_t val = (int16_t)(input << (16 - info->bits_used)) >>
78 (16 - info->bits_used);
79 printf("%05f ", ((float)val + info->offset) * info->scale);
80 } else {
81 printf("%05f ", ((float)input + info->offset) * info->scale);
82 }
83}
84
85void print4byte(uint32_t input, struct iio_channel_info *info)
86{
87 /* First swap if incorrect endian */
88 if (info->be)
89 input = be32toh(input);
90 else
91 input = le32toh(input);
77 92
78 val &= (1 << info->bits_used) - 1; 93 /*
79 val = (int16_t)(val << (16 - info->bits_used)) >> 94 * Shift before conversion to avoid sign extension
80 (16 - info->bits_used); 95 * of left aligned data
81 printf("%05f ", ((float)val + info->offset)*info->scale); 96 */
97 input >>= info->shift;
98 input &= info->mask;
99 if (info->is_signed) {
100 int32_t val = (int32_t)(input << (32 - info->bits_used)) >>
101 (32 - info->bits_used);
102 printf("%05f ", ((float)val + info->offset) * info->scale);
82 } else { 103 } else {
83 uint16_t val = input; 104 printf("%05f ", ((float)input + info->offset) * info->scale);
105 }
106}
84 107
85 val &= (1 << info->bits_used) - 1; 108void print8byte(uint64_t input, struct iio_channel_info *info)
86 printf("%05f ", ((float)val + info->offset)*info->scale); 109{
110 /* First swap if incorrect endian */
111 if (info->be)
112 input = be64toh(input);
113 else
114 input = le64toh(input);
115
116 /*
117 * Shift before conversion to avoid sign extension
118 * of left aligned data
119 */
120 input >>= info->shift;
121 input &= info->mask;
122 if (info->is_signed) {
123 int64_t val = (int64_t)(input << (64 - info->bits_used)) >>
124 (64 - info->bits_used);
125 /* special case for timestamp */
126 if (info->scale == 1.0f && info->offset == 0.0f)
127 printf("%" PRId64 " ", val);
128 else
129 printf("%05f ",
130 ((float)val + info->offset) * info->scale);
131 } else {
132 printf("%05f ", ((float)input + info->offset) * info->scale);
87 } 133 }
88} 134}
135
89/** 136/**
90 * process_scan() - print out the values in SI units 137 * process_scan() - print out the values in SI units
91 * @data: pointer to the start of the scan 138 * @data: pointer to the start of the scan
@@ -108,32 +155,12 @@ void process_scan(char *data,
108 &channels[k]); 155 &channels[k]);
109 break; 156 break;
110 case 4: 157 case 4:
111 if (!channels[k].is_signed) { 158 print4byte(*(uint32_t *)(data + channels[k].location),
112 uint32_t val = *(uint32_t *) 159 &channels[k]);
113 (data + channels[k].location);
114 printf("%05f ", ((float)val +
115 channels[k].offset)*
116 channels[k].scale);
117
118 }
119 break; 160 break;
120 case 8: 161 case 8:
121 if (channels[k].is_signed) { 162 print8byte(*(uint64_t *)(data + channels[k].location),
122 int64_t val = *(int64_t *) 163 &channels[k]);
123 (data +
124 channels[k].location);
125 if ((val >> channels[k].bits_used) & 1)
126 val = (val & channels[k].mask) |
127 ~channels[k].mask;
128 /* special case for timestamp */
129 if (channels[k].scale == 1.0f &&
130 channels[k].offset == 0.0f)
131 printf("%" PRId64 " ", val);
132 else
133 printf("%05f ", ((float)val +
134 channels[k].offset)*
135 channels[k].scale);
136 }
137 break; 164 break;
138 default: 165 default:
139 break; 166 break;
@@ -141,6 +168,19 @@ void process_scan(char *data,
141 printf("\n"); 168 printf("\n");
142} 169}
143 170
171void print_usage(void)
172{
173 printf("Usage: generic_buffer [options]...\n"
174 "Capture, convert and output data from IIO device buffer\n"
175 " -c <n> Do n conversions\n"
176 " -e Disable wait for event (new data)\n"
177 " -g Use trigger-less mode\n"
178 " -l <n> Set buffer length to n samples\n"
179 " -n <name> Set device name (mandatory)\n"
180 " -t <name> Set trigger name\n"
181 " -w <n> Set delay between reads in us (event-less mode)\n");
182}
183
144int main(int argc, char **argv) 184int main(int argc, char **argv)
145{ 185{
146 unsigned long num_loops = 2; 186 unsigned long num_loops = 2;
@@ -166,8 +206,26 @@ int main(int argc, char **argv)
166 206
167 struct iio_channel_info *channels; 207 struct iio_channel_info *channels;
168 208
169 while ((c = getopt(argc, argv, "l:w:c:et:n:g")) != -1) { 209 while ((c = getopt(argc, argv, "c:egl:n:t:w:")) != -1) {
170 switch (c) { 210 switch (c) {
211 case 'c':
212 errno = 0;
213 num_loops = strtoul(optarg, &dummy, 10);
214 if (errno)
215 return -errno;
216 break;
217 case 'e':
218 noevents = 1;
219 break;
220 case 'g':
221 notrigger = 1;
222 break;
223 case 'l':
224 errno = 0;
225 buf_len = strtoul(optarg, &dummy, 10);
226 if (errno)
227 return -errno;
228 break;
171 case 'n': 229 case 'n':
172 device_name = optarg; 230 device_name = optarg;
173 break; 231 break;
@@ -175,39 +233,35 @@ int main(int argc, char **argv)
175 trigger_name = optarg; 233 trigger_name = optarg;
176 datardytrigger = 0; 234 datardytrigger = 0;
177 break; 235 break;
178 case 'e':
179 noevents = 1;
180 break;
181 case 'c':
182 num_loops = strtoul(optarg, &dummy, 10);
183 break;
184 case 'w': 236 case 'w':
237 errno = 0;
185 timedelay = strtoul(optarg, &dummy, 10); 238 timedelay = strtoul(optarg, &dummy, 10);
186 break; 239 if (errno)
187 case 'l': 240 return -errno;
188 buf_len = strtoul(optarg, &dummy, 10);
189 break;
190 case 'g':
191 notrigger = 1;
192 break; 241 break;
193 case '?': 242 case '?':
243 print_usage();
194 return -1; 244 return -1;
195 } 245 }
196 } 246 }
197 247
198 if (device_name == NULL) 248 if (device_name == NULL) {
249 printf("Device name not set\n");
250 print_usage();
199 return -1; 251 return -1;
252 }
200 253
201 /* Find the device requested */ 254 /* Find the device requested */
202 dev_num = find_type_by_name(device_name, "iio:device"); 255 dev_num = find_type_by_name(device_name, "iio:device");
203 if (dev_num < 0) { 256 if (dev_num < 0) {
204 printf("Failed to find the %s\n", device_name); 257 printf("Failed to find the %s\n", device_name);
205 ret = -ENODEV; 258 return dev_num;
206 goto error_ret;
207 } 259 }
208 printf("iio device number being used is %d\n", dev_num); 260 printf("iio device number being used is %d\n", dev_num);
209 261
210 asprintf(&dev_dir_name, "%siio:device%d", iio_dir, dev_num); 262 ret = asprintf(&dev_dir_name, "%siio:device%d", iio_dir, dev_num);
263 if (ret < 0)
264 return -ENOMEM;
211 265
212 if (!notrigger) { 266 if (!notrigger) {
213 if (trigger_name == NULL) { 267 if (trigger_name == NULL) {
@@ -220,7 +274,7 @@ int main(int argc, char **argv)
220 "%s-dev%d", device_name, dev_num); 274 "%s-dev%d", device_name, dev_num);
221 if (ret < 0) { 275 if (ret < 0) {
222 ret = -ENOMEM; 276 ret = -ENOMEM;
223 goto error_ret; 277 goto error_free_dev_dir_name;
224 } 278 }
225 } 279 }
226 280
@@ -228,7 +282,7 @@ int main(int argc, char **argv)
228 trig_num = find_type_by_name(trigger_name, "trigger"); 282 trig_num = find_type_by_name(trigger_name, "trigger");
229 if (trig_num < 0) { 283 if (trig_num < 0) {
230 printf("Failed to find the trigger %s\n", trigger_name); 284 printf("Failed to find the trigger %s\n", trigger_name);
231 ret = -ENODEV; 285 ret = trig_num;
232 goto error_free_triggername; 286 goto error_free_triggername;
233 } 287 }
234 printf("iio trigger number being used is %d\n", trig_num); 288 printf("iio trigger number being used is %d\n", trig_num);
@@ -255,7 +309,7 @@ int main(int argc, char **argv)
255 "%siio:device%d/buffer", iio_dir, dev_num); 309 "%siio:device%d/buffer", iio_dir, dev_num);
256 if (ret < 0) { 310 if (ret < 0) {
257 ret = -ENOMEM; 311 ret = -ENOMEM;
258 goto error_free_triggername; 312 goto error_free_channels;
259 } 313 }
260 314
261 if (!notrigger) { 315 if (!notrigger) {
@@ -296,8 +350,8 @@ int main(int argc, char **argv)
296 /* Attempt to open non blocking the access dev */ 350 /* Attempt to open non blocking the access dev */
297 fp = open(buffer_access, O_RDONLY | O_NONBLOCK); 351 fp = open(buffer_access, O_RDONLY | O_NONBLOCK);
298 if (fp == -1) { /* If it isn't there make the node */ 352 if (fp == -1) { /* If it isn't there make the node */
299 printf("Failed to open %s\n", buffer_access);
300 ret = -errno; 353 ret = -errno;
354 printf("Failed to open %s\n", buffer_access);
301 goto error_free_buffer_access; 355 goto error_free_buffer_access;
302 } 356 }
303 357
@@ -309,7 +363,14 @@ int main(int argc, char **argv)
309 .events = POLLIN, 363 .events = POLLIN,
310 }; 364 };
311 365
312 poll(&pfd, 1, -1); 366 ret = poll(&pfd, 1, -1);
367 if (ret < 0) {
368 ret = -errno;
369 goto error_close_buffer_access;
370 } else if (ret == 0) {
371 continue;
372 }
373
313 toread = buf_len; 374 toread = buf_len;
314 375
315 } else { 376 } else {
@@ -321,7 +382,7 @@ int main(int argc, char **argv)
321 data, 382 data,
322 toread*scan_size); 383 toread*scan_size);
323 if (read_size < 0) { 384 if (read_size < 0) {
324 if (errno == -EAGAIN) { 385 if (errno == EAGAIN) {
325 printf("nothing available\n"); 386 printf("nothing available\n");
326 continue; 387 continue;
327 } else 388 } else
@@ -340,20 +401,31 @@ int main(int argc, char **argv)
340 401
341 if (!notrigger) 402 if (!notrigger)
342 /* Disconnect the trigger - just write a dummy name. */ 403 /* Disconnect the trigger - just write a dummy name. */
343 write_sysfs_string("trigger/current_trigger", 404 ret = write_sysfs_string("trigger/current_trigger",
344 dev_dir_name, "NULL"); 405 dev_dir_name, "NULL");
406 if (ret < 0)
407 printf("Failed to write to %s\n", dev_dir_name);
345 408
346error_close_buffer_access: 409error_close_buffer_access:
347 close(fp); 410 if (close(fp) == -1)
348error_free_data: 411 perror("Failed to close buffer");
349 free(data);
350error_free_buffer_access: 412error_free_buffer_access:
351 free(buffer_access); 413 free(buffer_access);
414error_free_data:
415 free(data);
352error_free_buf_dir_name: 416error_free_buf_dir_name:
353 free(buf_dir_name); 417 free(buf_dir_name);
418error_free_channels:
419 for (i = num_channels - 1; i >= 0; i--) {
420 free(channels[i].name);
421 free(channels[i].generic_name);
422 }
423 free(channels);
354error_free_triggername: 424error_free_triggername:
355 if (datardytrigger) 425 if (datardytrigger)
356 free(trigger_name); 426 free(trigger_name);
357error_ret: 427error_free_dev_dir_name:
428 free(dev_dir_name);
429
358 return ret; 430 return ret;
359} 431}
diff --git a/tools/iio/iio_event_monitor.c b/tools/iio/iio_event_monitor.c
index 427c271ac0d6..016760e769c0 100644
--- a/tools/iio/iio_event_monitor.c
+++ b/tools/iio/iio_event_monitor.c
@@ -213,23 +213,19 @@ static void print_event(struct iio_event_data *event)
213 return; 213 return;
214 } 214 }
215 215
216 printf("Event: time: %lld, ", event->timestamp); 216 printf("Event: time: %lld, type: %s", event->timestamp,
217 iio_chan_type_name_spec[type]);
217 218
218 if (mod != IIO_NO_MOD) { 219 if (mod != IIO_NO_MOD)
219 printf("type: %s(%s), ", 220 printf("(%s)", iio_modifier_names[mod]);
220 iio_chan_type_name_spec[type],
221 iio_modifier_names[mod]);
222 } else {
223 printf("type: %s, ",
224 iio_chan_type_name_spec[type]);
225 }
226 221
227 if (diff && chan >= 0 && chan2 >= 0) 222 if (chan >= 0) {
228 printf("channel: %d-%d, ", chan, chan2); 223 printf(", channel: %d", chan);
229 else if (chan >= 0) 224 if (diff && chan2 >= 0)
230 printf("channel: %d, ", chan); 225 printf("-%d", chan2);
226 }
231 227
232 printf("evtype: %s", iio_ev_type_text[ev_type]); 228 printf(", evtype: %s", iio_ev_type_text[ev_type]);
233 229
234 if (dir != IIO_EV_DIR_NONE) 230 if (dir != IIO_EV_DIR_NONE)
235 printf(", direction: %s", iio_ev_dir_text[dir]); 231 printf(", direction: %s", iio_ev_dir_text[dir]);
@@ -258,28 +254,34 @@ int main(int argc, char **argv)
258 device_name, dev_num); 254 device_name, dev_num);
259 ret = asprintf(&chrdev_name, "/dev/iio:device%d", dev_num); 255 ret = asprintf(&chrdev_name, "/dev/iio:device%d", dev_num);
260 if (ret < 0) { 256 if (ret < 0) {
261 ret = -ENOMEM; 257 return -ENOMEM;
262 goto error_ret;
263 } 258 }
264 } else { 259 } else {
265 /* If we can't find a IIO device by name assume device_name is a 260 /* If we can't find a IIO device by name assume device_name is a
266 IIO chrdev */ 261 IIO chrdev */
267 chrdev_name = strdup(device_name); 262 chrdev_name = strdup(device_name);
263 if (!chrdev_name)
264 return -ENOMEM;
268 } 265 }
269 266
270 fd = open(chrdev_name, 0); 267 fd = open(chrdev_name, 0);
271 if (fd == -1) { 268 if (fd == -1) {
272 fprintf(stdout, "Failed to open %s\n", chrdev_name);
273 ret = -errno; 269 ret = -errno;
270 fprintf(stdout, "Failed to open %s\n", chrdev_name);
274 goto error_free_chrdev_name; 271 goto error_free_chrdev_name;
275 } 272 }
276 273
277 ret = ioctl(fd, IIO_GET_EVENT_FD_IOCTL, &event_fd); 274 ret = ioctl(fd, IIO_GET_EVENT_FD_IOCTL, &event_fd);
278
279 close(fd);
280
281 if (ret == -1 || event_fd == -1) { 275 if (ret == -1 || event_fd == -1) {
276 ret = -errno;
282 fprintf(stdout, "Failed to retrieve event fd\n"); 277 fprintf(stdout, "Failed to retrieve event fd\n");
278 if (close(fd) == -1)
279 perror("Failed to close character device file");
280
281 goto error_free_chrdev_name;
282 }
283
284 if (close(fd) == -1) {
283 ret = -errno; 285 ret = -errno;
284 goto error_free_chrdev_name; 286 goto error_free_chrdev_name;
285 } 287 }
@@ -291,8 +293,8 @@ int main(int argc, char **argv)
291 printf("nothing available\n"); 293 printf("nothing available\n");
292 continue; 294 continue;
293 } else { 295 } else {
294 perror("Failed to read event from device");
295 ret = -errno; 296 ret = -errno;
297 perror("Failed to read event from device");
296 break; 298 break;
297 } 299 }
298 } 300 }
@@ -300,9 +302,11 @@ int main(int argc, char **argv)
300 print_event(&event); 302 print_event(&event);
301 } 303 }
302 304
303 close(event_fd); 305 if (close(event_fd) == -1)
306 perror("Failed to close event file");
307
304error_free_chrdev_name: 308error_free_chrdev_name:
305 free(chrdev_name); 309 free(chrdev_name);
306error_ret: 310
307 return ret; 311 return ret;
308} 312}
diff --git a/tools/iio/iio_utils.c b/tools/iio/iio_utils.c
index 6f6452167b67..ec9ab7f9ae4c 100644
--- a/tools/iio/iio_utils.c
+++ b/tools/iio/iio_utils.c
@@ -29,6 +29,8 @@ static char * const iio_direction[] = {
29 * iioutils_break_up_name() - extract generic name from full channel name 29 * iioutils_break_up_name() - extract generic name from full channel name
30 * @full_name: the full channel name 30 * @full_name: the full channel name
31 * @generic_name: the output generic channel name 31 * @generic_name: the output generic channel name
32 *
33 * Returns 0 on success, or a negative error code if string extraction failed.
32 **/ 34 **/
33int iioutils_break_up_name(const char *full_name, 35int iioutils_break_up_name(const char *full_name,
34 char **generic_name) 36 char **generic_name)
@@ -36,7 +38,7 @@ int iioutils_break_up_name(const char *full_name,
36 char *current; 38 char *current;
37 char *w, *r; 39 char *w, *r;
38 char *working, *prefix = ""; 40 char *working, *prefix = "";
39 int i; 41 int i, ret;
40 42
41 for (i = 0; i < sizeof(iio_direction) / sizeof(iio_direction[0]); i++) 43 for (i = 0; i < sizeof(iio_direction) / sizeof(iio_direction[0]); i++)
42 if (!strncmp(full_name, iio_direction[i], 44 if (!strncmp(full_name, iio_direction[i],
@@ -46,7 +48,14 @@ int iioutils_break_up_name(const char *full_name,
46 } 48 }
47 49
48 current = strdup(full_name + strlen(prefix) + 1); 50 current = strdup(full_name + strlen(prefix) + 1);
51 if (!current)
52 return -ENOMEM;
53
49 working = strtok(current, "_\0"); 54 working = strtok(current, "_\0");
55 if (!working) {
56 free(current);
57 return -EINVAL;
58 }
50 59
51 w = working; 60 w = working;
52 r = working; 61 r = working;
@@ -59,21 +68,25 @@ int iioutils_break_up_name(const char *full_name,
59 r++; 68 r++;
60 } 69 }
61 *w = '\0'; 70 *w = '\0';
62 asprintf(generic_name, "%s_%s", prefix, working); 71 ret = asprintf(generic_name, "%s_%s", prefix, working);
63 free(current); 72 free(current);
64 73
65 return 0; 74 return (ret == -1) ? -ENOMEM : 0;
66} 75}
67 76
68/** 77/**
69 * iioutils_get_type() - find and process _type attribute data 78 * iioutils_get_type() - find and process _type attribute data
70 * @is_signed: output whether channel is signed 79 * @is_signed: output whether channel is signed
71 * @bytes: output how many bytes the channel storage occupies 80 * @bytes: output how many bytes the channel storage occupies
81 * @bits_used: output number of valid bits of data
82 * @shift: output amount of bits to shift right data before applying bit mask
72 * @mask: output a bit mask for the raw data 83 * @mask: output a bit mask for the raw data
73 * @be: big endian 84 * @be: output if data in big endian
74 * @device_dir: the iio device directory 85 * @device_dir: the IIO device directory
75 * @name: the channel name 86 * @name: the channel name
76 * @generic_name: the channel type name 87 * @generic_name: the channel type name
88 *
89 * Returns a value >= 0 on success, otherwise a negative error code.
77 **/ 90 **/
78int iioutils_get_type(unsigned *is_signed, 91int iioutils_get_type(unsigned *is_signed,
79 unsigned *bytes, 92 unsigned *bytes,
@@ -94,10 +107,9 @@ int iioutils_get_type(unsigned *is_signed,
94 const struct dirent *ent; 107 const struct dirent *ent;
95 108
96 ret = asprintf(&scan_el_dir, FORMAT_SCAN_ELEMENTS_DIR, device_dir); 109 ret = asprintf(&scan_el_dir, FORMAT_SCAN_ELEMENTS_DIR, device_dir);
97 if (ret < 0) { 110 if (ret < 0)
98 ret = -ENOMEM; 111 return -ENOMEM;
99 goto error_ret; 112
100 }
101 ret = asprintf(&builtname, FORMAT_TYPE_FILE, name); 113 ret = asprintf(&builtname, FORMAT_TYPE_FILE, name);
102 if (ret < 0) { 114 if (ret < 0) {
103 ret = -ENOMEM; 115 ret = -ENOMEM;
@@ -114,6 +126,7 @@ int iioutils_get_type(unsigned *is_signed,
114 ret = -errno; 126 ret = -errno;
115 goto error_free_builtname_generic; 127 goto error_free_builtname_generic;
116 } 128 }
129 ret = -ENOENT;
117 while (ent = readdir(dp), ent != NULL) 130 while (ent = readdir(dp), ent != NULL)
118 /* 131 /*
119 * Do we allow devices to override a generic name with 132 * Do we allow devices to override a generic name with
@@ -129,8 +142,8 @@ int iioutils_get_type(unsigned *is_signed,
129 } 142 }
130 sysfsfp = fopen(filename, "r"); 143 sysfsfp = fopen(filename, "r");
131 if (sysfsfp == NULL) { 144 if (sysfsfp == NULL) {
132 printf("failed to open %s\n", filename);
133 ret = -errno; 145 ret = -errno;
146 printf("failed to open %s\n", filename);
134 goto error_free_filename; 147 goto error_free_filename;
135 } 148 }
136 149
@@ -141,8 +154,12 @@ int iioutils_get_type(unsigned *is_signed,
141 bits_used, 154 bits_used,
142 &padint, shift); 155 &padint, shift);
143 if (ret < 0) { 156 if (ret < 0) {
144 printf("failed to pass scan type description\n");
145 ret = -errno; 157 ret = -errno;
158 printf("failed to pass scan type description\n");
159 goto error_close_sysfsfp;
160 } else if (ret != 5) {
161 ret = -EIO;
162 printf("scan type description didn't match\n");
146 goto error_close_sysfsfp; 163 goto error_close_sysfsfp;
147 } 164 }
148 *be = (endianchar == 'b'); 165 *be = (endianchar == 'b');
@@ -151,34 +168,50 @@ int iioutils_get_type(unsigned *is_signed,
151 *mask = ~0; 168 *mask = ~0;
152 else 169 else
153 *mask = (1 << *bits_used) - 1; 170 *mask = (1 << *bits_used) - 1;
154 if (signchar == 's') 171 *is_signed = (signchar == 's');
155 *is_signed = 1; 172 if (fclose(sysfsfp)) {
156 else 173 ret = -errno;
157 *is_signed = 0; 174 printf("Failed to close %s\n", filename);
158 fclose(sysfsfp); 175 goto error_free_filename;
176 }
177
178 sysfsfp = 0;
159 free(filename); 179 free(filename);
160 180
161 filename = 0; 181 filename = 0;
162 sysfsfp = 0;
163 } 182 }
164error_close_sysfsfp: 183error_close_sysfsfp:
165 if (sysfsfp) 184 if (sysfsfp)
166 fclose(sysfsfp); 185 if (fclose(sysfsfp))
186 perror("iioutils_get_type(): Failed to close file");
187
167error_free_filename: 188error_free_filename:
168 if (filename) 189 if (filename)
169 free(filename); 190 free(filename);
170error_closedir: 191error_closedir:
171 closedir(dp); 192 if (closedir(dp) == -1)
193 perror("iioutils_get_type(): Failed to close directory");
194
172error_free_builtname_generic: 195error_free_builtname_generic:
173 free(builtname_generic); 196 free(builtname_generic);
174error_free_builtname: 197error_free_builtname:
175 free(builtname); 198 free(builtname);
176error_free_scan_el_dir: 199error_free_scan_el_dir:
177 free(scan_el_dir); 200 free(scan_el_dir);
178error_ret: 201
179 return ret; 202 return ret;
180} 203}
181 204
205/**
206 * iioutils_get_param_float() - read a float value from a channel parameter
207 * @output: output the float value
208 * @param_name: the parameter name to read
209 * @device_dir: the IIO device directory in sysfs
210 * @name: the channel name
211 * @generic_name: the channel type name
212 *
213 * Returns a value >= 0 on success, otherwise a negative error code.
214 **/
182int iioutils_get_param_float(float *output, 215int iioutils_get_param_float(float *output,
183 const char *param_name, 216 const char *param_name,
184 const char *device_dir, 217 const char *device_dir,
@@ -193,10 +226,9 @@ int iioutils_get_param_float(float *output,
193 const struct dirent *ent; 226 const struct dirent *ent;
194 227
195 ret = asprintf(&builtname, "%s_%s", name, param_name); 228 ret = asprintf(&builtname, "%s_%s", name, param_name);
196 if (ret < 0) { 229 if (ret < 0)
197 ret = -ENOMEM; 230 return -ENOMEM;
198 goto error_ret; 231
199 }
200 ret = asprintf(&builtname_generic, 232 ret = asprintf(&builtname_generic,
201 "%s_%s", generic_name, param_name); 233 "%s_%s", generic_name, param_name);
202 if (ret < 0) { 234 if (ret < 0) {
@@ -208,6 +240,7 @@ int iioutils_get_param_float(float *output,
208 ret = -errno; 240 ret = -errno;
209 goto error_free_builtname_generic; 241 goto error_free_builtname_generic;
210 } 242 }
243 ret = -ENOENT;
211 while (ent = readdir(dp), ent != NULL) 244 while (ent = readdir(dp), ent != NULL)
212 if ((strcmp(builtname, ent->d_name) == 0) || 245 if ((strcmp(builtname, ent->d_name) == 0) ||
213 (strcmp(builtname_generic, ent->d_name) == 0)) { 246 (strcmp(builtname_generic, ent->d_name) == 0)) {
@@ -222,25 +255,31 @@ int iioutils_get_param_float(float *output,
222 ret = -errno; 255 ret = -errno;
223 goto error_free_filename; 256 goto error_free_filename;
224 } 257 }
225 fscanf(sysfsfp, "%f", output); 258 errno = 0;
259 if (fscanf(sysfsfp, "%f", output) != 1)
260 ret = errno ? -errno : -ENODATA;
261
226 break; 262 break;
227 } 263 }
228error_free_filename: 264error_free_filename:
229 if (filename) 265 if (filename)
230 free(filename); 266 free(filename);
231error_closedir: 267error_closedir:
232 closedir(dp); 268 if (closedir(dp) == -1)
269 perror("iioutils_get_param_float(): Failed to close directory");
270
233error_free_builtname_generic: 271error_free_builtname_generic:
234 free(builtname_generic); 272 free(builtname_generic);
235error_free_builtname: 273error_free_builtname:
236 free(builtname); 274 free(builtname);
237error_ret: 275
238 return ret; 276 return ret;
239} 277}
240 278
241/** 279/**
242 * bsort_channel_array_by_index() - reorder so that the array is in index order 280 * bsort_channel_array_by_index() - sort the array in index order
243 * 281 * @ci_array: the iio_channel_info array to be sorted
282 * @cnt: the amount of array elements
244 **/ 283 **/
245 284
246void bsort_channel_array_by_index(struct iio_channel_info **ci_array, 285void bsort_channel_array_by_index(struct iio_channel_info **ci_array,
@@ -262,7 +301,10 @@ void bsort_channel_array_by_index(struct iio_channel_info **ci_array,
262/** 301/**
263 * build_channel_array() - function to figure out what channels are present 302 * build_channel_array() - function to figure out what channels are present
264 * @device_dir: the IIO device directory in sysfs 303 * @device_dir: the IIO device directory in sysfs
265 * @ 304 * @ci_array: output the resulting array of iio_channel_info
305 * @counter: output the amount of array elements
306 *
307 * Returns 0 on success, otherwise a negative error code.
266 **/ 308 **/
267int build_channel_array(const char *device_dir, 309int build_channel_array(const char *device_dir,
268 struct iio_channel_info **ci_array, 310 struct iio_channel_info **ci_array,
@@ -270,7 +312,7 @@ int build_channel_array(const char *device_dir,
270{ 312{
271 DIR *dp; 313 DIR *dp;
272 FILE *sysfsfp; 314 FILE *sysfsfp;
273 int count, i; 315 int count = 0, i;
274 struct iio_channel_info *current; 316 struct iio_channel_info *current;
275 int ret; 317 int ret;
276 const struct dirent *ent; 318 const struct dirent *ent;
@@ -279,10 +321,9 @@ int build_channel_array(const char *device_dir,
279 321
280 *counter = 0; 322 *counter = 0;
281 ret = asprintf(&scan_el_dir, FORMAT_SCAN_ELEMENTS_DIR, device_dir); 323 ret = asprintf(&scan_el_dir, FORMAT_SCAN_ELEMENTS_DIR, device_dir);
282 if (ret < 0) { 324 if (ret < 0)
283 ret = -ENOMEM; 325 return -ENOMEM;
284 goto error_ret; 326
285 }
286 dp = opendir(scan_el_dir); 327 dp = opendir(scan_el_dir);
287 if (dp == NULL) { 328 if (dp == NULL) {
288 ret = -errno; 329 ret = -errno;
@@ -303,10 +344,24 @@ int build_channel_array(const char *device_dir,
303 free(filename); 344 free(filename);
304 goto error_close_dir; 345 goto error_close_dir;
305 } 346 }
306 fscanf(sysfsfp, "%i", &ret); 347 errno = 0;
348 if (fscanf(sysfsfp, "%i", &ret) != 1) {
349 ret = errno ? -errno : -ENODATA;
350 if (fclose(sysfsfp))
351 perror("build_channel_array(): Failed to close file");
352
353 free(filename);
354 goto error_close_dir;
355 }
356
307 if (ret == 1) 357 if (ret == 1)
308 (*counter)++; 358 (*counter)++;
309 fclose(sysfsfp); 359 if (fclose(sysfsfp)) {
360 ret = -errno;
361 free(filename);
362 goto error_close_dir;
363 }
364
310 free(filename); 365 free(filename);
311 } 366 }
312 *ci_array = malloc(sizeof(**ci_array) * (*counter)); 367 *ci_array = malloc(sizeof(**ci_array) * (*counter));
@@ -315,7 +370,6 @@ int build_channel_array(const char *device_dir,
315 goto error_close_dir; 370 goto error_close_dir;
316 } 371 }
317 seekdir(dp, 0); 372 seekdir(dp, 0);
318 count = 0;
319 while (ent = readdir(dp), ent != NULL) { 373 while (ent = readdir(dp), ent != NULL) {
320 if (strcmp(ent->d_name + strlen(ent->d_name) - strlen("_en"), 374 if (strcmp(ent->d_name + strlen(ent->d_name) - strlen("_en"),
321 "_en") == 0) { 375 "_en") == 0) {
@@ -332,12 +386,25 @@ int build_channel_array(const char *device_dir,
332 } 386 }
333 sysfsfp = fopen(filename, "r"); 387 sysfsfp = fopen(filename, "r");
334 if (sysfsfp == NULL) { 388 if (sysfsfp == NULL) {
389 ret = -errno;
335 free(filename); 390 free(filename);
391 count--;
392 goto error_cleanup_array;
393 }
394 errno = 0;
395 if (fscanf(sysfsfp, "%i", &current_enabled) != 1) {
396 ret = errno ? -errno : -ENODATA;
397 free(filename);
398 count--;
399 goto error_cleanup_array;
400 }
401
402 if (fclose(sysfsfp)) {
336 ret = -errno; 403 ret = -errno;
404 free(filename);
405 count--;
337 goto error_cleanup_array; 406 goto error_cleanup_array;
338 } 407 }
339 fscanf(sysfsfp, "%i", &current_enabled);
340 fclose(sysfsfp);
341 408
342 if (!current_enabled) { 409 if (!current_enabled) {
343 free(filename); 410 free(filename);
@@ -353,6 +420,7 @@ int build_channel_array(const char *device_dir,
353 if (current->name == NULL) { 420 if (current->name == NULL) {
354 free(filename); 421 free(filename);
355 ret = -ENOMEM; 422 ret = -ENOMEM;
423 count--;
356 goto error_cleanup_array; 424 goto error_cleanup_array;
357 } 425 }
358 /* Get the generic and specific name elements */ 426 /* Get the generic and specific name elements */
@@ -360,6 +428,8 @@ int build_channel_array(const char *device_dir,
360 &current->generic_name); 428 &current->generic_name);
361 if (ret) { 429 if (ret) {
362 free(filename); 430 free(filename);
431 free(current->name);
432 count--;
363 goto error_cleanup_array; 433 goto error_cleanup_array;
364 } 434 }
365 ret = asprintf(&filename, 435 ret = asprintf(&filename,
@@ -372,8 +442,29 @@ int build_channel_array(const char *device_dir,
372 goto error_cleanup_array; 442 goto error_cleanup_array;
373 } 443 }
374 sysfsfp = fopen(filename, "r"); 444 sysfsfp = fopen(filename, "r");
375 fscanf(sysfsfp, "%u", &current->index); 445 if (sysfsfp == NULL) {
376 fclose(sysfsfp); 446 ret = -errno;
447 printf("failed to open %s\n", filename);
448 free(filename);
449 goto error_cleanup_array;
450 }
451
452 errno = 0;
453 if (fscanf(sysfsfp, "%u", &current->index) != 1) {
454 ret = errno ? -errno : -ENODATA;
455 if (fclose(sysfsfp))
456 perror("build_channel_array(): Failed to close file");
457
458 free(filename);
459 goto error_cleanup_array;
460 }
461
462 if (fclose(sysfsfp)) {
463 ret = -errno;
464 free(filename);
465 goto error_cleanup_array;
466 }
467
377 free(filename); 468 free(filename);
378 /* Find the scale */ 469 /* Find the scale */
379 ret = iioutils_get_param_float(&current->scale, 470 ret = iioutils_get_param_float(&current->scale,
@@ -399,38 +490,64 @@ int build_channel_array(const char *device_dir,
399 device_dir, 490 device_dir,
400 current->name, 491 current->name,
401 current->generic_name); 492 current->generic_name);
493 if (ret < 0)
494 goto error_cleanup_array;
402 } 495 }
403 } 496 }
404 497
405 closedir(dp); 498 if (closedir(dp) == -1) {
499 ret = -errno;
500 goto error_cleanup_array;
501 }
502
503 free(scan_el_dir);
406 /* reorder so that the array is in index order */ 504 /* reorder so that the array is in index order */
407 bsort_channel_array_by_index(ci_array, *counter); 505 bsort_channel_array_by_index(ci_array, *counter);
408 506
409 return 0; 507 return 0;
410 508
411error_cleanup_array: 509error_cleanup_array:
412 for (i = count - 1; i >= 0; i--) 510 for (i = count - 1; i >= 0; i--) {
413 free((*ci_array)[i].name); 511 free((*ci_array)[i].name);
512 free((*ci_array)[i].generic_name);
513 }
414 free(*ci_array); 514 free(*ci_array);
415error_close_dir: 515error_close_dir:
416 closedir(dp); 516 if (dp)
517 if (closedir(dp) == -1)
518 perror("build_channel_array(): Failed to close dir");
519
417error_free_name: 520error_free_name:
418 free(scan_el_dir); 521 free(scan_el_dir);
419error_ret: 522
420 return ret; 523 return ret;
421} 524}
422 525
526int calc_digits(int num)
527{
528 int count = 0;
529
530 while (num != 0) {
531 num /= 10;
532 count++;
533 }
534
535 return count;
536}
537
423/** 538/**
424 * find_type_by_name() - function to match top level types by name 539 * find_type_by_name() - function to match top level types by name
425 * @name: top level type instance name 540 * @name: top level type instance name
426 * @type: the type of top level instance being sort 541 * @type: the type of top level instance being searched
427 * 542 *
543 * Returns the device number of a matched IIO device on success, otherwise a
544 * negative error code.
428 * Typical types this is used for are device and trigger. 545 * Typical types this is used for are device and trigger.
429 **/ 546 **/
430int find_type_by_name(const char *name, const char *type) 547int find_type_by_name(const char *name, const char *type)
431{ 548{
432 const struct dirent *ent; 549 const struct dirent *ent;
433 int number, numstrlen; 550 int number, numstrlen, ret;
434 551
435 FILE *nameFile; 552 FILE *nameFile;
436 DIR *dp; 553 DIR *dp;
@@ -448,9 +565,19 @@ int find_type_by_name(const char *name, const char *type)
448 strcmp(ent->d_name, "..") != 0 && 565 strcmp(ent->d_name, "..") != 0 &&
449 strlen(ent->d_name) > strlen(type) && 566 strlen(ent->d_name) > strlen(type) &&
450 strncmp(ent->d_name, type, strlen(type)) == 0) { 567 strncmp(ent->d_name, type, strlen(type)) == 0) {
451 numstrlen = sscanf(ent->d_name + strlen(type), 568 errno = 0;
452 "%d", 569 ret = sscanf(ent->d_name + strlen(type), "%d", &number);
453 &number); 570 if (ret < 0) {
571 ret = -errno;
572 printf("failed to read element number\n");
573 goto error_close_dir;
574 } else if (ret != 1) {
575 ret = -EIO;
576 printf("failed to match element number\n");
577 goto error_close_dir;
578 }
579
580 numstrlen = calc_digits(number);
454 /* verify the next character is not a colon */ 581 /* verify the next character is not a colon */
455 if (strncmp(ent->d_name + strlen(type) + numstrlen, 582 if (strncmp(ent->d_name + strlen(type) + numstrlen,
456 ":", 583 ":",
@@ -460,33 +587,55 @@ int find_type_by_name(const char *name, const char *type)
460 + numstrlen 587 + numstrlen
461 + 6); 588 + 6);
462 if (filename == NULL) { 589 if (filename == NULL) {
463 closedir(dp); 590 ret = -ENOMEM;
464 return -ENOMEM; 591 goto error_close_dir;
465 } 592 }
466 sprintf(filename, "%s%s%d/name", 593
467 iio_dir, 594 ret = sprintf(filename, "%s%s%d/name", iio_dir,
468 type, 595 type, number);
469 number); 596 if (ret < 0) {
597 free(filename);
598 goto error_close_dir;
599 }
600
470 nameFile = fopen(filename, "r"); 601 nameFile = fopen(filename, "r");
471 if (!nameFile) { 602 if (!nameFile) {
472 free(filename); 603 free(filename);
473 continue; 604 continue;
474 } 605 }
475 free(filename); 606 free(filename);
476 fscanf(nameFile, "%s", thisname); 607 errno = 0;
477 fclose(nameFile); 608 if (fscanf(nameFile, "%s", thisname) != 1) {
609 ret = errno ? -errno : -ENODATA;
610 goto error_close_dir;
611 }
612
613 if (fclose(nameFile)) {
614 ret = -errno;
615 goto error_close_dir;
616 }
617
478 if (strcmp(name, thisname) == 0) { 618 if (strcmp(name, thisname) == 0) {
479 closedir(dp); 619 if (closedir(dp) == -1)
620 return -errno;
480 return number; 621 return number;
481 } 622 }
482 } 623 }
483 } 624 }
484 } 625 }
485 closedir(dp); 626 if (closedir(dp) == -1)
627 return -errno;
628
486 return -ENODEV; 629 return -ENODEV;
630
631error_close_dir:
632 if (closedir(dp) == -1)
633 perror("find_type_by_name(): Failed to close directory");
634 return ret;
487} 635}
488 636
489int _write_sysfs_int(char *filename, char *basedir, int val, int verify) 637static int _write_sysfs_int(const char *filename, const char *basedir, int val,
638 int verify)
490{ 639{
491 int ret = 0; 640 int ret = 0;
492 FILE *sysfsfp; 641 FILE *sysfsfp;
@@ -495,24 +644,49 @@ int _write_sysfs_int(char *filename, char *basedir, int val, int verify)
495 644
496 if (temp == NULL) 645 if (temp == NULL)
497 return -ENOMEM; 646 return -ENOMEM;
498 sprintf(temp, "%s/%s", basedir, filename); 647 ret = sprintf(temp, "%s/%s", basedir, filename);
648 if (ret < 0)
649 goto error_free;
650
499 sysfsfp = fopen(temp, "w"); 651 sysfsfp = fopen(temp, "w");
500 if (sysfsfp == NULL) { 652 if (sysfsfp == NULL) {
653 ret = -errno;
501 printf("failed to open %s\n", temp); 654 printf("failed to open %s\n", temp);
655 goto error_free;
656 }
657 ret = fprintf(sysfsfp, "%d", val);
658 if (ret < 0) {
659 if (fclose(sysfsfp))
660 perror("_write_sysfs_int(): Failed to close dir");
661
662 goto error_free;
663 }
664
665 if (fclose(sysfsfp)) {
502 ret = -errno; 666 ret = -errno;
503 goto error_free; 667 goto error_free;
504 } 668 }
505 fprintf(sysfsfp, "%d", val); 669
506 fclose(sysfsfp);
507 if (verify) { 670 if (verify) {
508 sysfsfp = fopen(temp, "r"); 671 sysfsfp = fopen(temp, "r");
509 if (sysfsfp == NULL) { 672 if (sysfsfp == NULL) {
673 ret = -errno;
510 printf("failed to open %s\n", temp); 674 printf("failed to open %s\n", temp);
675 goto error_free;
676 }
677 if (fscanf(sysfsfp, "%d", &test) != 1) {
678 ret = errno ? -errno : -ENODATA;
679 if (fclose(sysfsfp))
680 perror("_write_sysfs_int(): Failed to close dir");
681
682 goto error_free;
683 }
684
685 if (fclose(sysfsfp)) {
511 ret = -errno; 686 ret = -errno;
512 goto error_free; 687 goto error_free;
513 } 688 }
514 fscanf(sysfsfp, "%d", &test); 689
515 fclose(sysfsfp);
516 if (test != val) { 690 if (test != val) {
517 printf("Possible failure in int write %d to %s%s\n", 691 printf("Possible failure in int write %d to %s%s\n",
518 val, 692 val,
@@ -526,17 +700,36 @@ error_free:
526 return ret; 700 return ret;
527} 701}
528 702
529int write_sysfs_int(char *filename, char *basedir, int val) 703/**
704 * write_sysfs_int() - write an integer value to a sysfs file
705 * @filename: name of the file to write to
706 * @basedir: the sysfs directory in which the file is to be found
707 * @val: integer value to write to file
708 *
709 * Returns a value >= 0 on success, otherwise a negative error code.
710 **/
711int write_sysfs_int(const char *filename, const char *basedir, int val)
530{ 712{
531 return _write_sysfs_int(filename, basedir, val, 0); 713 return _write_sysfs_int(filename, basedir, val, 0);
532} 714}
533 715
534int write_sysfs_int_and_verify(char *filename, char *basedir, int val) 716/**
717 * write_sysfs_int_and_verify() - write an integer value to a sysfs file
718 * and verify
719 * @filename: name of the file to write to
720 * @basedir: the sysfs directory in which the file is to be found
721 * @val: integer value to write to file
722 *
723 * Returns a value >= 0 on success, otherwise a negative error code.
724 **/
725int write_sysfs_int_and_verify(const char *filename, const char *basedir,
726 int val)
535{ 727{
536 return _write_sysfs_int(filename, basedir, val, 1); 728 return _write_sysfs_int(filename, basedir, val, 1);
537} 729}
538 730
539int _write_sysfs_string(char *filename, char *basedir, char *val, int verify) 731static int _write_sysfs_string(const char *filename, const char *basedir,
732 const char *val, int verify)
540{ 733{
541 int ret = 0; 734 int ret = 0;
542 FILE *sysfsfp; 735 FILE *sysfsfp;
@@ -546,24 +739,49 @@ int _write_sysfs_string(char *filename, char *basedir, char *val, int verify)
546 printf("Memory allocation failed\n"); 739 printf("Memory allocation failed\n");
547 return -ENOMEM; 740 return -ENOMEM;
548 } 741 }
549 sprintf(temp, "%s/%s", basedir, filename); 742 ret = sprintf(temp, "%s/%s", basedir, filename);
743 if (ret < 0)
744 goto error_free;
745
550 sysfsfp = fopen(temp, "w"); 746 sysfsfp = fopen(temp, "w");
551 if (sysfsfp == NULL) { 747 if (sysfsfp == NULL) {
748 ret = -errno;
552 printf("Could not open %s\n", temp); 749 printf("Could not open %s\n", temp);
750 goto error_free;
751 }
752 ret = fprintf(sysfsfp, "%s", val);
753 if (ret < 0) {
754 if (fclose(sysfsfp))
755 perror("_write_sysfs_string(): Failed to close dir");
756
757 goto error_free;
758 }
759
760 if (fclose(sysfsfp)) {
553 ret = -errno; 761 ret = -errno;
554 goto error_free; 762 goto error_free;
555 } 763 }
556 fprintf(sysfsfp, "%s", val); 764
557 fclose(sysfsfp);
558 if (verify) { 765 if (verify) {
559 sysfsfp = fopen(temp, "r"); 766 sysfsfp = fopen(temp, "r");
560 if (sysfsfp == NULL) { 767 if (sysfsfp == NULL) {
768 ret = -errno;
561 printf("could not open file to verify\n"); 769 printf("could not open file to verify\n");
770 goto error_free;
771 }
772 if (fscanf(sysfsfp, "%s", temp) != 1) {
773 ret = errno ? -errno : -ENODATA;
774 if (fclose(sysfsfp))
775 perror("_write_sysfs_string(): Failed to close dir");
776
777 goto error_free;
778 }
779
780 if (fclose(sysfsfp)) {
562 ret = -errno; 781 ret = -errno;
563 goto error_free; 782 goto error_free;
564 } 783 }
565 fscanf(sysfsfp, "%s", temp); 784
566 fclose(sysfsfp);
567 if (strcmp(temp, val) != 0) { 785 if (strcmp(temp, val) != 0) {
568 printf("Possible failure in string write of %s " 786 printf("Possible failure in string write of %s "
569 "Should be %s " 787 "Should be %s "
@@ -586,18 +804,38 @@ error_free:
586 * @filename: name of file to write to 804 * @filename: name of file to write to
587 * @basedir: the sysfs directory in which the file is to be found 805 * @basedir: the sysfs directory in which the file is to be found
588 * @val: the string to write 806 * @val: the string to write
807 *
808 * Returns a value >= 0 on success, otherwise a negative error code.
589 **/ 809 **/
590int write_sysfs_string_and_verify(char *filename, char *basedir, char *val) 810int write_sysfs_string_and_verify(const char *filename, const char *basedir,
811 const char *val)
591{ 812{
592 return _write_sysfs_string(filename, basedir, val, 1); 813 return _write_sysfs_string(filename, basedir, val, 1);
593} 814}
594 815
595int write_sysfs_string(char *filename, char *basedir, char *val) 816/**
817 * write_sysfs_string() - write string to a sysfs file
818 * @filename: name of file to write to
819 * @basedir: the sysfs directory in which the file is to be found
820 * @val: the string to write
821 *
822 * Returns a value >= 0 on success, otherwise a negative error code.
823 **/
824int write_sysfs_string(const char *filename, const char *basedir,
825 const char *val)
596{ 826{
597 return _write_sysfs_string(filename, basedir, val, 0); 827 return _write_sysfs_string(filename, basedir, val, 0);
598} 828}
599 829
600int read_sysfs_posint(char *filename, char *basedir) 830/**
831 * read_sysfs_posint() - read an integer value from file
832 * @filename: name of file to read from
833 * @basedir: the sysfs directory in which the file is to be found
834 *
835 * Returns the read integer value >= 0 on success, otherwise a negative error
836 * code.
837 **/
838int read_sysfs_posint(const char *filename, const char *basedir)
601{ 839{
602 int ret; 840 int ret;
603 FILE *sysfsfp; 841 FILE *sysfsfp;
@@ -607,20 +845,41 @@ int read_sysfs_posint(char *filename, char *basedir)
607 printf("Memory allocation failed"); 845 printf("Memory allocation failed");
608 return -ENOMEM; 846 return -ENOMEM;
609 } 847 }
610 sprintf(temp, "%s/%s", basedir, filename); 848 ret = sprintf(temp, "%s/%s", basedir, filename);
849 if (ret < 0)
850 goto error_free;
851
611 sysfsfp = fopen(temp, "r"); 852 sysfsfp = fopen(temp, "r");
612 if (sysfsfp == NULL) { 853 if (sysfsfp == NULL) {
613 ret = -errno; 854 ret = -errno;
614 goto error_free; 855 goto error_free;
615 } 856 }
616 fscanf(sysfsfp, "%d\n", &ret); 857 errno = 0;
617 fclose(sysfsfp); 858 if (fscanf(sysfsfp, "%d\n", &ret) != 1) {
859 ret = errno ? -errno : -ENODATA;
860 if (fclose(sysfsfp))
861 perror("read_sysfs_posint(): Failed to close dir");
862
863 goto error_free;
864 }
865
866 if (fclose(sysfsfp))
867 ret = -errno;
868
618error_free: 869error_free:
619 free(temp); 870 free(temp);
620 return ret; 871 return ret;
621} 872}
622 873
623int read_sysfs_float(char *filename, char *basedir, float *val) 874/**
875 * read_sysfs_float() - read a float value from file
876 * @filename: name of file to read from
877 * @basedir: the sysfs directory in which the file is to be found
878 * @val: output the read float value
879 *
880 * Returns a value >= 0 on success, otherwise a negative error code.
881 **/
882int read_sysfs_float(const char *filename, const char *basedir, float *val)
624{ 883{
625 int ret = 0; 884 int ret = 0;
626 FILE *sysfsfp; 885 FILE *sysfsfp;
@@ -630,19 +889,40 @@ int read_sysfs_float(char *filename, char *basedir, float *val)
630 printf("Memory allocation failed"); 889 printf("Memory allocation failed");
631 return -ENOMEM; 890 return -ENOMEM;
632 } 891 }
633 sprintf(temp, "%s/%s", basedir, filename); 892 ret = sprintf(temp, "%s/%s", basedir, filename);
893 if (ret < 0)
894 goto error_free;
895
634 sysfsfp = fopen(temp, "r"); 896 sysfsfp = fopen(temp, "r");
635 if (sysfsfp == NULL) { 897 if (sysfsfp == NULL) {
636 ret = -errno; 898 ret = -errno;
637 goto error_free; 899 goto error_free;
638 } 900 }
639 fscanf(sysfsfp, "%f\n", val); 901 errno = 0;
640 fclose(sysfsfp); 902 if (fscanf(sysfsfp, "%f\n", val) != 1) {
903 ret = errno ? -errno : -ENODATA;
904 if (fclose(sysfsfp))
905 perror("read_sysfs_float(): Failed to close dir");
906
907 goto error_free;
908 }
909
910 if (fclose(sysfsfp))
911 ret = -errno;
912
641error_free: 913error_free:
642 free(temp); 914 free(temp);
643 return ret; 915 return ret;
644} 916}
645 917
918/**
919 * read_sysfs_string() - read a string from file
920 * @filename: name of file to read from
921 * @basedir: the sysfs directory in which the file is to be found
922 * @str: output the read string
923 *
924 * Returns a value >= 0 on success, otherwise a negative error code.
925 **/
646int read_sysfs_string(const char *filename, const char *basedir, char *str) 926int read_sysfs_string(const char *filename, const char *basedir, char *str)
647{ 927{
648 int ret = 0; 928 int ret = 0;
@@ -653,14 +933,27 @@ int read_sysfs_string(const char *filename, const char *basedir, char *str)
653 printf("Memory allocation failed"); 933 printf("Memory allocation failed");
654 return -ENOMEM; 934 return -ENOMEM;
655 } 935 }
656 sprintf(temp, "%s/%s", basedir, filename); 936 ret = sprintf(temp, "%s/%s", basedir, filename);
937 if (ret < 0)
938 goto error_free;
939
657 sysfsfp = fopen(temp, "r"); 940 sysfsfp = fopen(temp, "r");
658 if (sysfsfp == NULL) { 941 if (sysfsfp == NULL) {
659 ret = -errno; 942 ret = -errno;
660 goto error_free; 943 goto error_free;
661 } 944 }
662 fscanf(sysfsfp, "%s\n", str); 945 errno = 0;
663 fclose(sysfsfp); 946 if (fscanf(sysfsfp, "%s\n", str) != 1) {
947 ret = errno ? -errno : -ENODATA;
948 if (fclose(sysfsfp))
949 perror("read_sysfs_string(): Failed to close dir");
950
951 goto error_free;
952 }
953
954 if (fclose(sysfsfp))
955 ret = -errno;
956
664error_free: 957error_free:
665 free(temp); 958 free(temp);
666 return ret; 959 return ret;
diff --git a/tools/iio/iio_utils.h b/tools/iio/iio_utils.h
index 1bc837b2d769..379eed9deaea 100644
--- a/tools/iio/iio_utils.h
+++ b/tools/iio/iio_utils.h
@@ -28,9 +28,12 @@ extern const char *iio_dir;
28 * @offset: offset to be applied for conversion to si units 28 * @offset: offset to be applied for conversion to si units
29 * @index: the channel index in the buffer output 29 * @index: the channel index in the buffer output
30 * @bytes: number of bytes occupied in buffer output 30 * @bytes: number of bytes occupied in buffer output
31 * @bits_used: number of valid bits of data
32 * @shift: amount of bits to shift right data before applying bit mask
31 * @mask: a bit mask for the raw output 33 * @mask: a bit mask for the raw output
34 * @be: flag if data is big endian
32 * @is_signed: is the raw value stored signed 35 * @is_signed: is the raw value stored signed
33 * @enabled: is this channel enabled 36 * @location: data offset for this channel inside the buffer (in bytes)
34 **/ 37 **/
35struct iio_channel_info { 38struct iio_channel_info {
36 char *name; 39 char *name;
@@ -60,12 +63,15 @@ void bsort_channel_array_by_index(struct iio_channel_info **ci_array, int cnt);
60int build_channel_array(const char *device_dir, 63int build_channel_array(const char *device_dir,
61 struct iio_channel_info **ci_array, int *counter); 64 struct iio_channel_info **ci_array, int *counter);
62int find_type_by_name(const char *name, const char *type); 65int find_type_by_name(const char *name, const char *type);
63int write_sysfs_int(char *filename, char *basedir, int val); 66int write_sysfs_int(const char *filename, const char *basedir, int val);
64int write_sysfs_int_and_verify(char *filename, char *basedir, int val); 67int write_sysfs_int_and_verify(const char *filename, const char *basedir,
65int write_sysfs_string_and_verify(char *filename, char *basedir, char *val); 68 int val);
66int write_sysfs_string(char *filename, char *basedir, char *val); 69int write_sysfs_string_and_verify(const char *filename, const char *basedir,
67int read_sysfs_posint(char *filename, char *basedir); 70 const char *val);
68int read_sysfs_float(char *filename, char *basedir, float *val); 71int write_sysfs_string(const char *filename, const char *basedir,
72 const char *val);
73int read_sysfs_posint(const char *filename, const char *basedir);
74int read_sysfs_float(const char *filename, const char *basedir, float *val);
69int read_sysfs_string(const char *filename, const char *basedir, char *str); 75int read_sysfs_string(const char *filename, const char *basedir, char *str);
70 76
71#endif /* _IIO_UTILS_H_ */ 77#endif /* _IIO_UTILS_H_ */
diff --git a/tools/iio/lsiio.c b/tools/iio/lsiio.c
index c585440f864e..b59ee1733924 100644
--- a/tools/iio/lsiio.c
+++ b/tools/iio/lsiio.c
@@ -56,7 +56,7 @@ static int dump_channels(const char *dev_dir_name)
56 printf(" %-10s\n", ent->d_name); 56 printf(" %-10s\n", ent->d_name);
57 } 57 }
58 58
59 return 0; 59 return (closedir(dp) == -1) ? -errno : 0;
60} 60}
61 61
62static int dump_one_device(const char *dev_dir_name) 62static int dump_one_device(const char *dev_dir_name)
@@ -69,7 +69,10 @@ static int dump_one_device(const char *dev_dir_name)
69 "%i", &dev_idx); 69 "%i", &dev_idx);
70 if (retval != 1) 70 if (retval != 1)
71 return -EINVAL; 71 return -EINVAL;
72 read_sysfs_string("name", dev_dir_name, name); 72 retval = read_sysfs_string("name", dev_dir_name, name);
73 if (retval)
74 return retval;
75
73 printf("Device %03d: %s\n", dev_idx, name); 76 printf("Device %03d: %s\n", dev_idx, name);
74 77
75 if (verblevel >= VERBLEVEL_SENSORS) 78 if (verblevel >= VERBLEVEL_SENSORS)
@@ -87,28 +90,42 @@ static int dump_one_trigger(const char *dev_dir_name)
87 "%i", &dev_idx); 90 "%i", &dev_idx);
88 if (retval != 1) 91 if (retval != 1)
89 return -EINVAL; 92 return -EINVAL;
90 read_sysfs_string("name", dev_dir_name, name); 93 retval = read_sysfs_string("name", dev_dir_name, name);
94 if (retval)
95 return retval;
96
91 printf("Trigger %03d: %s\n", dev_idx, name); 97 printf("Trigger %03d: %s\n", dev_idx, name);
92 return 0; 98 return 0;
93} 99}
94 100
95static void dump_devices(void) 101static int dump_devices(void)
96{ 102{
97 const struct dirent *ent; 103 const struct dirent *ent;
104 int ret;
98 DIR *dp; 105 DIR *dp;
99 106
100 dp = opendir(iio_dir); 107 dp = opendir(iio_dir);
101 if (dp == NULL) { 108 if (dp == NULL) {
102 printf("No industrial I/O devices available\n"); 109 printf("No industrial I/O devices available\n");
103 return; 110 return -ENODEV;
104 } 111 }
105 112
106 while (ent = readdir(dp), ent != NULL) { 113 while (ent = readdir(dp), ent != NULL) {
107 if (check_prefix(ent->d_name, type_device)) { 114 if (check_prefix(ent->d_name, type_device)) {
108 char *dev_dir_name; 115 char *dev_dir_name;
109 116
110 asprintf(&dev_dir_name, "%s%s", iio_dir, ent->d_name); 117 if (asprintf(&dev_dir_name, "%s%s", iio_dir,
111 dump_one_device(dev_dir_name); 118 ent->d_name) < 0) {
119 ret = -ENOMEM;
120 goto error_close_dir;
121 }
122
123 ret = dump_one_device(dev_dir_name);
124 if (ret) {
125 free(dev_dir_name);
126 goto error_close_dir;
127 }
128
112 free(dev_dir_name); 129 free(dev_dir_name);
113 if (verblevel >= VERBLEVEL_SENSORS) 130 if (verblevel >= VERBLEVEL_SENSORS)
114 printf("\n"); 131 printf("\n");
@@ -119,19 +136,35 @@ static void dump_devices(void)
119 if (check_prefix(ent->d_name, type_trigger)) { 136 if (check_prefix(ent->d_name, type_trigger)) {
120 char *dev_dir_name; 137 char *dev_dir_name;
121 138
122 asprintf(&dev_dir_name, "%s%s", iio_dir, ent->d_name); 139 if (asprintf(&dev_dir_name, "%s%s", iio_dir,
123 dump_one_trigger(dev_dir_name); 140 ent->d_name) < 0) {
141 ret = -ENOMEM;
142 goto error_close_dir;
143 }
144
145 ret = dump_one_trigger(dev_dir_name);
146 if (ret) {
147 free(dev_dir_name);
148 goto error_close_dir;
149 }
150
124 free(dev_dir_name); 151 free(dev_dir_name);
125 } 152 }
126 } 153 }
127 closedir(dp); 154 return (closedir(dp) == -1) ? -errno : 0;
155
156error_close_dir:
157 if (closedir(dp) == -1)
158 perror("dump_devices(): Failed to close directory");
159
160 return ret;
128} 161}
129 162
130int main(int argc, char **argv) 163int main(int argc, char **argv)
131{ 164{
132 int c, err = 0; 165 int c, err = 0;
133 166
134 while ((c = getopt(argc, argv, "d:D:v")) != EOF) { 167 while ((c = getopt(argc, argv, "v")) != EOF) {
135 switch (c) { 168 switch (c) {
136 case 'v': 169 case 'v':
137 verblevel++; 170 verblevel++;
@@ -146,13 +179,9 @@ int main(int argc, char **argv)
146 if (err || argc > optind) { 179 if (err || argc > optind) {
147 fprintf(stderr, "Usage: lsiio [options]...\n" 180 fprintf(stderr, "Usage: lsiio [options]...\n"
148 "List industrial I/O devices\n" 181 "List industrial I/O devices\n"
149 " -v, --verbose\n" 182 " -v Increase verbosity (may be given multiple times)\n");
150 " Increase verbosity (may be given multiple times)\n"
151 );
152 exit(1); 183 exit(1);
153 } 184 }
154 185
155 dump_devices(); 186 return dump_devices();
156
157 return 0;
158} 187}