Skip to content

Commit

Permalink
Staging: IIO: Documentation: iio_utils: fix channel array generation.
Browse files Browse the repository at this point in the history
The previous implementation flawed, in case some channels are not enabled.
The sorted array would then include channel information of disabled channels,
And misses the enabled ones, when the count is reached.
More troublesome, the loop would not even terminate.

The fix is twofold:

First we skip channels that are not enabled.
Then we use a tested bubble sort algorithm to sort the array.
Since we already allocated exactly the number of bytes we need.
We can exercise bubble sort on the original memory.
In all cases I've seen, the array is already sorted, so this sort
terminates immediately.

Changes since V1:
Fix coding style issues.

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Michael Hennerich authored and Greg Kroah-Hartman committed Mar 9, 2011
1 parent 14f88f1 commit 8b68bb2
Showing 1 changed file with 33 additions and 23 deletions.
56 changes: 33 additions & 23 deletions drivers/staging/iio/Documentation/iio_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ static int iioutils_break_up_name(const char *full_name,
w = working;
r = working;

while(*r != '\0') {
while (*r != '\0') {
if (!isdigit(*r)) {
*w = *r;
w++;
Expand Down Expand Up @@ -242,6 +242,26 @@ inline int iioutils_get_param_float(float *output,
return ret;
}

/**
* bsort_channel_array_by_index() - reorder so that the array is in index order
*
**/

inline void bsort_channel_array_by_index(struct iio_channel_info **ci_array,
int cnt)
{

struct iio_channel_info temp;
int x, y;

for (x = 0; x < cnt; x++)
for (y = 0; y < (cnt - 1); y++)
if ((*ci_array)[y].index > (*ci_array)[y+1].index) {
temp = (*ci_array)[y + 1];
(*ci_array)[y + 1] = (*ci_array)[y];
(*ci_array)[y] = temp;
}
}

/**
* build_channel_array() - function to figure out what channels are present
Expand All @@ -254,7 +274,7 @@ inline int build_channel_array(const char *device_dir,
{
DIR *dp;
FILE *sysfsfp;
int count = 0, temp, i;
int count, temp, i;
struct iio_channel_info *current;
int ret;
const struct dirent *ent;
Expand Down Expand Up @@ -290,11 +310,10 @@ inline int build_channel_array(const char *device_dir,
fscanf(sysfsfp, "%u", &ret);
if (ret == 1)
(*counter)++;
count++;
fclose(sysfsfp);
free(filename);
}
*ci_array = malloc(sizeof(**ci_array)*count);
*ci_array = malloc(sizeof(**ci_array) * (*counter));
if (*ci_array == NULL) {
ret = -ENOMEM;
goto error_close_dir;
Expand All @@ -321,6 +340,13 @@ inline int build_channel_array(const char *device_dir,
}
fscanf(sysfsfp, "%u", &current->enabled);
fclose(sysfsfp);

if (!current->enabled) {
free(filename);
count--;
continue;
}

current->scale = 1.0;
current->offset = 0;
current->name = strndup(ent->d_name,
Expand Down Expand Up @@ -375,26 +401,10 @@ inline int build_channel_array(const char *device_dir,
current->generic_name);
}
}
/* reorder so that the array is in index order*/
current = malloc(sizeof(**ci_array)*(*counter));
if (current == NULL) {
ret = -ENOMEM;
goto error_cleanup_array;
}

closedir(dp);
count = 0;
temp = 0;
while (count < *counter)
for (i = 0; i < *counter; i++)
if ((*ci_array)[i].index == temp) {
memcpy(&current[count++],
&(*ci_array)[i],
sizeof(*current));
temp++;
break;
}
free(*ci_array);
*ci_array = current;
/* reorder so that the array is in index order */
bsort_channel_array_by_index(ci_array, *counter);

return 0;

Expand Down

0 comments on commit 8b68bb2

Please sign in to comment.