Introduced /proc/sys/dev/sensors/chips file

See doc/sysctl for an explanation why it is needed.

Also fixed two very small cleanup bugs in lm75/lm78, which would probably be
impossible to trigger anyway, but still.


git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@51 7894878c-1315-0410-8ee3-d5d059ff63e0
This commit is contained in:
Frodo Looijaard committed 1998-12-08 22:52:05 +00:00
1 parent a28dc58524
commit 2e4f147647
10 files changed
+225 -13

No files matched your search

-3
View File
@@ -10,9 +10,6 @@ Many, many things. Most notably:
* Make it SMP-safe: there are no spinlocks yet. They are needed at many
places, probably (everywhere where global vars are accessed). This must be
done for the i2c modules, too.
* Extend sensors.c with a file /proc/sys/dev/sensors/chips, which lists
all directories under /proc/sys/dev/sensors with their SYSCTL id
(needed for good sysctl access).
* Extend the mod_inc_use/mod_dec_use through the fill_inode trick, for all
new /proc files.
* Make lm78.c detect 'double hits', (same chip connected to both SMBus and
+11
View File
@@ -0,0 +1,11 @@
You can access everything under /proc/sys through the sysctl interface. This
is mostly useful for C programs, which can use the sysctl function. Try
'man 2 sysctl' for more information.
As each chip gets its own directory under /proc/sys/dev/sensors, you must
somehow know the sysctl id of these directories to access the sensor data.
This is done through the file /proc/sys/dev/sensors/chips (see sensors.h
for the corresponding SYSCTL ids). You can only read this file; it
returns an array of struct sensors_chips_data, as defined in sensors.h.
Each chip will have its own entry here, with both its sysctl id and
the corresponding /proc name.
+1 -1
View File
@@ -331,8 +331,8 @@ int lm75_cleanup(void)
printk("lm75.o: Driver deregistration failed, module not removed.\n");
return res;
}
} else
lm75_initialized --;
}
return 0;
}
+1 -2
View File
@@ -878,9 +878,8 @@ int lm78_cleanup(void)
printk("lm78.o: Driver deregistration failed, module not removed.\n");
return res;
}
} else
lm78_initialized --;
}
return 0;
}
+9 -1
View File
@@ -73,10 +73,12 @@ extern int sensors_register_entry(struct i2c_client *client,
const char *prefix, ctl_table *ctl_template);
extern void sensors_deregister_entry(int id);
#endif /* def __KERNEL__ */
/* The maximum length of the prefix */
#define SENSORS_PREFIX_MAX 20
/* Driver IDs */
#define I2C_DRIVERID_I2CPROC 1001
#define I2C_DRIVERID_LM78 1002
@@ -90,6 +92,12 @@ extern void sensors_deregister_entry(int id);
dev table */
#endif /* def DEV_HWMON */
#define SENSORS_CHIPS 1
struct sensors_chips_data {
int sysctl_id;
char name[SENSORS_PREFIX_MAX + 13];
};
#define LM78_SYSCTL_IN0 1000 /* Volts * 100 */
#define LM78_SYSCTL_IN1 1001
#define LM78_SYSCTL_IN2 1002
+96 -1
View File
@@ -41,6 +41,11 @@ static void sensors_parse_reals(int *nrels, void *buffer, int bufsize,
long *results, int magnitude);
static void sensors_write_reals(int nrels,void *buffer,int *bufsize,
long *results, int magnitude);
static int sensors_proc_chips(ctl_table *ctl, int write, struct file * filp,
void *buffer, size_t *lenp);
static int sensors_sysctl_chips (ctl_table *table, int *name, int nlen,
void *oldval, size_t *oldlenp, void *newval,
size_t newlen, void **context);
static int sensors_init(void);
static int sensors_cleanup(void);
@@ -63,6 +68,27 @@ static ctl_table sysctl_table[] = {
{ 0 }
};
static ctl_table sensors_proc_dev_sensors[] = {
{ SENSORS_CHIPS, "chips", NULL, 0, 0644, NULL, &sensors_proc_chips,
&sensors_sysctl_chips },
{ 0 }
};
static ctl_table sensors_proc_dev[] = {
{ DEV_SENSORS, "sensors", NULL, 0, 0555, sensors_proc_dev_sensors },
{ 0 },
};
static ctl_table sensors_proc[] = {
{ CTL_DEV, "dev", NULL, 0, 0555, sensors_proc_dev },
{ 0 }
};
static struct ctl_table_header *sensors_proc_header;
static int sensors_initialized;
/* This returns a nice name for a new directory; for example lm78-isa-0310
(for a LM78 chip on the ISA bus at port 0x310), or lm75-i2c-3-4e (for
a LM75 chip on the third i2c bus at address 0x4e).
@@ -207,6 +233,68 @@ void sensors_fill_inode(struct inode *inode, int fill)
}
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) */
int sensors_proc_chips(ctl_table *ctl, int write, struct file * filp,
void *buffer, size_t *lenp)
{
char BUF[SENSORS_PREFIX_MAX + 30];
int buflen,curbufsize,i;
struct ctl_table *client_tbl;
if (write)
return 0;
/* If buffer is size 0, or we try to read when not at the start, we
return nothing. Note that I think writing when not at the start
does not work either, but anyway, this is straight from the kernel
sources. */
if (!*lenp || (filp->f_pos && !write)) {
*lenp = 0;
return 0;
}
curbufsize = 0;
for (i = 0; i < SENSORS_ENTRY_MAX; i ++)
if (sensors_entries[i]) {
client_tbl = sensors_entries[i]->ctl_table->child->child;
buflen = sprintf(BUF,"%d\t%s\n",client_tbl->ctl_name,
client_tbl->procname);
if (buflen + curbufsize > *lenp)
buflen=*lenp-curbufsize;
copy_to_user(buffer,BUF,buflen);
curbufsize += buflen;
(char *) buffer += buflen;
}
*lenp = curbufsize;
filp->f_pos += curbufsize;
return 0;
}
int sensors_sysctl_chips (ctl_table *table, int *name, int nlen, void *oldval,
size_t *oldlenp, void *newval, size_t newlen,
void **context)
{
struct sensors_chips_data data;
int i,oldlen,nrels,maxels;
struct ctl_table *client_tbl;
if (oldval && oldlenp && ! get_user_data(oldlen,oldlenp) && oldlen) {
maxels = oldlen / sizeof(struct sensors_chips_data);
nrels = 0;
for (i = 0; (i < SENSORS_ENTRY_MAX) && (nrels < maxels); i++)
if (sensors_entries[i]) {
client_tbl = sensors_entries[i]->ctl_table->child->child;
data.sysctl_id = client_tbl->ctl_name;
strcpy(data.name,client_tbl->procname);
copy_to_user(oldval,&data,sizeof(struct sensors_chips_data));
(char *) oldval += sizeof(struct sensors_chips_data);
nrels++;
}
oldlen = nrels * sizeof(struct sensors_chips_data);
put_user(oldlen,oldlenp);
}
return 0;
}
/* This funcion reads or writes a 'real' value (encoded by the combination
of an integer and a magnitude, the last is the power of ten the value
should be divided with) to a /proc/sys directory. To use this function,
@@ -263,7 +351,6 @@ int sensors_proc_real(ctl_table *ctl, int write, struct file * filp,
/* And write them to buffer, converting to reals */
sensors_write_reals(nrels,buffer,lenp,results,mag);
sensors_write_reals(nrels,buffer,lenp,results,mag);
filp->f_pos += *lenp;
return 0;
}
@@ -477,11 +564,19 @@ void sensors_write_reals(int nrels,void *buffer,int *bufsize,long *results,
int sensors_init(void)
{
printk("sensors.o version %s (%s)\n",LM_VERSION,LM_DATE);
sensors_initialized = 0;
if (! (sensors_proc_header = register_sysctl_table(sensors_proc,0)))
return -ENOMEM;
sensors_initialized ++;
return 0;
}
int sensors_cleanup(void)
{
if (sensors_initialized >= 1) {
unregister_sysctl_table(sensors_proc_header);
sensors_initialized --;
}
return 0;
}
+1 -1
View File
@@ -331,8 +331,8 @@ int lm75_cleanup(void)
printk("lm75.o: Driver deregistration failed, module not removed.\n");
return res;
}
} else
lm75_initialized --;
}
return 0;
}
+1 -2
View File
@@ -878,9 +878,8 @@ int lm78_cleanup(void)
printk("lm78.o: Driver deregistration failed, module not removed.\n");
return res;
}
} else
lm78_initialized --;
}
return 0;
}
+96 -1
View File
@@ -41,6 +41,11 @@ static void sensors_parse_reals(int *nrels, void *buffer, int bufsize,
long *results, int magnitude);
static void sensors_write_reals(int nrels,void *buffer,int *bufsize,
long *results, int magnitude);
static int sensors_proc_chips(ctl_table *ctl, int write, struct file * filp,
void *buffer, size_t *lenp);
static int sensors_sysctl_chips (ctl_table *table, int *name, int nlen,
void *oldval, size_t *oldlenp, void *newval,
size_t newlen, void **context);
static int sensors_init(void);
static int sensors_cleanup(void);
@@ -63,6 +68,27 @@ static ctl_table sysctl_table[] = {
{ 0 }
};
static ctl_table sensors_proc_dev_sensors[] = {
{ SENSORS_CHIPS, "chips", NULL, 0, 0644, NULL, &sensors_proc_chips,
&sensors_sysctl_chips },
{ 0 }
};
static ctl_table sensors_proc_dev[] = {
{ DEV_SENSORS, "sensors", NULL, 0, 0555, sensors_proc_dev_sensors },
{ 0 },
};
static ctl_table sensors_proc[] = {
{ CTL_DEV, "dev", NULL, 0, 0555, sensors_proc_dev },
{ 0 }
};
static struct ctl_table_header *sensors_proc_header;
static int sensors_initialized;
/* This returns a nice name for a new directory; for example lm78-isa-0310
(for a LM78 chip on the ISA bus at port 0x310), or lm75-i2c-3-4e (for
a LM75 chip on the third i2c bus at address 0x4e).
@@ -207,6 +233,68 @@ void sensors_fill_inode(struct inode *inode, int fill)
}
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) */
int sensors_proc_chips(ctl_table *ctl, int write, struct file * filp,
void *buffer, size_t *lenp)
{
char BUF[SENSORS_PREFIX_MAX + 30];
int buflen,curbufsize,i;
struct ctl_table *client_tbl;
if (write)
return 0;
/* If buffer is size 0, or we try to read when not at the start, we
return nothing. Note that I think writing when not at the start
does not work either, but anyway, this is straight from the kernel
sources. */
if (!*lenp || (filp->f_pos && !write)) {
*lenp = 0;
return 0;
}
curbufsize = 0;
for (i = 0; i < SENSORS_ENTRY_MAX; i ++)
if (sensors_entries[i]) {
client_tbl = sensors_entries[i]->ctl_table->child->child;
buflen = sprintf(BUF,"%d\t%s\n",client_tbl->ctl_name,
client_tbl->procname);
if (buflen + curbufsize > *lenp)
buflen=*lenp-curbufsize;
copy_to_user(buffer,BUF,buflen);
curbufsize += buflen;
(char *) buffer += buflen;
}
*lenp = curbufsize;
filp->f_pos += curbufsize;
return 0;
}
int sensors_sysctl_chips (ctl_table *table, int *name, int nlen, void *oldval,
size_t *oldlenp, void *newval, size_t newlen,
void **context)
{
struct sensors_chips_data data;
int i,oldlen,nrels,maxels;
struct ctl_table *client_tbl;
if (oldval && oldlenp && ! get_user_data(oldlen,oldlenp) && oldlen) {
maxels = oldlen / sizeof(struct sensors_chips_data);
nrels = 0;
for (i = 0; (i < SENSORS_ENTRY_MAX) && (nrels < maxels); i++)
if (sensors_entries[i]) {
client_tbl = sensors_entries[i]->ctl_table->child->child;
data.sysctl_id = client_tbl->ctl_name;
strcpy(data.name,client_tbl->procname);
copy_to_user(oldval,&data,sizeof(struct sensors_chips_data));
(char *) oldval += sizeof(struct sensors_chips_data);
nrels++;
}
oldlen = nrels * sizeof(struct sensors_chips_data);
put_user(oldlen,oldlenp);
}
return 0;
}
/* This funcion reads or writes a 'real' value (encoded by the combination
of an integer and a magnitude, the last is the power of ten the value
should be divided with) to a /proc/sys directory. To use this function,
@@ -263,7 +351,6 @@ int sensors_proc_real(ctl_table *ctl, int write, struct file * filp,
/* And write them to buffer, converting to reals */
sensors_write_reals(nrels,buffer,lenp,results,mag);
sensors_write_reals(nrels,buffer,lenp,results,mag);
filp->f_pos += *lenp;
return 0;
}
@@ -477,11 +564,19 @@ void sensors_write_reals(int nrels,void *buffer,int *bufsize,long *results,
int sensors_init(void)
{
printk("sensors.o version %s (%s)\n",LM_VERSION,LM_DATE);
sensors_initialized = 0;
if (! (sensors_proc_header = register_sysctl_table(sensors_proc,0)))
return -ENOMEM;
sensors_initialized ++;
return 0;
}
int sensors_cleanup(void)
{
if (sensors_initialized >= 1) {
unregister_sysctl_table(sensors_proc_header);
sensors_initialized --;
}
return 0;
}
+9 -1
View File
@@ -73,10 +73,12 @@ extern int sensors_register_entry(struct i2c_client *client,
const char *prefix, ctl_table *ctl_template);
extern void sensors_deregister_entry(int id);
#endif /* def __KERNEL__ */
/* The maximum length of the prefix */
#define SENSORS_PREFIX_MAX 20
/* Driver IDs */
#define I2C_DRIVERID_I2CPROC 1001
#define I2C_DRIVERID_LM78 1002
@@ -90,6 +92,12 @@ extern void sensors_deregister_entry(int id);
dev table */
#endif /* def DEV_HWMON */
#define SENSORS_CHIPS 1
struct sensors_chips_data {
int sysctl_id;
char name[SENSORS_PREFIX_MAX + 13];
};
#define LM78_SYSCTL_IN0 1000 /* Volts * 100 */
#define LM78_SYSCTL_IN1 1001
#define LM78_SYSCTL_IN2 1002