Browse Source

Split print_i2c_busses into a gathering part and a printing part.

git-svn-id: http://lm-sensors.org/svn/i2c-tools/trunk@5194 7894878c-1315-0410-8ee3-d5d059ff63e0
tags/v3.0.2
Jean Delvare 18 years ago
parent
commit
f7b64dce7e
  1. 172
      tools/i2cbusses.c

172
tools/i2cbusses.c

@ -4,6 +4,7 @@
devices.
Copyright (c) 1999-2003 Frodo Looijaard <frodol@dds.nl> and
Mark D. Studebaker <mdsxyz123@yahoo.com>
Copyright (C) 2008 Jean Delvare <khali@linux-fr.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -54,6 +55,13 @@ static struct adap_type adap_types[5] = {
.algo = "N/A", },
};
struct i2c_adap {
int nr;
char *name;
const char *funcs;
const char *algo;
};
static enum adt i2c_get_funcs(int i2cbus)
{
unsigned long funcs;
@ -80,14 +88,47 @@ static enum adt i2c_get_funcs(int i2cbus)
return ret;
}
/*
this just prints out the installed i2c busses in a consistent format, whether
on a 2.4 kernel using /proc or a 2.6 kernel using /sys.
If procfmt == 1, print out exactly /proc/bus/i2c format on stdout.
This allows this to be used in a program to emulate /proc/bus/i2c on a
sysfs system.
*/
void print_i2c_busses(int procfmt)
/* Remove trailing spaces from a string
Return the new string length including the trailing NUL */
static int rtrim(char *s)
{
int i;
for (i = strlen(s) - 1; i >= 0 && (s[i] == ' ' || s[i] == '\n'); i--)
s[i] = '\0';
return i + 2;
}
static void free_adapters(struct i2c_adap *adapters)
{
int i;
for (i = 0; adapters[i].name; i++)
free(adapters[i].name);
free(adapters);
}
/* We allocate space for the adapters in bunches. The last item is a
terminator, so here we start with room for 7 adapters, which should
be enough in most cases. If not, we allocate more later as needed. */
#define BUNCH 8
/* n must match the size of adapters at calling time */
static struct i2c_adap *more_adapters(struct i2c_adap *adapters, int n)
{
struct i2c_adap *new_adapters;
new_adapters = realloc(adapters, (n + BUNCH) * sizeof(struct i2c_adap));
if (!new_adapters) {
free_adapters(adapters);
return NULL;
}
memset(new_adapters + n, 0, BUNCH * sizeof(struct i2c_adap));
return new_adapters;
}
static struct i2c_adap *gather_i2c_busses(void)
{
FILE *fptr;
char s[100];
@ -98,17 +139,51 @@ void print_i2c_busses(int procfmt)
char dev[NAME_MAX], fstype[NAME_MAX], sysfs[NAME_MAX], n[NAME_MAX];
int foundsysfs = 0;
int count=0;
struct i2c_adap *adapters;
adapters = calloc(BUNCH, sizeof(struct i2c_adap));
if (!adapters)
return NULL;
/* look in /proc/bus/i2c */
if((fptr = fopen("/proc/bus/i2c", "r"))) {
while(fgets(s, 100, fptr)) {
if(count++ == 0 && !procfmt)
fprintf(stderr," Installed I2C busses:\n");
if(procfmt)
printf("%s", s);
else
fprintf(stderr, " %s", s);
char *algo, *name, *type, *all;
int len_algo, len_name, len_type;
int i2cbus;
algo = strrchr(s, '\t');
*(algo++) = '\0';
len_algo = rtrim(algo);
name = strrchr(s, '\t');
*(name++) = '\0';
len_name = rtrim(name);
type = strrchr(s, '\t');
*(type++) = '\0';
len_type = rtrim(type);
sscanf(s, "i2c-%d", &i2cbus);
if ((count + 1) % BUNCH == 0) {
/* We need more space */
adapters = more_adapters(adapters, count + 1);
if (!adapters)
return NULL;
}
all = malloc(len_name + len_type + len_algo);
if (all == NULL) {
free_adapters(adapters);
return NULL;
}
adapters[count].nr = i2cbus;
adapters[count].name = strcpy(all, name);
adapters[count].funcs = strcpy(all + len_name, type);
adapters[count].algo = strcpy(all + len_name + len_type,
algo);
count++;
}
fclose(fptr);
goto done;
@ -189,33 +264,80 @@ found:
}
if ((border = strchr(x, '\n')) != NULL)
*border = 0;
if(count++ == 0 && !procfmt)
fprintf(stderr," Installed I2C busses:\n");
/* match 2.4 /proc/bus/i2c format as closely as possible */
if (!sscanf(de->d_name, "i2c-%d", &i2cbus))
continue;
if(!strncmp(x, "ISA ", 4)) {
type = adt_isa;
} else if(!sscanf(de->d_name, "i2c-%d", &i2cbus)) {
type = adt_dummy;
} else {
/* Attempt to probe for adapter capabilities */
type = i2c_get_funcs(i2cbus);
}
if (procfmt)
printf("%s\t%-10s\t%-32s\t%s\n", de->d_name,
adap_types[type].funcs, x, adap_types[type].algo);
else
fprintf(stderr, " %s\t%-10s\t%s\n", de->d_name,
adap_types[type].funcs, x);
if ((count + 1) % BUNCH == 0) {
/* We need more space */
adapters = more_adapters(adapters, count + 1);
if (!adapters)
return NULL;
}
adapters[count].nr = i2cbus;
adapters[count].name = strdup(x);
if (adapters[count].name == NULL) {
free_adapters(adapters);
return NULL;
}
adapters[count].funcs = adap_types[type].funcs;
adapters[count].algo = adap_types[type].algo;
count++;
}
}
closedir(dir);
done:
return adapters;
}
/*
this just prints out the installed i2c busses in a consistent format, whether
on a 2.4 kernel using /proc or a 2.6 kernel using /sys.
If procfmt == 1, print out exactly /proc/bus/i2c format on stdout.
This allows this to be used in a program to emulate /proc/bus/i2c on a
sysfs system.
*/
void print_i2c_busses(int procfmt)
{
struct i2c_adap *adapters;
int count;
adapters = gather_i2c_busses();
if (adapters == NULL) {
fprintf(stderr, "Error: Out of memory!\n");
return;
}
for (count = 0; adapters[count].name; count++) {
if (count == 0 && !procfmt)
fprintf(stderr," Installed I2C busses:\n");
if (procfmt)
/* match 2.4 /proc/bus/i2c format as closely as possible */
printf("i2c-%d\t%-10s\t%-32s\t%s\n",
adapters[count].nr,
adapters[count].funcs,
adapters[count].name,
adapters[count].algo);
else
fprintf(stderr, " i2c-%d\t%-10s\t%s\n",
adapters[count].nr,
adapters[count].funcs,
adapters[count].name);
}
if(count == 0 && !procfmt)
fprintf(stderr,"Error: No I2C busses found!\n"
"Be sure you have done 'modprobe i2c-dev'\n"
"and also modprobed your i2c bus drivers\n");
free_adapters(adapters);
}
/*

Loading…
Cancel
Save