mirror of
https://github.com/lm-sensors/lm-sensors.git
synced 2026-10-29 12:50:43 +00:00
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:
1 parent
a28dc58524
commit
2e4f147647
10 files changed
+225
-13
No files matched your search
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
Reference in new issue
Block a user