diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-26 18:46:08 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-26 18:46:08 -0400 |
commit | 23908db413eccd77084b09c9b0a4451dfb0524c0 (patch) | |
tree | 646f21a92496bdc04175e95642b0ecb2dc3dd09e /tools | |
parent | 8d7804a2f03dbd34940fcb426450c730adf29dae (diff) | |
parent | 53a20e9e378ecd52f0afa4b60f8f8c81b6f97c27 (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/Makefile | 8 | ||||
-rw-r--r-- | tools/iio/Makefile | 4 | ||||
-rw-r--r-- | tools/iio/generic_buffer.c | 200 | ||||
-rw-r--r-- | tools/iio/iio_event_monitor.c | 50 | ||||
-rw-r--r-- | tools/iio/iio_utils.c | 469 | ||||
-rw-r--r-- | tools/iio/iio_utils.h | 20 | ||||
-rw-r--r-- | tools/iio/lsiio.c | 63 |
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 | |||
47 | cpupower: FORCE | 48 | cpupower: FORCE |
48 | $(call descend,power/$@) | 49 | $(call descend,power/$@) |
49 | 50 | ||
50 | cgroup firewire hv guest usb virtio vm net: FORCE | 51 | cgroup firewire hv guest usb virtio vm net iio: FORCE |
51 | $(call descend,$@) | 52 | $(call descend,$@) |
52 | 53 | ||
53 | liblockdep: FORCE | 54 | liblockdep: FORCE |
@@ -108,7 +109,7 @@ acpi_clean: | |||
108 | cpupower_clean: | 109 | cpupower_clean: |
109 | $(call descend,power/cpupower,clean) | 110 | $(call descend,power/cpupower,clean) |
110 | 111 | ||
111 | cgroup_clean hv_clean firewire_clean lguest_clean usb_clean virtio_clean vm_clean net_clean: | 112 | cgroup_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 | ||
114 | liblockdep_clean: | 115 | liblockdep_clean: |
@@ -134,6 +135,7 @@ freefall_clean: | |||
134 | 135 | ||
135 | clean: acpi_clean cgroup_clean cpupower_clean hv_clean firewire_clean lguest_clean \ | 136 | clean: 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 @@ | |||
1 | CC = gcc | 1 | CC = $(CROSS_COMPILE)gcc |
2 | CFLAGS = -Wall -g -D_GNU_SOURCE | 2 | CFLAGS += -Wall -g -D_GNU_SOURCE |
3 | 3 | ||
4 | all: iio_event_monitor lsiio generic_buffer | 4 | all: 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 | ||
62 | void print2byte(int input, struct iio_channel_info *info) | 62 | void 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 | |||
85 | void 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; | 108 | void 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 | ||
171 | void 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 | |||
144 | int main(int argc, char **argv) | 184 | int 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 | ||
346 | error_close_buffer_access: | 409 | error_close_buffer_access: |
347 | close(fp); | 410 | if (close(fp) == -1) |
348 | error_free_data: | 411 | perror("Failed to close buffer"); |
349 | free(data); | ||
350 | error_free_buffer_access: | 412 | error_free_buffer_access: |
351 | free(buffer_access); | 413 | free(buffer_access); |
414 | error_free_data: | ||
415 | free(data); | ||
352 | error_free_buf_dir_name: | 416 | error_free_buf_dir_name: |
353 | free(buf_dir_name); | 417 | free(buf_dir_name); |
418 | error_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); | ||
354 | error_free_triggername: | 424 | error_free_triggername: |
355 | if (datardytrigger) | 425 | if (datardytrigger) |
356 | free(trigger_name); | 426 | free(trigger_name); |
357 | error_ret: | 427 | error_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 | |||
304 | error_free_chrdev_name: | 308 | error_free_chrdev_name: |
305 | free(chrdev_name); | 309 | free(chrdev_name); |
306 | error_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 | **/ |
33 | int iioutils_break_up_name(const char *full_name, | 35 | int 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 | **/ |
78 | int iioutils_get_type(unsigned *is_signed, | 91 | int 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 | } |
164 | error_close_sysfsfp: | 183 | error_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 | |||
167 | error_free_filename: | 188 | error_free_filename: |
168 | if (filename) | 189 | if (filename) |
169 | free(filename); | 190 | free(filename); |
170 | error_closedir: | 191 | error_closedir: |
171 | closedir(dp); | 192 | if (closedir(dp) == -1) |
193 | perror("iioutils_get_type(): Failed to close directory"); | ||
194 | |||
172 | error_free_builtname_generic: | 195 | error_free_builtname_generic: |
173 | free(builtname_generic); | 196 | free(builtname_generic); |
174 | error_free_builtname: | 197 | error_free_builtname: |
175 | free(builtname); | 198 | free(builtname); |
176 | error_free_scan_el_dir: | 199 | error_free_scan_el_dir: |
177 | free(scan_el_dir); | 200 | free(scan_el_dir); |
178 | error_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 | **/ | ||
182 | int iioutils_get_param_float(float *output, | 215 | int 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 | } |
228 | error_free_filename: | 264 | error_free_filename: |
229 | if (filename) | 265 | if (filename) |
230 | free(filename); | 266 | free(filename); |
231 | error_closedir: | 267 | error_closedir: |
232 | closedir(dp); | 268 | if (closedir(dp) == -1) |
269 | perror("iioutils_get_param_float(): Failed to close directory"); | ||
270 | |||
233 | error_free_builtname_generic: | 271 | error_free_builtname_generic: |
234 | free(builtname_generic); | 272 | free(builtname_generic); |
235 | error_free_builtname: | 273 | error_free_builtname: |
236 | free(builtname); | 274 | free(builtname); |
237 | error_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 | ||
246 | void bsort_channel_array_by_index(struct iio_channel_info **ci_array, | 285 | void 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 | **/ |
267 | int build_channel_array(const char *device_dir, | 309 | int 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", ¤t_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", ¤t_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 | ¤t->generic_name); | 428 | ¤t->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", ¤t->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", ¤t->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(¤t->scale, | 470 | ret = iioutils_get_param_float(¤t->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 | ||
411 | error_cleanup_array: | 509 | error_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); |
415 | error_close_dir: | 515 | error_close_dir: |
416 | closedir(dp); | 516 | if (dp) |
517 | if (closedir(dp) == -1) | ||
518 | perror("build_channel_array(): Failed to close dir"); | ||
519 | |||
417 | error_free_name: | 520 | error_free_name: |
418 | free(scan_el_dir); | 521 | free(scan_el_dir); |
419 | error_ret: | 522 | |
420 | return ret; | 523 | return ret; |
421 | } | 524 | } |
422 | 525 | ||
526 | int 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 | **/ |
430 | int find_type_by_name(const char *name, const char *type) | 547 | int 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 | |||
631 | error_close_dir: | ||
632 | if (closedir(dp) == -1) | ||
633 | perror("find_type_by_name(): Failed to close directory"); | ||
634 | return ret; | ||
487 | } | 635 | } |
488 | 636 | ||
489 | int _write_sysfs_int(char *filename, char *basedir, int val, int verify) | 637 | static 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 | ||
529 | int 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 | **/ | ||
711 | int 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 | ||
534 | int 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 | **/ | ||
725 | int 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 | ||
539 | int _write_sysfs_string(char *filename, char *basedir, char *val, int verify) | 731 | static 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 | **/ |
590 | int write_sysfs_string_and_verify(char *filename, char *basedir, char *val) | 810 | int 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 | ||
595 | int 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 | **/ | ||
824 | int 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 | ||
600 | int 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 | **/ | ||
838 | int 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 | |||
618 | error_free: | 869 | error_free: |
619 | free(temp); | 870 | free(temp); |
620 | return ret; | 871 | return ret; |
621 | } | 872 | } |
622 | 873 | ||
623 | int 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 | **/ | ||
882 | int 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 | |||
641 | error_free: | 913 | error_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 | **/ | ||
646 | int read_sysfs_string(const char *filename, const char *basedir, char *str) | 926 | int 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 | |||
664 | error_free: | 957 | error_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 | **/ |
35 | struct iio_channel_info { | 38 | struct 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); | |||
60 | int build_channel_array(const char *device_dir, | 63 | int 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); |
62 | int find_type_by_name(const char *name, const char *type); | 65 | int find_type_by_name(const char *name, const char *type); |
63 | int write_sysfs_int(char *filename, char *basedir, int val); | 66 | int write_sysfs_int(const char *filename, const char *basedir, int val); |
64 | int write_sysfs_int_and_verify(char *filename, char *basedir, int val); | 67 | int write_sysfs_int_and_verify(const char *filename, const char *basedir, |
65 | int write_sysfs_string_and_verify(char *filename, char *basedir, char *val); | 68 | int val); |
66 | int write_sysfs_string(char *filename, char *basedir, char *val); | 69 | int write_sysfs_string_and_verify(const char *filename, const char *basedir, |
67 | int read_sysfs_posint(char *filename, char *basedir); | 70 | const char *val); |
68 | int read_sysfs_float(char *filename, char *basedir, float *val); | 71 | int write_sysfs_string(const char *filename, const char *basedir, |
72 | const char *val); | ||
73 | int read_sysfs_posint(const char *filename, const char *basedir); | ||
74 | int read_sysfs_float(const char *filename, const char *basedir, float *val); | ||
69 | int read_sysfs_string(const char *filename, const char *basedir, char *str); | 75 | int 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 | ||
62 | static int dump_one_device(const char *dev_dir_name) | 62 | static 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 | ||
95 | static void dump_devices(void) | 101 | static 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 | |||
156 | error_close_dir: | ||
157 | if (closedir(dp) == -1) | ||
158 | perror("dump_devices(): Failed to close directory"); | ||
159 | |||
160 | return ret; | ||
128 | } | 161 | } |
129 | 162 | ||
130 | int main(int argc, char **argv) | 163 | int 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 | } |