root/i2c/trunk/kernel/i2c-proc.c @ 3560

Revision 3560, 24.2 KB (checked in by mds, 12 years ago)

Belatedly sync with kernel 2.4.2 (malloc.h -> slab.h)

Should be ok for 2.2 kernels also.
Thanks J . A . Magallon <jamagallon@…>

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