linux/tools/iio/iio_generic_buffer.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/* Industrialio buffer test code.
   3 *
   4 * Copyright (c) 2008 Jonathan Cameron
   5 *
   6 * This program is primarily intended as an example application.
   7 * Reads the current buffer setup from sysfs and starts a short capture
   8 * from the specified device, pretty printing the result after appropriate
   9 * conversion.
  10 *
  11 * Command line parameters
  12 * generic_buffer -n <device_name> -t <trigger_name>
  13 * If trigger name is not specified the program assumes you want a dataready
  14 * trigger associated with the device and goes looking for it.
  15 */
  16
  17#include <unistd.h>
  18#include <stdlib.h>
  19#include <dirent.h>
  20#include <fcntl.h>
  21#include <stdio.h>
  22#include <errno.h>
  23#include <sys/stat.h>
  24#include <sys/dir.h>
  25#include <linux/types.h>
  26#include <string.h>
  27#include <poll.h>
  28#include <endian.h>
  29#include <getopt.h>
  30#include <inttypes.h>
  31#include <stdbool.h>
  32#include <signal.h>
  33#include <sys/ioctl.h>
  34#include <linux/iio/buffer.h>
  35#include "iio_utils.h"
  36
  37/**
  38 * enum autochan - state for the automatic channel enabling mechanism
  39 */
  40enum autochan {
  41        AUTOCHANNELS_DISABLED,
  42        AUTOCHANNELS_ENABLED,
  43        AUTOCHANNELS_ACTIVE,
  44};
  45
  46/**
  47 * size_from_channelarray() - calculate the storage size of a scan
  48 * @channels:           the channel info array
  49 * @num_channels:       number of channels
  50 *
  51 * Has the side effect of filling the channels[i].location values used
  52 * in processing the buffer output.
  53 **/
  54static int size_from_channelarray(struct iio_channel_info *channels, int num_channels)
  55{
  56        int bytes = 0;
  57        int i = 0;
  58
  59        while (i < num_channels) {
  60                if (bytes % channels[i].bytes == 0)
  61                        channels[i].location = bytes;
  62                else
  63                        channels[i].location = bytes - bytes % channels[i].bytes
  64                                               + channels[i].bytes;
  65
  66                bytes = channels[i].location + channels[i].bytes;
  67                i++;
  68        }
  69
  70        return bytes;
  71}
  72
  73static void print1byte(uint8_t input, struct iio_channel_info *info)
  74{
  75        /*
  76         * Shift before conversion to avoid sign extension
  77         * of left aligned data
  78         */
  79        input >>= info->shift;
  80        input &= info->mask;
  81        if (info->is_signed) {
  82                int8_t val = (int8_t)(input << (8 - info->bits_used)) >>
  83                             (8 - info->bits_used);
  84                printf("%05f ", ((float)val + info->offset) * info->scale);
  85        } else {
  86                printf("%05f ", ((float)input + info->offset) * info->scale);
  87        }
  88}
  89
  90static void print2byte(uint16_t input, struct iio_channel_info *info)
  91{
  92        /* First swap if incorrect endian */
  93        if (info->be)
  94                input = be16toh(input);
  95        else
  96                input = le16toh(input);
  97
  98        /*
  99         * Shift before conversion to avoid sign extension
 100         * of left aligned data
 101         */
 102        input >>= info->shift;
 103        input &= info->mask;
 104        if (info->is_signed) {
 105                int16_t val = (int16_t)(input << (16 - info->bits_used)) >>
 106                              (16 - info->bits_used);
 107                printf("%05f ", ((float)val + info->offset) * info->scale);
 108        } else {
 109                printf("%05f ", ((float)input + info->offset) * info->scale);
 110        }
 111}
 112
 113static void print4byte(uint32_t input, struct iio_channel_info *info)
 114{
 115        /* First swap if incorrect endian */
 116        if (info->be)
 117                input = be32toh(input);
 118        else
 119                input = le32toh(input);
 120
 121        /*
 122         * Shift before conversion to avoid sign extension
 123         * of left aligned data
 124         */
 125        input >>= info->shift;
 126        input &= info->mask;
 127        if (info->is_signed) {
 128                int32_t val = (int32_t)(input << (32 - info->bits_used)) >>
 129                              (32 - info->bits_used);
 130                printf("%05f ", ((float)val + info->offset) * info->scale);
 131        } else {
 132                printf("%05f ", ((float)input + info->offset) * info->scale);
 133        }
 134}
 135
 136static void print8byte(uint64_t input, struct iio_channel_info *info)
 137{
 138        /* First swap if incorrect endian */
 139        if (info->be)
 140                input = be64toh(input);
 141        else
 142                input = le64toh(input);
 143
 144        /*
 145         * Shift before conversion to avoid sign extension
 146         * of left aligned data
 147         */
 148        input >>= info->shift;
 149        input &= info->mask;
 150        if (info->is_signed) {
 151                int64_t val = (int64_t)(input << (64 - info->bits_used)) >>
 152                              (64 - info->bits_used);
 153                /* special case for timestamp */
 154                if (info->scale == 1.0f && info->offset == 0.0f)
 155                        printf("%" PRId64 " ", val);
 156                else
 157                        printf("%05f ",
 158                               ((float)val + info->offset) * info->scale);
 159        } else {
 160                printf("%05f ", ((float)input + info->offset) * info->scale);
 161        }
 162}
 163
 164/**
 165 * process_scan() - print out the values in SI units
 166 * @data:               pointer to the start of the scan
 167 * @channels:           information about the channels.
 168 *                      Note: size_from_channelarray must have been called first
 169 *                            to fill the location offsets.
 170 * @num_channels:       number of channels
 171 **/
 172static void process_scan(char *data, struct iio_channel_info *channels,
 173                         int num_channels)
 174{
 175        int k;
 176
 177        for (k = 0; k < num_channels; k++)
 178                switch (channels[k].bytes) {
 179                        /* only a few cases implemented so far */
 180                case 1:
 181                        print1byte(*(uint8_t *)(data + channels[k].location),
 182                                   &channels[k]);
 183                        break;
 184                case 2:
 185                        print2byte(*(uint16_t *)(data + channels[k].location),
 186                                   &channels[k]);
 187                        break;
 188                case 4:
 189                        print4byte(*(uint32_t *)(data + channels[k].location),
 190                                   &channels[k]);
 191                        break;
 192                case 8:
 193                        print8byte(*(uint64_t *)(data + channels[k].location),
 194                                   &channels[k]);
 195                        break;
 196                default:
 197                        break;
 198                }
 199        printf("\n");
 200}
 201
 202static int enable_disable_all_channels(char *dev_dir_name, int buffer_idx, int enable)
 203{
 204        const struct dirent *ent;
 205        char scanelemdir[256];
 206        DIR *dp;
 207        int ret;
 208
 209        snprintf(scanelemdir, sizeof(scanelemdir),
 210                 FORMAT_SCAN_ELEMENTS_DIR, dev_dir_name, buffer_idx);
 211        scanelemdir[sizeof(scanelemdir)-1] = '\0';
 212
 213        dp = opendir(scanelemdir);
 214        if (!dp) {
 215                fprintf(stderr, "Enabling/disabling channels: can't open %s\n",
 216                        scanelemdir);
 217                return -EIO;
 218        }
 219
 220        ret = -ENOENT;
 221        while (ent = readdir(dp), ent) {
 222                if (iioutils_check_suffix(ent->d_name, "_en")) {
 223                        printf("%sabling: %s\n",
 224                               enable ? "En" : "Dis",
 225                               ent->d_name);
 226                        ret = write_sysfs_int(ent->d_name, scanelemdir,
 227                                              enable);
 228                        if (ret < 0)
 229                                fprintf(stderr, "Failed to enable/disable %s\n",
 230                                        ent->d_name);
 231                }
 232        }
 233
 234        if (closedir(dp) == -1) {
 235                perror("Enabling/disabling channels: "
 236                       "Failed to close directory");
 237                return -errno;
 238        }
 239        return 0;
 240}
 241
 242static void print_usage(void)
 243{
 244        fprintf(stderr, "Usage: generic_buffer [options]...\n"
 245                "Capture, convert and output data from IIO device buffer\n"
 246                "  -a         Auto-activate all available channels\n"
 247                "  -A         Force-activate ALL channels\n"
 248                "  -b <n>     The buffer which to open (by index), default 0\n"
 249                "  -c <n>     Do n conversions, or loop forever if n < 0\n"
 250                "  -e         Disable wait for event (new data)\n"
 251                "  -g         Use trigger-less mode\n"
 252                "  -l <n>     Set buffer length to n samples\n"
 253                "  --device-name -n <name>\n"
 254                "  --device-num -N <num>\n"
 255                "        Set device by name or number (mandatory)\n"
 256                "  --trigger-name -t <name>\n"
 257                "  --trigger-num -T <num>\n"
 258                "        Set trigger by name or number\n"
 259                "  -w <n>     Set delay between reads in us (event-less mode)\n");
 260}
 261
 262static enum autochan autochannels = AUTOCHANNELS_DISABLED;
 263static char *dev_dir_name = NULL;
 264static char *buf_dir_name = NULL;
 265static int buffer_idx = 0;
 266static bool current_trigger_set = false;
 267
 268static void cleanup(void)
 269{
 270        int ret;
 271
 272        /* Disable trigger */
 273        if (dev_dir_name && current_trigger_set) {
 274                /* Disconnect the trigger - just write a dummy name. */
 275                ret = write_sysfs_string("trigger/current_trigger",
 276                                         dev_dir_name, "NULL");
 277                if (ret < 0)
 278                        fprintf(stderr, "Failed to disable trigger: %s\n",
 279                                strerror(-ret));
 280                current_trigger_set = false;
 281        }
 282
 283        /* Disable buffer */
 284        if (buf_dir_name) {
 285                ret = write_sysfs_int("enable", buf_dir_name, 0);
 286                if (ret < 0)
 287                        fprintf(stderr, "Failed to disable buffer: %s\n",
 288                                strerror(-ret));
 289        }
 290
 291        /* Disable channels if auto-enabled */
 292        if (dev_dir_name && autochannels == AUTOCHANNELS_ACTIVE) {
 293                ret = enable_disable_all_channels(dev_dir_name, buffer_idx, 0);
 294                if (ret)
 295                        fprintf(stderr, "Failed to disable all channels\n");
 296                autochannels = AUTOCHANNELS_DISABLED;
 297        }
 298}
 299
 300static void sig_handler(int signum)
 301{
 302        fprintf(stderr, "Caught signal %d\n", signum);
 303        cleanup();
 304        exit(-signum);
 305}
 306
 307static void register_cleanup(void)
 308{
 309        struct sigaction sa = { .sa_handler = sig_handler };
 310        const int signums[] = { SIGINT, SIGTERM, SIGABRT };
 311        int ret, i;
 312
 313        for (i = 0; i < ARRAY_SIZE(signums); ++i) {
 314                ret = sigaction(signums[i], &sa, NULL);
 315                if (ret) {
 316                        perror("Failed to register signal handler");
 317                        exit(-1);
 318                }
 319        }
 320}
 321
 322static const struct option longopts[] = {
 323        { "device-name",        1, 0, 'n' },
 324        { "device-num",         1, 0, 'N' },
 325        { "trigger-name",       1, 0, 't' },
 326        { "trigger-num",        1, 0, 'T' },
 327        { },
 328};
 329
 330int main(int argc, char **argv)
 331{
 332        long long num_loops = 2;
 333        unsigned long timedelay = 1000000;
 334        unsigned long buf_len = 128;
 335
 336        ssize_t i;
 337        unsigned long long j;
 338        unsigned long toread;
 339        int ret, c;
 340        struct stat st;
 341        int fd = -1;
 342        int buf_fd = -1;
 343
 344        int num_channels = 0;
 345        char *trigger_name = NULL, *device_name = NULL;
 346
 347        char *data = NULL;
 348        ssize_t read_size;
 349        int dev_num = -1, trig_num = -1;
 350        char *buffer_access = NULL;
 351        int scan_size;
 352        int noevents = 0;
 353        int notrigger = 0;
 354        char *dummy;
 355        bool force_autochannels = false;
 356
 357        struct iio_channel_info *channels = NULL;
 358
 359        register_cleanup();
 360
 361        while ((c = getopt_long(argc, argv, "aAb:c:egl:n:N:t:T:w:?", longopts,
 362                                NULL)) != -1) {
 363                switch (c) {
 364                case 'a':
 365                        autochannels = AUTOCHANNELS_ENABLED;
 366                        break;
 367                case 'A':
 368                        autochannels = AUTOCHANNELS_ENABLED;
 369                        force_autochannels = true;
 370                        break;
 371                case 'b':
 372                        errno = 0;
 373                        buffer_idx = strtoll(optarg, &dummy, 10);
 374                        if (errno) {
 375                                ret = -errno;
 376                                goto error;
 377                        }
 378                        if (buffer_idx < 0) {
 379                                ret = -ERANGE;
 380                                goto error;
 381                        }
 382
 383                        break;
 384                case 'c':
 385                        errno = 0;
 386                        num_loops = strtoll(optarg, &dummy, 10);
 387                        if (errno) {
 388                                ret = -errno;
 389                                goto error;
 390                        }
 391
 392                        break;
 393                case 'e':
 394                        noevents = 1;
 395                        break;
 396                case 'g':
 397                        notrigger = 1;
 398                        break;
 399                case 'l':
 400                        errno = 0;
 401                        buf_len = strtoul(optarg, &dummy, 10);
 402                        if (errno) {
 403                                ret = -errno;
 404                                goto error;
 405                        }
 406
 407                        break;
 408                case 'n':
 409                        device_name = strdup(optarg);
 410                        break;
 411                case 'N':
 412                        errno = 0;
 413                        dev_num = strtoul(optarg, &dummy, 10);
 414                        if (errno) {
 415                                ret = -errno;
 416                                goto error;
 417                        }
 418                        break;
 419                case 't':
 420                        trigger_name = strdup(optarg);
 421                        break;
 422                case 'T':
 423                        errno = 0;
 424                        trig_num = strtoul(optarg, &dummy, 10);
 425                        if (errno)
 426                                return -errno;
 427                        break;
 428                case 'w':
 429                        errno = 0;
 430                        timedelay = strtoul(optarg, &dummy, 10);
 431                        if (errno) {
 432                                ret = -errno;
 433                                goto error;
 434                        }
 435                        break;
 436                case '?':
 437                        print_usage();
 438                        ret = -1;
 439                        goto error;
 440                }
 441        }
 442
 443        /* Find the device requested */
 444        if (dev_num < 0 && !device_name) {
 445                fprintf(stderr, "Device not set\n");
 446                print_usage();
 447                ret = -1;
 448                goto error;
 449        } else if (dev_num >= 0 && device_name) {
 450                fprintf(stderr, "Only one of --device-num or --device-name needs to be set\n");
 451                print_usage();
 452                ret = -1;
 453                goto error;
 454        } else if (dev_num < 0) {
 455                dev_num = find_type_by_name(device_name, "iio:device");
 456                if (dev_num < 0) {
 457                        fprintf(stderr, "Failed to find the %s\n", device_name);
 458                        ret = dev_num;
 459                        goto error;
 460                }
 461        }
 462        printf("iio device number being used is %d\n", dev_num);
 463
 464        ret = asprintf(&dev_dir_name, "%siio:device%d", iio_dir, dev_num);
 465        if (ret < 0)
 466                return -ENOMEM;
 467        /* Fetch device_name if specified by number */
 468        if (!device_name) {
 469                device_name = malloc(IIO_MAX_NAME_LENGTH);
 470                if (!device_name) {
 471                        ret = -ENOMEM;
 472                        goto error;
 473                }
 474                ret = read_sysfs_string("name", dev_dir_name, device_name);
 475                if (ret < 0) {
 476                        fprintf(stderr, "Failed to read name of device %d\n", dev_num);
 477                        goto error;
 478                }
 479        }
 480
 481        if (notrigger) {
 482                printf("trigger-less mode selected\n");
 483        } else if (trig_num >= 0) {
 484                char *trig_dev_name;
 485                ret = asprintf(&trig_dev_name, "%strigger%d", iio_dir, trig_num);
 486                if (ret < 0) {
 487                        return -ENOMEM;
 488                }
 489                trigger_name = malloc(IIO_MAX_NAME_LENGTH);
 490                ret = read_sysfs_string("name", trig_dev_name, trigger_name);
 491                free(trig_dev_name);
 492                if (ret < 0) {
 493                        fprintf(stderr, "Failed to read trigger%d name from\n", trig_num);
 494                        return ret;
 495                }
 496                printf("iio trigger number being used is %d\n", trig_num);
 497        } else {
 498                if (!trigger_name) {
 499                        /*
 500                         * Build the trigger name. If it is device associated
 501                         * its name is <device_name>_dev[n] where n matches
 502                         * the device number found above.
 503                         */
 504                        ret = asprintf(&trigger_name,
 505                                       "%s-dev%d", device_name, dev_num);
 506                        if (ret < 0) {
 507                                ret = -ENOMEM;
 508                                goto error;
 509                        }
 510                }
 511
 512                /* Look for this "-devN" trigger */
 513                trig_num = find_type_by_name(trigger_name, "trigger");
 514                if (trig_num < 0) {
 515                        /* OK try the simpler "-trigger" suffix instead */
 516                        free(trigger_name);
 517                        ret = asprintf(&trigger_name,
 518                                       "%s-trigger", device_name);
 519                        if (ret < 0) {
 520                                ret = -ENOMEM;
 521                                goto error;
 522                        }
 523                }
 524
 525                trig_num = find_type_by_name(trigger_name, "trigger");
 526                if (trig_num < 0) {
 527                        fprintf(stderr, "Failed to find the trigger %s\n",
 528                                trigger_name);
 529                        ret = trig_num;
 530                        goto error;
 531                }
 532
 533                printf("iio trigger number being used is %d\n", trig_num);
 534        }
 535
 536        /*
 537         * Parse the files in scan_elements to identify what channels are
 538         * present
 539         */
 540        ret = build_channel_array(dev_dir_name, buffer_idx, &channels, &num_channels);
 541        if (ret) {
 542                fprintf(stderr, "Problem reading scan element information\n"
 543                        "diag %s\n", dev_dir_name);
 544                goto error;
 545        }
 546        if (num_channels && autochannels == AUTOCHANNELS_ENABLED &&
 547            !force_autochannels) {
 548                fprintf(stderr, "Auto-channels selected but some channels "
 549                        "are already activated in sysfs\n");
 550                fprintf(stderr, "Proceeding without activating any channels\n");
 551        }
 552
 553        if ((!num_channels && autochannels == AUTOCHANNELS_ENABLED) ||
 554            (autochannels == AUTOCHANNELS_ENABLED && force_autochannels)) {
 555                fprintf(stderr, "Enabling all channels\n");
 556
 557                ret = enable_disable_all_channels(dev_dir_name, buffer_idx, 1);
 558                if (ret) {
 559                        fprintf(stderr, "Failed to enable all channels\n");
 560                        goto error;
 561                }
 562
 563                /* This flags that we need to disable the channels again */
 564                autochannels = AUTOCHANNELS_ACTIVE;
 565
 566                ret = build_channel_array(dev_dir_name, buffer_idx, &channels,
 567                                          &num_channels);
 568                if (ret) {
 569                        fprintf(stderr, "Problem reading scan element "
 570                                "information\n"
 571                                "diag %s\n", dev_dir_name);
 572                        goto error;
 573                }
 574                if (!num_channels) {
 575                        fprintf(stderr, "Still no channels after "
 576                                "auto-enabling, giving up\n");
 577                        goto error;
 578                }
 579        }
 580
 581        if (!num_channels && autochannels == AUTOCHANNELS_DISABLED) {
 582                fprintf(stderr,
 583                        "No channels are enabled, we have nothing to scan.\n");
 584                fprintf(stderr, "Enable channels manually in "
 585                        FORMAT_SCAN_ELEMENTS_DIR
 586                        "/*_en or pass -a to autoenable channels and "
 587                        "try again.\n", dev_dir_name, buffer_idx);
 588                ret = -ENOENT;
 589                goto error;
 590        }
 591
 592        /*
 593         * Construct the directory name for the associated buffer.
 594         * As we know that the lis3l02dq has only one buffer this may
 595         * be built rather than found.
 596         */
 597        ret = asprintf(&buf_dir_name,
 598                       "%siio:device%d/buffer%d", iio_dir, dev_num, buffer_idx);
 599        if (ret < 0) {
 600                ret = -ENOMEM;
 601                goto error;
 602        }
 603
 604        if (stat(buf_dir_name, &st)) {
 605                fprintf(stderr, "Could not stat() '%s', got error %d: %s\n",
 606                        buf_dir_name, errno, strerror(errno));
 607                ret = -errno;
 608                goto error;
 609        }
 610
 611        if (!S_ISDIR(st.st_mode)) {
 612                fprintf(stderr, "File '%s' is not a directory\n", buf_dir_name);
 613                ret = -EFAULT;
 614                goto error;
 615        }
 616
 617        if (!notrigger) {
 618                printf("%s %s\n", dev_dir_name, trigger_name);
 619                /*
 620                 * Set the device trigger to be the data ready trigger found
 621                 * above
 622                 */
 623                ret = write_sysfs_string_and_verify("trigger/current_trigger",
 624                                                    dev_dir_name,
 625                                                    trigger_name);
 626                if (ret < 0) {
 627                        fprintf(stderr,
 628                                "Failed to write current_trigger file\n");
 629                        goto error;
 630                }
 631        }
 632
 633        ret = asprintf(&buffer_access, "/dev/iio:device%d", dev_num);
 634        if (ret < 0) {
 635                ret = -ENOMEM;
 636                goto error;
 637        }
 638
 639        /* Attempt to open non blocking the access dev */
 640        fd = open(buffer_access, O_RDONLY | O_NONBLOCK);
 641        if (fd == -1) { /* TODO: If it isn't there make the node */
 642                ret = -errno;
 643                fprintf(stderr, "Failed to open %s\n", buffer_access);
 644                goto error;
 645        }
 646
 647        /* specify for which buffer index we want an FD */
 648        buf_fd = buffer_idx;
 649
 650        ret = ioctl(fd, IIO_BUFFER_GET_FD_IOCTL, &buf_fd);
 651        if (ret == -1 || buf_fd == -1) {
 652                ret = -errno;
 653                if (ret == -ENODEV || ret == -EINVAL)
 654                        fprintf(stderr,
 655                                "Device does not have this many buffers\n");
 656                else
 657                        fprintf(stderr, "Failed to retrieve buffer fd\n");
 658
 659                goto error;
 660        }
 661
 662        /* Setup ring buffer parameters */
 663        ret = write_sysfs_int("length", buf_dir_name, buf_len);
 664        if (ret < 0)
 665                goto error;
 666
 667        /* Enable the buffer */
 668        ret = write_sysfs_int("enable", buf_dir_name, 1);
 669        if (ret < 0) {
 670                fprintf(stderr,
 671                        "Failed to enable buffer '%s': %s\n",
 672                        buf_dir_name, strerror(-ret));
 673                goto error;
 674        }
 675
 676        scan_size = size_from_channelarray(channels, num_channels);
 677        data = malloc(scan_size * buf_len);
 678        if (!data) {
 679                ret = -ENOMEM;
 680                goto error;
 681        }
 682
 683        /**
 684         * This check is being done here for sanity reasons, however it
 685         * should be omitted under normal operation.
 686         * If this is buffer0, we check that we get EBUSY after this point.
 687         */
 688        if (buffer_idx == 0) {
 689                errno = 0;
 690                read_size = read(fd, data, 1);
 691                if (read_size > -1 || errno != EBUSY) {
 692                        ret = -EFAULT;
 693                        perror("Reading from '%s' should not be possible after ioctl()");
 694                        goto error;
 695                }
 696        }
 697
 698        /* close now the main chardev FD and let the buffer FD work */
 699        if (close(fd) == -1)
 700                perror("Failed to close character device file");
 701        fd = -1;
 702
 703        for (j = 0; j < num_loops || num_loops < 0; j++) {
 704                if (!noevents) {
 705                        struct pollfd pfd = {
 706                                .fd = buf_fd,
 707                                .events = POLLIN,
 708                        };
 709
 710                        ret = poll(&pfd, 1, -1);
 711                        if (ret < 0) {
 712                                ret = -errno;
 713                                goto error;
 714                        } else if (ret == 0) {
 715                                continue;
 716                        }
 717
 718                        toread = buf_len;
 719                } else {
 720                        usleep(timedelay);
 721                        toread = 64;
 722                }
 723
 724                read_size = read(buf_fd, data, toread * scan_size);
 725                if (read_size < 0) {
 726                        if (errno == EAGAIN) {
 727                                fprintf(stderr, "nothing available\n");
 728                                continue;
 729                        } else {
 730                                break;
 731                        }
 732                }
 733                for (i = 0; i < read_size / scan_size; i++)
 734                        process_scan(data + scan_size * i, channels,
 735                                     num_channels);
 736        }
 737
 738error:
 739        cleanup();
 740
 741        if (fd >= 0 && close(fd) == -1)
 742                perror("Failed to close character device");
 743        if (buf_fd >= 0 && close(buf_fd) == -1)
 744                perror("Failed to close buffer");
 745        free(buffer_access);
 746        free(data);
 747        free(buf_dir_name);
 748        for (i = num_channels - 1; i >= 0; i--) {
 749                free(channels[i].name);
 750                free(channels[i].generic_name);
 751        }
 752        free(channels);
 753        free(trigger_name);
 754        free(device_name);
 755        free(dev_dir_name);
 756
 757        return ret;
 758}
 759