root/lm-sensors/trunk/kernel/sensors.c @ 324

Revision 324, 22.8 KB (checked in by frodo, 14 years ago)

Introducing module parameter scanning in sensors.c

It is untested as of yet; but it compiled without problem. Next step: add
support to the chip modules.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2    sensors.c - Part of lm_sensors, Linux kernel modules for hardware
3                monitoring
4    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#include <linux/module.h>
22#include <linux/malloc.h>
23#include <linux/ctype.h>
24#include <linux/sysctl.h>
25#include <linux/proc_fs.h>
26
27#include "version.h"
28#include "i2c.h"
29#include "i2c-isa.h"
30#include "sensors.h"
31#include "compat.h"
32#include "smbus.h"
33
34
35#ifdef MODULE
36extern int init_module(void);
37extern int cleanup_module(void);
38#endif /* MODULE */
39
40static int sensors_create_name(char **name, const char *prefix,
41                               struct i2c_adapter * adapter, int addr);
42static void sensors_parse_reals(int *nrels, void *buffer, int bufsize,
43                                long *results, int magnitude);
44static void sensors_write_reals(int nrels,void *buffer,int *bufsize,
45                                long *results, int magnitude);
46static int sensors_proc_chips(ctl_table *ctl, int write, struct file * filp,
47                              void *buffer, size_t *lenp);
48static int sensors_sysctl_chips (ctl_table *table, int *name, int nlen, 
49                                 void *oldval, size_t *oldlenp, void *newval,
50                                 size_t newlen, void **context);
51
52static int sensors_init(void);
53static int sensors_cleanup(void);
54
55#define SENSORS_ENTRY_MAX 20
56static struct ctl_table_header *sensors_entries[SENSORS_ENTRY_MAX];
57
58#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58))
59static struct i2c_client *sensors_clients[SENSORS_ENTRY_MAX];
60static unsigned short sensors_inodes[SENSORS_ENTRY_MAX];
61static void sensors_fill_inode(struct inode *inode, int fill);
62static void sensors_dir_fill_inode(struct inode *inode, int fill);
63#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) */
64
65static ctl_table sysctl_table[] = {
66  { CTL_DEV, "dev", NULL, 0, 0555 },
67  { 0 },
68  { DEV_SENSORS, "sensors", NULL, 0, 0555 },
69  { 0 },
70  { 0, NULL, NULL, 0, 0555 },
71  { 0 }
72};
73
74static ctl_table sensors_proc_dev_sensors[] = {
75  { SENSORS_CHIPS, "chips", NULL, 0, 0644, NULL, &sensors_proc_chips, 
76    &sensors_sysctl_chips },
77  { 0 }
78};
79
80static ctl_table sensors_proc_dev[] = {
81  { DEV_SENSORS, "sensors", NULL, 0, 0555, sensors_proc_dev_sensors },
82  { 0 },
83};
84
85
86static ctl_table sensors_proc[] = {
87  { CTL_DEV, "dev", NULL, 0, 0555, sensors_proc_dev },
88  { 0 }
89};
90
91
92static struct ctl_table_header *sensors_proc_header;
93static int sensors_initialized;
94
95/* This returns a nice name for a new directory; for example lm78-isa-0310
96   (for a LM78 chip on the ISA bus at port 0x310), or lm75-i2c-3-4e (for
97   a LM75 chip on the third i2c bus at address 0x4e). 
98   name is allocated first. */
99int sensors_create_name(char **name, const char *prefix, 
100                        struct i2c_adapter * adapter, int addr)
101{
102  char name_buffer[50]; 
103  int id;
104  if (i2c_is_isa_adapter(adapter)) 
105    sprintf(name_buffer,"%s-isa-%04x",prefix,addr);
106  else {
107    if ((id = i2c_adapter_id(adapter)) < 0)
108      return -ENOENT;
109    sprintf(name_buffer,"%s-i2c-%d-%02x",prefix,id,addr);
110  }
111  *name = kmalloc(strlen(name_buffer)+1,GFP_KERNEL);
112  strcpy(*name,name_buffer);
113  return 0;
114}
115
116/* This rather complex function must be called when you want to add an entry
117   to /proc/sys/dev/sensors/chips. It also creates a new directory within
118   /proc/sys/dev/sensors/.
119   ctl_template should be a template of the newly created directory. It is
120   copied in memory. The extra2 field of each file is set to point to client.
121   If any driver wants subdirectories within the newly created directory,
122   this function must be updated! */
123int sensors_register_entry(struct i2c_client *client ,const char *prefix, 
124                           ctl_table *ctl_template)
125{
126  int i,res,len,id;
127  ctl_table *new_table;
128  char *name;
129  struct ctl_table_header *new_header;
130
131  if ((res = sensors_create_name(&name,prefix,client->adapter,
132                                 i2c_is_isa_client(client)?
133                                 ((struct isa_client *) client)->isa_addr:
134                                 client->addr)))
135    return res;
136
137  for (id = 0; id < SENSORS_ENTRY_MAX; id++)
138    if (! sensors_entries[id]) {
139      break;
140    }
141  if (id == SENSORS_ENTRY_MAX) {
142    kfree(name);
143    return -ENOMEM;
144  }
145  id += 256;
146
147  len = 0;
148  while (ctl_template[len].procname)
149    len++;
150  len += 7;
151  if (! (new_table = kmalloc(sizeof(ctl_table) * len,GFP_KERNEL))) {
152    kfree(name);
153    return -ENOMEM;
154  }
155   
156  memcpy(new_table,sysctl_table,6 * sizeof(ctl_table));
157  new_table[0].child = &new_table[2];
158  new_table[2].child = &new_table[4];
159  new_table[4].child = &new_table[6];
160  new_table[4].procname = name;
161  new_table[4].ctl_name = id;
162  memcpy(new_table+6,ctl_template,(len-6) * sizeof(ctl_table));
163  for (i = 6; i < len; i++)
164    new_table[i].extra2 = client;
165
166  if (! (new_header = register_sysctl_table(new_table,0))) {
167    kfree(new_table);
168    kfree(name);
169    return -ENOMEM;
170  }
171
172  sensors_entries[id-256] = new_header;
173
174#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58))
175  sensors_clients[id-256] = client;
176#ifdef DEBUG
177  if (!new_header || !new_header->ctl_table || 
178      !new_header->ctl_table->child || 
179      !new_header->ctl_table->child->child ||
180      !new_header->ctl_table->child->child->de) {
181    printk("sensors.o: NULL pointer when trying to install fill_inode fix!\n");
182    return id; 
183  }
184#endif /* DEBUG */
185  sensors_inodes[id-256] = new_header->ctl_table->child->child->de->low_ino;
186  new_header->ctl_table->child->child->de->fill_inode = &sensors_dir_fill_inode;
187#endif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58))
188
189  return id;
190}
191
192void sensors_deregister_entry(int id)
193{
194  ctl_table *table;
195  char *temp;
196  id -= 256;
197  if (sensors_entries[id]) {
198    table = sensors_entries[id]->ctl_table;
199    unregister_sysctl_table(sensors_entries[id]);
200    /* Below two-step kfree is needed to keep gcc happy about const points */
201    (const char *) temp = table[4].procname;
202    kfree(temp);
203    kfree(table);
204    sensors_entries[id] = NULL;
205#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58))
206    sensors_clients[id] = NULL;
207#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) */
208  }
209}
210
211#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58))
212/* Monitor access for /proc/sys/dev/sensors; make unloading sensors.o
213   impossible if some process still uses it or some file in it */
214void sensors_fill_inode(struct inode *inode, int fill)
215{
216  if (fill)
217    MOD_INC_USE_COUNT;
218  else
219    MOD_DEC_USE_COUNT;
220}
221
222/* Monitor access for /proc/sys/dev/sensors/ directories; make unloading
223   the corresponding module impossible if some process still uses it or
224   some file in it */
225void sensors_dir_fill_inode(struct inode *inode, int fill)
226{
227  int i;
228  struct i2c_client *client;
229
230#ifdef DEBUG
231  if (! inode) {
232    printk("sensors.o: Warning: inode NULL in fill_inode()\n");
233    return;
234  }
235#endif /* def DEBUG */
236 
237  for (i = 0; i < SENSORS_ENTRY_MAX; i++) 
238    if (sensors_clients[i] && (sensors_inodes[i] == inode->i_ino))
239      break;
240#ifdef DEBUG
241  if (i == SENSORS_ENTRY_MAX) {
242    printk("sensors.o: Warning: inode (%ld) not found in fill_inode()\n",
243           inode->i_ino);
244    return;
245  }
246#endif /* def DEBUG */
247  client = sensors_clients[i];
248  if (fill)
249    client->driver->inc_use(client);
250  else
251    client->driver->dec_use(client);
252}
253#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) */
254
255int sensors_proc_chips(ctl_table *ctl, int write, struct file * filp,
256                       void *buffer, size_t *lenp)
257{
258  char BUF[SENSORS_PREFIX_MAX + 30];
259  int buflen,curbufsize,i;
260  struct ctl_table *client_tbl;
261
262  if (write)
263    return 0;
264
265  /* If buffer is size 0, or we try to read when not at the start, we
266     return nothing. Note that I think writing when not at the start
267     does not work either, but anyway, this is straight from the kernel
268     sources. */
269  if (!*lenp || (filp->f_pos && !write)) {
270    *lenp = 0;
271    return 0;
272  }
273  curbufsize = 0;
274  for (i = 0; i < SENSORS_ENTRY_MAX; i ++)
275    if (sensors_entries[i]) {
276      client_tbl = sensors_entries[i]->ctl_table->child->child;
277      buflen = sprintf(BUF,"%d\t%s\n",client_tbl->ctl_name,
278                       client_tbl->procname);
279      if (buflen + curbufsize > *lenp)
280        buflen=*lenp-curbufsize;
281      copy_to_user(buffer,BUF,buflen);
282      curbufsize += buflen;
283      (char *) buffer += buflen;
284    }
285  *lenp = curbufsize;
286  filp->f_pos += curbufsize;
287  return 0;
288}
289
290int sensors_sysctl_chips (ctl_table *table, int *name, int nlen, void *oldval,
291                          size_t *oldlenp, void *newval, size_t newlen,
292                          void **context)
293{
294  struct sensors_chips_data data;
295  int i,oldlen,nrels,maxels;
296  struct ctl_table *client_tbl;
297
298  if (oldval && oldlenp && ! get_user_data(oldlen,oldlenp) && oldlen) {
299    maxels = oldlen / sizeof(struct sensors_chips_data);
300    nrels = 0;
301    for (i = 0; (i < SENSORS_ENTRY_MAX) && (nrels < maxels); i++)
302      if (sensors_entries[i]) {
303        client_tbl = sensors_entries[i]->ctl_table->child->child;
304        data.sysctl_id = client_tbl->ctl_name;
305        strcpy(data.name,client_tbl->procname);
306        copy_to_user(oldval,&data,sizeof(struct sensors_chips_data));
307        (char *) oldval += sizeof(struct sensors_chips_data);
308        nrels++;
309      }
310    oldlen = nrels * sizeof(struct sensors_chips_data);
311    put_user(oldlen,oldlenp);
312  }
313  return 0;
314}
315
316
317/* This funcion reads or writes a 'real' value (encoded by the combination
318   of an integer and a magnitude, the last is the power of ten the value
319   should be divided with) to a /proc/sys directory. To use this function,
320   you must (before registering the ctl_table) set the extra2 field to the
321   client, and the extra1 field to a function of the form:
322      void func(struct i2c_client *client, int operation, int ctl_name,
323                int *nrels_mag, long *results)
324   This function can be called for three values of operation. If operation
325   equals SENSORS_PROC_REAL_INFO, the magnitude should be returned in
326   nrels_mag. If operation equals SENSORS_PROC_REAL_READ, values should
327   be read into results. nrels_mag should return the number of elements
328   read; the maximum number is put in it on entry. Finally, if operation
329   equals SENSORS_PROC_REAL_WRITE, the values in results should be
330   written to the chip. nrels_mag contains on entry the number of elements
331   found.
332   In all cases, client points to the client we wish to interact with,
333   and ctl_name is the SYSCTL id of the file we are accessing. */
334int sensors_proc_real(ctl_table *ctl, int write, struct file * filp,
335                      void *buffer, size_t *lenp)
336{
337#define MAX_RESULTS 20
338  int mag,nrels=MAX_RESULTS;
339  long results[MAX_RESULTS];
340  sensors_real_callback callback = ctl -> extra1;
341  struct i2c_client *client = ctl -> extra2;
342
343  /* If buffer is size 0, or we try to read when not at the start, we
344     return nothing. Note that I think writing when not at the start
345     does not work either, but anyway, this is straight from the kernel
346     sources. */
347  if (!*lenp || (filp->f_pos && !write)) {
348    *lenp = 0;
349    return 0;
350  }
351
352  /* Get the magnitude */
353  callback(client,SENSORS_PROC_REAL_INFO,ctl->ctl_name,&mag,NULL);
354
355  if (write) {
356    /* Read the complete input into results, converting to longs */
357    sensors_parse_reals(&nrels,buffer,*lenp,results,mag);
358
359    if (! nrels)
360      return 0;
361
362    /* Now feed this information back to the client */
363    callback(client,SENSORS_PROC_REAL_WRITE,ctl->ctl_name,&nrels,results);
364   
365    filp->f_pos += *lenp;
366    return 0;
367  } else { /* read */
368    /* Get the information from the client into results */
369    callback(client,SENSORS_PROC_REAL_READ,ctl->ctl_name,&nrels,results);
370
371    /* And write them to buffer, converting to reals */
372    sensors_write_reals(nrels,buffer,lenp,results,mag);
373    filp->f_pos += *lenp;
374    return 0;
375  }
376}
377
378/* This function is equivalent to sensors_proc_real, only it interacts with
379   the sysctl(2) syscall, and returns no reals, but integers */
380int sensors_sysctl_real (ctl_table *table, int *name, int nlen, void *oldval,
381               size_t *oldlenp, void *newval, size_t newlen,
382               void **context)
383{
384  long results[MAX_RESULTS];
385  int oldlen,nrels=MAX_RESULTS;
386  sensors_real_callback callback = table -> extra1;
387  struct i2c_client *client = table -> extra2;
388
389  /* Check if we need to output the old values */
390  if (oldval && oldlenp && ! get_user_data(oldlen,oldlenp) && oldlen) {
391    callback(client,SENSORS_PROC_REAL_READ,table->ctl_name,&nrels,results);
392
393    /* Note the rounding factor! */
394    if (nrels * sizeof(long) < oldlen)
395      oldlen = nrels * sizeof(long);
396    oldlen = (oldlen / sizeof(long)) * sizeof(long);
397    copy_to_user(oldval,results,oldlen);
398    put_user(oldlen,oldlenp);
399  }
400
401  if (newval && newlen) {
402    /* Note the rounding factor! */
403    newlen -= newlen % sizeof(long);
404    nrels = newlen / sizeof(long);
405    copy_from_user(results,newval,newlen);
406   
407    /* Get the new values back to the client */
408    callback(client,SENSORS_PROC_REAL_WRITE,table->ctl_name,&nrels,results);
409  }
410  return 0;
411}
412   
413
414/* nrels contains initially the maximum number of elements which can be
415   put in results, and finally the number of elements actually put there.
416   A magnitude of 1 will multiply everything with 10; etc.
417   buffer, bufsize is the character buffer we read from and its length.
418   results will finally contain the parsed integers.
419
420   Buffer should contain several reals, separated by whitespace. A real
421   has the following syntax:
422     [ Minus ] Digit* [ Dot Digit* ]
423   (everything between [] is optional; * means zero or more).
424   When the next character is unparsable, everything is skipped until the
425   next whitespace.
426
427   WARNING! This is tricky code. I have tested it, but there may still be
428            hidden bugs in it, even leading to crashes and things!
429*/
430void sensors_parse_reals(int *nrels, void *buffer, int bufsize, 
431                         long *results, int magnitude)
432{
433  int maxels,min,mag;
434  long res;
435  char nextchar=0;
436
437  maxels = *nrels;
438  *nrels = 0;
439
440  while (bufsize && (*nrels < maxels)) {
441
442    /* Skip spaces at the start */
443    while (bufsize && ! get_user_data(nextchar,(char *) buffer) && 
444           isspace((int) nextchar)) {
445      bufsize --;
446      ((char *) buffer)++;
447    }
448
449    /* Well, we may be done now */
450    if (! bufsize)
451      return;
452
453    /* New defaults for our result */
454    min = 0;
455    res = 0;
456    mag = magnitude;
457
458    /* Check for a minus */
459    if (! get_user_data(nextchar,(char *) buffer) && (nextchar == '-')) {
460      min=1;
461      bufsize--;
462      ((char *) buffer)++;
463    }
464
465    /* Digits before a decimal dot */
466    while (bufsize && !get_user_data(nextchar,(char *) buffer) && 
467           isdigit((int) nextchar)) {
468      res = res * 10 + nextchar - '0';
469      bufsize--;
470      ((char *) buffer)++;
471    }
472
473    /* If mag < 0, we must actually divide here! */
474    while (mag < 0) {
475      res = res / 10;
476      mag++;
477    }
478
479    if (bufsize && (nextchar == '.')) {
480      /* Skip the dot */
481      bufsize--;
482      ((char *) buffer)++;
483 
484      /* Read digits while they are significant */
485      while(bufsize && (mag > 0) && 
486            !get_user_data(nextchar,(char *) buffer) &&
487            isdigit((int) nextchar)) {
488        res = res * 10 + nextchar - '0';
489        mag--;
490        bufsize--;
491        ((char *) buffer)++;
492      }
493    }
494    /* If we are out of data, but mag > 0, we need to scale here */
495    while (mag > 0) {
496      res = res * 10;
497      mag --;
498    }
499
500    /* Skip everything until we hit whitespace */
501    while(bufsize && !get_user_data(nextchar,(char *) buffer) &&
502          isspace ((int) nextchar)) {
503      bufsize --;
504      ((char *) buffer) ++;
505    }
506
507    /* Put res in results */
508    results[*nrels] = (min?-1:1)*res;
509    (*nrels)++;
510  }   
511 
512  /* Well, there may be more in the buffer, but we need no more data.
513     Ignore anything that is left. */
514  return;
515}
516   
517void sensors_write_reals(int nrels,void *buffer,int *bufsize,long *results,
518                         int magnitude)
519{
520  #define BUFLEN 20
521  char BUF[BUFLEN+1]; /* An individual representation should fit in here! */
522  char printfstr[10];
523  int nr=0;
524  int buflen,mag,times;
525  int curbufsize=0;
526
527  while ((nr < nrels) && (curbufsize < *bufsize)) {
528    mag=magnitude;
529
530    if (nr != 0) {
531      put_user(' ', (char *) buffer);
532      curbufsize ++;
533      ((char *) buffer) ++;
534    }
535
536    /* Fill BUF with the representation of the next string */
537    if (mag <= 0) {
538
539      buflen=sprintf(BUF,"%ld",results[nr]);
540      if (buflen < 0) { /* Oops, a sprintf error! */
541        *bufsize=0;
542        return;
543      }
544      while ((mag < 0) && (buflen < BUFLEN)) {
545        BUF[buflen++]='0';
546        mag++;
547      }
548      BUF[buflen]=0;
549    } else {
550      times=1;
551      for (times=1; mag-- > 0; times *= 10);
552      if (results[nr] < 0) {
553        BUF[0] = '-';
554        buflen = 1;
555      } else
556        buflen=0;
557      strcpy(printfstr,"%ld.%0Xld");
558      printfstr[6]=magnitude+'0';
559      buflen+=sprintf(BUF+buflen,printfstr,abs(results[nr])/times,
560                      abs(results[nr])%times);
561      if (buflen < 0) { /* Oops, a sprintf error! */
562        *bufsize=0;
563        return;
564      }
565    }
566
567    /* Now copy it to the user-space buffer */
568    if (buflen + curbufsize > *bufsize)
569      buflen=*bufsize-curbufsize;
570    copy_to_user(buffer,BUF,buflen);
571    curbufsize += buflen;
572    (char *) buffer += buflen;
573
574    nr ++;
575  }
576  if (curbufsize < *bufsize) {
577    put_user('\n', (char *) buffer);
578    curbufsize ++;
579  }
580  *bufsize=curbufsize;
581}
582
583
584/* Very inefficient for ISA detects! */
585void sensors_detect(struct i2c_adapter *adapter,
586                    struct sensors_address_data *address_data,
587                    sensors_found_addr_proc *found_proc)
588{
589  int addr,i,found,j;
590  struct sensors_force_data *this_force;
591  unsigned int end_marker = i2c_is_isa_adapter(adapter)?SENSORS_ISA_END:
592                                                        SENSORS_I2C_END;
593  int adapter_id = i2c_is_isa_adapter(adapter)?SENSORS_ISA_BUS:
594                                               i2c_adapter_id(adapter);
595
596  for (addr = 0x00; addr <= i2c_is_isa_adapter(adapter)?0xfff:0x7f; addr ++) {
597    /* If it is in one of the force entries, we don't do any detection
598       at all */
599    found = 0;
600    for (i = 0; 
601         !found && (this_force = address_data->forces+i, this_force->force); 
602         i++) {
603      for (j = 0; !found && (this_force->force[j] != end_marker) ; i += 2) {
604        if (((adapter_id == this_force->force[j]) || 
605             (this_force->force[j] == SENSORS_ANY_I2C_BUS)) &&
606            (addr == this_force->force[j+1])) {
607          found_proc(adapter,addr,this_force->kind);
608          found = 1;
609        }
610      }
611    }
612    if (found)
613      continue;
614
615    /* If this address is in one of the ignores, we can forget about it
616       right now */
617    for (i = 0;
618         !found && (address_data->ignore[i] != end_marker); 
619         i += 2) {
620      if (((adapter_id == address_data->ignore[i]) || 
621           (address_data->ignore[i] == SENSORS_ANY_I2C_BUS)) &&
622          (addr == address_data->ignore[i+1])) {
623        found = 1;
624      }
625    }
626    for (i = 0;
627         !found && (address_data->ignore_range[i] != end_marker);
628         i += 3) {
629      if (((adapter_id == address_data->ignore_range[i]) ||
630           (address_data->ignore_range[i] == SENSORS_ANY_I2C_BUS)) &&
631          (addr >= address_data->ignore_range[i+1]) &&
632          (addr <= address_data->ignore_range[i+2]))
633        found = 1;
634    }
635    if (found)
636      continue;
637
638    /* Now, we will do a detection, but only if it is in the normal or
639       probe entries */
640    if (i2c_is_isa_adapter(adapter)) {
641      for (i = 0;
642           !found && (address_data->normal_isa[i] != SENSORS_ISA_END);
643           i += 1) {
644        if (addr == address_data->normal_isa[i]) {
645          found = 1;
646      }
647      for (i = 0;
648           !found && (address_data->normal_isa_range[i] != SENSORS_I2C_END);
649           i += 3) {
650         if ((addr >= address_data->normal_isa_range[i]) &&
651             (addr <= address_data->normal_isa_range[i+1]) &&
652             ((addr - address_data->normal_isa_range[i]) % 
653                                  address_data->normal_isa_range[i+2] == 0));
654          found = 1;
655        }
656      }
657    } else {
658      for (i = 0;
659           !found && (address_data->normal_i2c[i] != SENSORS_I2C_END);
660           i += 1) {
661        if (addr == address_data->normal_i2c[i]) {
662          found = 1;
663      }
664      for (i = 0;
665           !found && (address_data->normal_i2c_range[i] != SENSORS_I2C_END);
666           i += 2) {
667         if ((addr >= address_data->normal_i2c_range[i]) &&
668             (addr <= address_data->normal_i2c_range[i+1]))
669          found = 1;
670        }
671      }
672    }
673
674    for (i = 0;
675         !found && (address_data->probe[i] != SENSORS_I2C_END);
676         i += 2) {
677      if (((adapter_id == address_data->probe[i]) ||
678           (address_data->probe[i] == SENSORS_ANY_I2C_BUS)) &&
679          (addr == address_data->probe[i+1])) {
680        found = 1;
681      }
682    for (i = 0;
683         !found && (address_data->probe_range[i] != SENSORS_I2C_END);
684         i += 3) {
685      if (((adapter_id == address_data->probe_range[i]) ||
686           (address_data->probe_range[i] == SENSORS_ANY_I2C_BUS)) &&
687          (addr >= address_data->probe_range[i+1]) &&
688          (addr <= address_data->probe_range[i+2])) 
689        found = 1;
690      }
691    }
692    if (!found)
693      continue;
694
695    /* OK, so we really should examine this address. First check
696       whether there is some client here at all! */
697    if (!i2c_is_isa_adapter(adapter) || 
698        (smbus_read_byte(adapter,addr) >= 0))
699      found_proc(adapter,addr,0);
700  }
701}
702     
703int sensors_init(void) 
704{
705  printk("sensors.o version %s (%s)\n",LM_VERSION,LM_DATE);
706  sensors_initialized = 0;
707  if (! (sensors_proc_header = register_sysctl_table(sensors_proc,0)))
708    return -ENOMEM;
709#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58))
710  sensors_proc_header->ctl_table->child->de->fill_inode = &sensors_fill_inode;
711#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) */
712  sensors_initialized ++;
713  return 0;
714}
715
716int sensors_cleanup(void)
717{
718  if (sensors_initialized >= 1) {
719    unregister_sysctl_table(sensors_proc_header);
720    sensors_initialized --;
721  }
722  return 0;
723}
724
725#ifdef MODULE
726
727MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
728MODULE_DESCRIPTION("LM78 driver");
729
730int init_module(void)
731{
732  return sensors_init();
733}
734
735int cleanup_module(void)
736{
737  return sensors_cleanup();
738}
739
740#endif /* MODULE */
741
Note: See TracBrowser for help on using the browser.