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

Revision 496, 24.0 KB (checked in by frodo, 14 years ago)

First round of lm_sensors changes for the new I2C tree

* The i2c package can no longer be compiled as part of the lm_sensors tree
* The archive of the i2c package is removed
* smbus, i2c-dev and i2c-proc modules and headers have been removed; they

are now completely integrated into the i2c package

* The fake i2c.h header has been removed; this also allowed us to remove

the ugly LM_SENSORS and TBD defines.

* A new variable I2C_HEADERS is introduced in the Makefile. This allows

us to install the i2c headers in, for example, /usr/local/include/linux.

* All files now include <linux/i2c.h> instead of "i2c.h" and "smbus.h"

Status: 'make dep' works, all the right include files are found. 'make all'

does not yet work.

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