From 7937738275f65d4d98959da820b2230c2fb9d479 Mon Sep 17 00:00:00 2001 From: Frodo Looijaard Date: Mon, 7 Dec 1998 22:15:49 +0000 Subject: [PATCH] Module use count fix This fix will only work for kernels >= 2.1.58. * lm75, lm78: {INC,DEC}_MOD_USE_COUNT called for {inc,dec}_mod_use hooks * sensors: For new kernels, fill_inode is called, which in turn calls {inc,dec}_mod_use for a certain client git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@46 7894878c-1315-0410-8ee3-d5d059ff63e0 --- kernel/chips/lm75.c | 6 +++++ kernel/chips/lm78.c | 6 +++++ kernel/i2c-proc.c | 1 - kernel/sensors.c | 58 ++++++++++++++++++++++++++++++++++++++++++++- src/i2c-proc.c | 1 - src/lm75.c | 6 +++++ src/lm78.c | 6 +++++ src/sensors.c | 58 ++++++++++++++++++++++++++++++++++++++++++++- 8 files changed, 138 insertions(+), 4 deletions(-) diff --git a/kernel/chips/lm75.c b/kernel/chips/lm75.c index d2aab5ec..270b552d 100644 --- a/kernel/chips/lm75.c +++ b/kernel/chips/lm75.c @@ -221,11 +221,17 @@ int lm75_command(struct i2c_client *client, unsigned int cmd, void *arg) /* Nothing here yet */ void lm75_inc_use (struct i2c_client *client) { +#ifdef MODULE + MOD_INC_USE_COUNT; +#endif } /* Nothing here yet */ void lm75_dec_use (struct i2c_client *client) { +#ifdef MODULE + MOD_DEC_USE_COUNT; +#endif } u16 swap_bytes(u16 val) diff --git a/kernel/chips/lm78.c b/kernel/chips/lm78.c index 95b34324..57d34db6 100644 --- a/kernel/chips/lm78.c +++ b/kernel/chips/lm78.c @@ -583,11 +583,17 @@ int lm78_command(struct i2c_client *client, unsigned int cmd, void *arg) /* Nothing here yet */ void lm78_inc_use (struct i2c_client *client) { +#ifdef MODULE + MOD_INC_USE_COUNT; +#endif } /* Nothing here yet */ void lm78_dec_use (struct i2c_client *client) { +#ifdef MODULE + MOD_DEC_USE_COUNT; +#endif } diff --git a/kernel/i2c-proc.c b/kernel/i2c-proc.c index 1cd92947..64ea3103 100644 --- a/kernel/i2c-proc.c +++ b/kernel/i2c-proc.c @@ -435,7 +435,6 @@ void i2cproc_dec_use(struct i2c_client *client) { } - #ifdef MODULE MODULE_AUTHOR("Frodo Looijaard "); diff --git a/kernel/sensors.c b/kernel/sensors.c index a14972db..90845f9d 100644 --- a/kernel/sensors.c +++ b/kernel/sensors.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "version.h" #include "compat.h" @@ -47,6 +48,12 @@ static int sensors_cleanup(void); #define SENSORS_ENTRY_MAX 20 static struct ctl_table_header *sensors_entries[SENSORS_ENTRY_MAX]; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) +static struct i2c_client *sensors_clients[SENSORS_ENTRY_MAX]; +static unsigned short sensors_inodes[SENSORS_ENTRY_MAX]; +void sensors_fill_inode(struct inode *inode, int fill); +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) */ + static ctl_table sysctl_table[] = { { CTL_DEV, "dev", NULL, 0, 0555 }, { 0 }, @@ -135,6 +142,21 @@ int sensors_register_entry(struct i2c_client *client ,const char *prefix, sensors_entries[id-256] = new_header; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) + sensors_clients[id-256] = client; +#ifdef DEBUG + if (!new_header || !new_header->ctl_table || + !new_header->ctl_table->child || + !new_header->ctl_table->child->child || + !new_header->ctl_table->child->child->de) { + printk("sensors.o: NULL pointer when trying to install fill_inode fix!\n"); + return id; + } +#endif /* DEBUG */ + sensors_inodes[id-256] = new_header->ctl_table->child->child->de->low_ino; + new_header->ctl_table->child->child->de->fill_inode = &sensors_fill_inode; +#endif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) + return id; } @@ -147,10 +169,44 @@ void sensors_deregister_entry(int id) unregister_sysctl_table(sensors_entries[id]); kfree((void *) (table[4].procname)); kfree(table); - sensors_entries[id] = 0; + sensors_entries[id] = NULL; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) + sensors_clients[id-256] = NULL; +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) */ } } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) +void sensors_fill_inode(struct inode *inode, int fill) +{ + int i; + struct i2c_client *client; + +#ifdef DEBUG + if (! inode) { + printk("sensors.o: Warning: inode NULL in fill_inode()\n"); + return; + } +#endif /* def DEBUG */ + + for (i = 0; i < SENSORS_ENTRY_MAX; i++) + if (sensors_clients[i] && (sensors_inodes[i] == inode->i_ino)) + break; +#ifdef DEBUG + if (i == SENSORS_ENTRY_MAX) { + printk("sensors.o: Warning: inode (%ld) not found in fill_inode()\n", + inode->i_ino); + return; + } +#endif /* def DEBUG */ + client = sensors_clients[i]; + if (fill) + client->driver->inc_use(client); + else + client->driver->dec_use(client); +} +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) */ + /* 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, diff --git a/src/i2c-proc.c b/src/i2c-proc.c index 1cd92947..64ea3103 100644 --- a/src/i2c-proc.c +++ b/src/i2c-proc.c @@ -435,7 +435,6 @@ void i2cproc_dec_use(struct i2c_client *client) { } - #ifdef MODULE MODULE_AUTHOR("Frodo Looijaard "); diff --git a/src/lm75.c b/src/lm75.c index d2aab5ec..270b552d 100644 --- a/src/lm75.c +++ b/src/lm75.c @@ -221,11 +221,17 @@ int lm75_command(struct i2c_client *client, unsigned int cmd, void *arg) /* Nothing here yet */ void lm75_inc_use (struct i2c_client *client) { +#ifdef MODULE + MOD_INC_USE_COUNT; +#endif } /* Nothing here yet */ void lm75_dec_use (struct i2c_client *client) { +#ifdef MODULE + MOD_DEC_USE_COUNT; +#endif } u16 swap_bytes(u16 val) diff --git a/src/lm78.c b/src/lm78.c index 95b34324..57d34db6 100644 --- a/src/lm78.c +++ b/src/lm78.c @@ -583,11 +583,17 @@ int lm78_command(struct i2c_client *client, unsigned int cmd, void *arg) /* Nothing here yet */ void lm78_inc_use (struct i2c_client *client) { +#ifdef MODULE + MOD_INC_USE_COUNT; +#endif } /* Nothing here yet */ void lm78_dec_use (struct i2c_client *client) { +#ifdef MODULE + MOD_DEC_USE_COUNT; +#endif } diff --git a/src/sensors.c b/src/sensors.c index a14972db..90845f9d 100644 --- a/src/sensors.c +++ b/src/sensors.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "version.h" #include "compat.h" @@ -47,6 +48,12 @@ static int sensors_cleanup(void); #define SENSORS_ENTRY_MAX 20 static struct ctl_table_header *sensors_entries[SENSORS_ENTRY_MAX]; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) +static struct i2c_client *sensors_clients[SENSORS_ENTRY_MAX]; +static unsigned short sensors_inodes[SENSORS_ENTRY_MAX]; +void sensors_fill_inode(struct inode *inode, int fill); +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) */ + static ctl_table sysctl_table[] = { { CTL_DEV, "dev", NULL, 0, 0555 }, { 0 }, @@ -135,6 +142,21 @@ int sensors_register_entry(struct i2c_client *client ,const char *prefix, sensors_entries[id-256] = new_header; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) + sensors_clients[id-256] = client; +#ifdef DEBUG + if (!new_header || !new_header->ctl_table || + !new_header->ctl_table->child || + !new_header->ctl_table->child->child || + !new_header->ctl_table->child->child->de) { + printk("sensors.o: NULL pointer when trying to install fill_inode fix!\n"); + return id; + } +#endif /* DEBUG */ + sensors_inodes[id-256] = new_header->ctl_table->child->child->de->low_ino; + new_header->ctl_table->child->child->de->fill_inode = &sensors_fill_inode; +#endif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) + return id; } @@ -147,10 +169,44 @@ void sensors_deregister_entry(int id) unregister_sysctl_table(sensors_entries[id]); kfree((void *) (table[4].procname)); kfree(table); - sensors_entries[id] = 0; + sensors_entries[id] = NULL; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) + sensors_clients[id-256] = NULL; +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) */ } } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) +void sensors_fill_inode(struct inode *inode, int fill) +{ + int i; + struct i2c_client *client; + +#ifdef DEBUG + if (! inode) { + printk("sensors.o: Warning: inode NULL in fill_inode()\n"); + return; + } +#endif /* def DEBUG */ + + for (i = 0; i < SENSORS_ENTRY_MAX; i++) + if (sensors_clients[i] && (sensors_inodes[i] == inode->i_ino)) + break; +#ifdef DEBUG + if (i == SENSORS_ENTRY_MAX) { + printk("sensors.o: Warning: inode (%ld) not found in fill_inode()\n", + inode->i_ino); + return; + } +#endif /* def DEBUG */ + client = sensors_clients[i]; + if (fill) + client->driver->inc_use(client); + else + client->driver->dec_use(client); +} +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) */ + /* 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,