Changeset 18

Show
Ignore:
Timestamp:
11/28/98 02:40:37 (14 years ago)
Author:
frodo
Message:

Finished i2c-proc.c

When you insert i2c-proc.o, you will find some files in /proc/bus (which
is first created for 2.0 kernels). Currently, the following files are
implemented:

  • /proc/bus/i2c A list of i2c/smbus adapters. If DEBUG was true when you compiled this module, you will also see the ISA pseudo-adapter (if isa.o is loaded).
  • /proc/bus/i2c-? For each adapter in /proc/bus/i2c, a list of registered clients. If DEBUG was true when you compiled this module, you will also see the i2c-proc pseudo client.

Of course, these entries are modified when adapters are added/removed.

Kernel 2.1.x users are encouraged to test this module, as /proc entries
are somewhat different beginning with kernel 2.1.29.

Location:
lm-sensors/trunk
Files:
4 modified

Legend:

Unmodified
Added
Removed
  • lm-sensors/trunk/kernel/i2c-proc.c

    r17 r18  
    4141static void i2cproc_inc_use(struct i2c_client *client); 
    4242static void i2cproc_dec_use(struct i2c_client *client); 
    43  
    44 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)) 
    45  
    46 static int read_bus_i2c(char *buf, char **start, off_t offset, int len, 
    47                         int *eof , void *private); 
    48  
    49 #else /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,29)) */ 
    50  
     43static int i2cproc_bus_read(struct inode * inode, struct file * file,char * buf, 
     44                            int count); 
     45 
     46/* To implement the dynamic /proc/bus/i2c-? files, we need our own  
     47   implementation of the read hook */ 
     48static struct file_operations i2cproc_operations = { 
     49        NULL, 
     50        i2cproc_bus_read, 
     51}; 
     52 
     53static struct inode_operations i2cproc_inode_operations = { 
     54        &i2cproc_operations 
     55}; 
     56 
     57 
     58#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)) 
     59 
     60static int i2proc_bus_read(char *buf, char **start, off_t offset, int len, 
     61                           int *eof , void *private); 
     62ssize_t array_read(struct file * file, char * buf,size_t count, loff_t *ppos); 
     63 
     64#else /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,29)) */ 
     65 
     66int i2cproc_bus_read(struct inode * inode, struct file * file,char * buf, 
     67                     int count); 
    5168static int read_bus_i2c(char *buf, char **start, off_t offset, int len, 
    5269                        int unused); 
     
    89106/* This is a sorted list of all adapters that will have entries in /proc/bus */ 
    90107static struct i2c_adapter *i2cproc_adapters[I2C_ADAP_MAX]; 
     108 
     109/* Inodes of /dev/bus/i2c-? files */ 
     110static int i2cproc_inodes[I2C_ADAP_MAX]; 
    91111 
    92112/* We will use a nasty trick: we register a driver, that will be notified 
     
    208228} 
    209229 
     230/* This function generates the output for /proc/bus/i2c */ 
    210231#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)) 
    211232int read_bus_i2c(char *buf, char **start, off_t offset, int len, int *eof,  
     
    219240  for (i = 0; i < I2C_ADAP_MAX; i++) 
    220241    if (i2cproc_adapters[i]) 
    221       len += sprintf(buf, "/dev/i2c-%d\t%s\t%-32s\t%-32s\n",i, 
     242      len += sprintf(buf, "i2c-%d\t%s\t%-32s\t%-32s\n",i, 
    222243                     i2c_is_smbus_adapter(i2cproc_adapters[i])?"smbus": 
    223244#ifdef DEBUG 
     
    230251} 
    231252 
    232 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)) 
    233 int read_bus_i2c_file(char *buf, char **start, off_t offset, int len,  
    234                       int *eof, void *private) 
    235 #else /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,29)) */ 
    236 int read_bus_i2c_file(char *buf, char **start, off_t offset, int len,  
    237                       int unused) 
    238 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)) */ 
    239 { 
    240   len = 0; 
    241   return len; 
     253/* This function generates the output for /proc/bus/i2c-? */ 
     254#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)) 
     255ssize_t i2cproc_read(struct file * file, char * buf,size_t count, loff_t *ppos) 
     256{ 
     257  struct inode * inode = file->f_dentry->d_inode; 
     258#else (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,29)) 
     259int i2cproc_bus_read(struct inode * inode, struct file * file,char * buf, 
     260                     int count) 
     261{ 
     262#endif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)) 
     263  char *kbuf; 
     264  struct i2c_client *client; 
     265  int i,j,len=0; 
     266 
     267  if (count < 0) 
     268    return -EINVAL; 
     269  if (count > 4000) 
     270    count = 4000; 
     271  for (i = 0; i < I2C_ADAP_MAX; i++) 
     272    if (i2cproc_inodes[i] == inode->i_ino) { 
     273      if (! (kbuf = kmalloc(count,GFP_KERNEL))) 
     274        return -ENOMEM; 
     275      for (j = 0; j < I2C_CLIENT_MAX; j++) 
     276        if ((client = i2cproc_adapters[i]->clients[j])) 
     277          /* Filter out dummy clients */ 
     278#ifndef DEBUG 
     279          if (client->driver->id != I2C_DRIVERID_I2CPROC) 
     280#endif /* ndef DEBUG */ 
     281            len += sprintf(kbuf+len,"%x\t%-32s\t%-32s\n", 
     282#ifdef DEBUG 
     283                           i2c_is_isa_client(client)? 
     284                             ((struct isa_client *) client)->isa_addr&0xffffff: 
     285#endif /* def DEBUG */ 
     286                             client->addr, 
     287                           client->name,client->driver->name); 
     288      if (file->f_pos+len > count) 
     289        len = count - file->f_pos; 
     290      len = len - file->f_pos; 
     291      if (len < 0)  
     292        len = 0; 
     293      memcpy_tofs(buf,kbuf+file->f_pos,len); 
     294      file->f_pos += len; 
     295      kfree(kbuf); 
     296      return len; 
     297    } 
     298  return -ENOENT; 
    242299} 
    243300 
     
    266323  } 
    267324 
     325#ifndef DEBUG 
    268326  if (! (client = kmalloc(sizeof(struct i2c_client),GFP_KERNEL))) { 
     327#else /* def DEBUG */ 
     328  if (! (client = kmalloc(sizeof(struct isa_client),GFP_KERNEL))) { 
     329#endif  
    269330    printk("i2c-proc.o: Out of memory!\n"); 
    270331    return -ENOMEM; 
    271332  } 
    272333  memcpy(client,&i2cproc_client_template,sizeof(struct i2c_client)); 
     334#ifdef DEBUG 
     335  ((struct isa_client *) client) -> isa_addr = -1; 
     336#endif /* def DEBUG */ 
    273337  client->adapter = adapter; 
    274338  if ((res = i2c_attach_client(client))) { 
     
    289353    return -ENOENT; 
    290354  } 
    291   proc_entry->read_proc = &read_bus_i2c_file; 
     355  proc_entry->ops = &i2cproc_inode_operations; 
    292356#else /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,29)) */ 
    293357  if (!(proc_entry = kmalloc(sizeof(struct proc_dir_entry)+strlen(name)+1, 
     
    302366  proc_entry->mode = S_IRUGO | S_IFREG; 
    303367  proc_entry->nlink = 1; 
    304   proc_entry->get_info = &read_bus_i2c_file; 
     368  proc_entry->ops = &i2cproc_inode_operations; 
    305369  strcpy((char *) proc_entry->name,name); 
    306370 
     
    313377   
    314378  i2cproc_proc_entries[i] = proc_entry; 
     379  i2cproc_inodes[i] = proc_entry->low_ino; 
    315380#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)) */ 
    316381  return 0; 
     
    355420      } 
    356421      i2cproc_adapters[i] = NULL; 
     422      i2cproc_inodes[i] = 0; 
    357423      kfree(client); 
    358424      return 0; 
  • lm-sensors/trunk/kernel/include/sensors.h

    r16 r18  
    2222 
    2323/* Driver IDs */ 
    24 #define I2C_DRIVERID_LM78 2 
    25 #define I2C_DRIVERID_I2CPROC 1 
     24#define I2C_DRIVERID_I2CPROC 1001 
     25#define I2C_DRIVERID_LM78 1002 
    2626 
    2727#endif /* def SENSORS_SENSORS_H */ 
  • lm-sensors/trunk/src/i2c-proc.c

    r17 r18  
    4141static void i2cproc_inc_use(struct i2c_client *client); 
    4242static void i2cproc_dec_use(struct i2c_client *client); 
    43  
    44 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)) 
    45  
    46 static int read_bus_i2c(char *buf, char **start, off_t offset, int len, 
    47                         int *eof , void *private); 
    48  
    49 #else /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,29)) */ 
    50  
     43static int i2cproc_bus_read(struct inode * inode, struct file * file,char * buf, 
     44                            int count); 
     45 
     46/* To implement the dynamic /proc/bus/i2c-? files, we need our own  
     47   implementation of the read hook */ 
     48static struct file_operations i2cproc_operations = { 
     49        NULL, 
     50        i2cproc_bus_read, 
     51}; 
     52 
     53static struct inode_operations i2cproc_inode_operations = { 
     54        &i2cproc_operations 
     55}; 
     56 
     57 
     58#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)) 
     59 
     60static int i2proc_bus_read(char *buf, char **start, off_t offset, int len, 
     61                           int *eof , void *private); 
     62ssize_t array_read(struct file * file, char * buf,size_t count, loff_t *ppos); 
     63 
     64#else /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,29)) */ 
     65 
     66int i2cproc_bus_read(struct inode * inode, struct file * file,char * buf, 
     67                     int count); 
    5168static int read_bus_i2c(char *buf, char **start, off_t offset, int len, 
    5269                        int unused); 
     
    89106/* This is a sorted list of all adapters that will have entries in /proc/bus */ 
    90107static struct i2c_adapter *i2cproc_adapters[I2C_ADAP_MAX]; 
     108 
     109/* Inodes of /dev/bus/i2c-? files */ 
     110static int i2cproc_inodes[I2C_ADAP_MAX]; 
    91111 
    92112/* We will use a nasty trick: we register a driver, that will be notified 
     
    208228} 
    209229 
     230/* This function generates the output for /proc/bus/i2c */ 
    210231#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)) 
    211232int read_bus_i2c(char *buf, char **start, off_t offset, int len, int *eof,  
     
    219240  for (i = 0; i < I2C_ADAP_MAX; i++) 
    220241    if (i2cproc_adapters[i]) 
    221       len += sprintf(buf, "/dev/i2c-%d\t%s\t%-32s\t%-32s\n",i, 
     242      len += sprintf(buf, "i2c-%d\t%s\t%-32s\t%-32s\n",i, 
    222243                     i2c_is_smbus_adapter(i2cproc_adapters[i])?"smbus": 
    223244#ifdef DEBUG 
     
    230251} 
    231252 
    232 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)) 
    233 int read_bus_i2c_file(char *buf, char **start, off_t offset, int len,  
    234                       int *eof, void *private) 
    235 #else /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,29)) */ 
    236 int read_bus_i2c_file(char *buf, char **start, off_t offset, int len,  
    237                       int unused) 
    238 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)) */ 
    239 { 
    240   len = 0; 
    241   return len; 
     253/* This function generates the output for /proc/bus/i2c-? */ 
     254#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)) 
     255ssize_t i2cproc_read(struct file * file, char * buf,size_t count, loff_t *ppos) 
     256{ 
     257  struct inode * inode = file->f_dentry->d_inode; 
     258#else (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,29)) 
     259int i2cproc_bus_read(struct inode * inode, struct file * file,char * buf, 
     260                     int count) 
     261{ 
     262#endif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)) 
     263  char *kbuf; 
     264  struct i2c_client *client; 
     265  int i,j,len=0; 
     266 
     267  if (count < 0) 
     268    return -EINVAL; 
     269  if (count > 4000) 
     270    count = 4000; 
     271  for (i = 0; i < I2C_ADAP_MAX; i++) 
     272    if (i2cproc_inodes[i] == inode->i_ino) { 
     273      if (! (kbuf = kmalloc(count,GFP_KERNEL))) 
     274        return -ENOMEM; 
     275      for (j = 0; j < I2C_CLIENT_MAX; j++) 
     276        if ((client = i2cproc_adapters[i]->clients[j])) 
     277          /* Filter out dummy clients */ 
     278#ifndef DEBUG 
     279          if (client->driver->id != I2C_DRIVERID_I2CPROC) 
     280#endif /* ndef DEBUG */ 
     281            len += sprintf(kbuf+len,"%x\t%-32s\t%-32s\n", 
     282#ifdef DEBUG 
     283                           i2c_is_isa_client(client)? 
     284                             ((struct isa_client *) client)->isa_addr&0xffffff: 
     285#endif /* def DEBUG */ 
     286                             client->addr, 
     287                           client->name,client->driver->name); 
     288      if (file->f_pos+len > count) 
     289        len = count - file->f_pos; 
     290      len = len - file->f_pos; 
     291      if (len < 0)  
     292        len = 0; 
     293      memcpy_tofs(buf,kbuf+file->f_pos,len); 
     294      file->f_pos += len; 
     295      kfree(kbuf); 
     296      return len; 
     297    } 
     298  return -ENOENT; 
    242299} 
    243300 
     
    266323  } 
    267324 
     325#ifndef DEBUG 
    268326  if (! (client = kmalloc(sizeof(struct i2c_client),GFP_KERNEL))) { 
     327#else /* def DEBUG */ 
     328  if (! (client = kmalloc(sizeof(struct isa_client),GFP_KERNEL))) { 
     329#endif  
    269330    printk("i2c-proc.o: Out of memory!\n"); 
    270331    return -ENOMEM; 
    271332  } 
    272333  memcpy(client,&i2cproc_client_template,sizeof(struct i2c_client)); 
     334#ifdef DEBUG 
     335  ((struct isa_client *) client) -> isa_addr = -1; 
     336#endif /* def DEBUG */ 
    273337  client->adapter = adapter; 
    274338  if ((res = i2c_attach_client(client))) { 
     
    289353    return -ENOENT; 
    290354  } 
    291   proc_entry->read_proc = &read_bus_i2c_file; 
     355  proc_entry->ops = &i2cproc_inode_operations; 
    292356#else /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,29)) */ 
    293357  if (!(proc_entry = kmalloc(sizeof(struct proc_dir_entry)+strlen(name)+1, 
     
    302366  proc_entry->mode = S_IRUGO | S_IFREG; 
    303367  proc_entry->nlink = 1; 
    304   proc_entry->get_info = &read_bus_i2c_file; 
     368  proc_entry->ops = &i2cproc_inode_operations; 
    305369  strcpy((char *) proc_entry->name,name); 
    306370 
     
    313377   
    314378  i2cproc_proc_entries[i] = proc_entry; 
     379  i2cproc_inodes[i] = proc_entry->low_ino; 
    315380#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)) */ 
    316381  return 0; 
     
    355420      } 
    356421      i2cproc_adapters[i] = NULL; 
     422      i2cproc_inodes[i] = 0; 
    357423      kfree(client); 
    358424      return 0; 
  • lm-sensors/trunk/src/sensors.h

    r16 r18  
    2222 
    2323/* Driver IDs */ 
    24 #define I2C_DRIVERID_LM78 2 
    25 #define I2C_DRIVERID_I2CPROC 1 
     24#define I2C_DRIVERID_I2CPROC 1001 
     25#define I2C_DRIVERID_LM78 1002 
    2626 
    2727#endif /* def SENSORS_SENSORS_H */