]> rtime.felk.cvut.cz Git - lincan.git/blobdiff - lincan/src/proc.c
LinCAN sources go through big white-space cleanup.
[lincan.git] / lincan / src / proc.c
index 02522b18b4c034825ad49bbe8b86564898f3702c..7cb69c3a1da75073aafa7de0fe77fda365b32cb3 100644 (file)
@@ -1,11 +1,36 @@
-/* proc.c
- * Linux CAN-bus device driver.
- * Written by Arnaud Westenberg email:arnaud@wanadoo.nl
- * Rewritten for new CAN queues by Pavel Pisa - OCERA team member
- * email:pisa@cmp.felk.cvut.cz
- * This software is released under the GPL-License.
- * Version lincan-0.2  9 Jul 2003
- */ 
+/**************************************************************************/
+/* File: proc.c - proc filesystem entries for CAN driver                  */
+/*                                                                        */
+/* LinCAN - (Not only) Linux CAN bus driver                               */
+/* Copyright (C) 2002-2009 DCE FEE CTU Prague <http://dce.felk.cvut.cz>   */
+/* Copyright (C) 2002-2009 Pavel Pisa <pisa@cmp.felk.cvut.cz>             */
+/* Funded by OCERA and FRESCOR IST projects                               */
+/* Based on CAN driver code by Arnaud Westenberg <arnaud@wanadoo.nl>      */
+/*                                                                        */
+/* LinCAN is free software; you can redistribute it and/or modify it      */
+/* under terms of the GNU General Public License as published by the      */
+/* Free Software Foundation; either version 2, or (at your option) any    */
+/* later version.  LinCAN is distributed in the hope that it will be      */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty    */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU    */
+/* General Public License for more details. You should have received a    */
+/* copy of the GNU General Public License along with LinCAN; see file     */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                              */
+/*                                                                        */
+/* To allow use of LinCAN in the compact embedded systems firmware        */
+/* and RT-executives (RTEMS for example), main authors agree with next    */
+/* special exception:                                                     */
+/*                                                                        */
+/* Including LinCAN header files in a file, instantiating LinCAN generics */
+/* or templates, or linking other files with LinCAN objects to produce    */
+/* an application image/executable, does not by itself cause the          */
+/* resulting application image/executable to be covered by                */
+/* the GNU General Public License.                                        */
+/* This exception does not however invalidate any other reasons           */
+/* why the executable file might be covered by the GNU Public License.    */
+/* Publication of enhanced or derived LinCAN files is required although.  */
+/**************************************************************************/
 
 #include "../include/can.h"
 #include "../include/can_sysdep.h"
@@ -25,6 +50,12 @@ int remove_object_from_procdir(int chip_nr);
 static int can_proc_readlink(struct proc_dir_entry *ent, char *page);
 #endif
 
+#if  LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,25)
+#define CAN_PROC_ROOT (&proc_root)
+#else /* >= 2.6.26 */
+#define CAN_PROC_ROOT (NULL)
+#endif /* >= 2.6.26 */
+
 static int cc=0; /* static counter for each CAN chip */
 
 static struct canproc_t can_proc_base;
@@ -48,14 +79,14 @@ static struct proc_dir_entry * can_create_proc_entry(const char *name, mode_t mo
        struct proc_dir_entry *new_entry = NULL;
        char *namestore;
        int namelen;
-       
+
        if(!name || !parent)
                return NULL;
        namelen=strlen(name);
        if(!namelen)
                return NULL;
 
-       new_entry = (struct proc_dir_entry *) 
+       new_entry = (struct proc_dir_entry *)
                        can_checked_malloc(sizeof(struct proc_dir_entry)+namelen+1);
 
        if (new_entry == NULL)
@@ -94,7 +125,7 @@ static int can_remove_proc_entry(struct proc_dir_entry *del, struct proc_dir_ent
 static int can_proc_readlink(struct proc_dir_entry *ent, char *page)
 {
        char *link_dest = (char*)ent->data;
-       
+
        strcpy(page, link_dest);
        return strlen(link_dest);
 }
@@ -106,8 +137,8 @@ static inline struct proc_dir_entry *can_proc_symlink(const char *name,
                 struct proc_dir_entry *parent, const char *dest)
 {
        struct proc_dir_entry *entry;
-       
-       
+
+
        entry = can_create_proc_entry(name, S_IFLNK | S_IRUGO | S_IWUGO | S_IXUGO, parent);
        if (entry == NULL)
                return NULL;
@@ -149,15 +180,15 @@ int can_init_procdir(void)
 {
        int board;
        struct candevice_t *candev;
-       base->can_proc_entry = can_create_proc_entry("can", S_IFDIR | S_IRUGO | 
-                                       S_IXUGO, &proc_root);
+       base->can_proc_entry = can_create_proc_entry("can", S_IFDIR | S_IRUGO |
+                                       S_IXUGO, CAN_PROC_ROOT);
        if (base->can_proc_entry == NULL)
                return -ENODEV;
 
        for (board=0; board<hardware_p->nr_boards; board++) {
                candev=hardware_p->candevice[board];
                if(candev) add_channel_to_procdir(candev);
-       } 
+       }
 
        return 0;
 }
@@ -165,15 +196,45 @@ int can_init_procdir(void)
 /* can_delete_procdir removes the entire CAN tree from the proc system */
 int can_delete_procdir(void)
 {
-       if (remove_channel_from_procdir()) 
+       if (remove_channel_from_procdir())
                return -ENODEV;
        /* name: "can" */
-       if (can_remove_proc_entry(base->can_proc_entry, &proc_root)) 
+       if (can_remove_proc_entry(base->can_proc_entry, CAN_PROC_ROOT))
                return -ENODEV;
 
        return 0;
 }
 
+static int can_chip_procinfo(char *buf, char **start, off_t offset,
+                int count, int *eof, void *data)
+{
+       struct canchip_t *chip=data;
+       int len=0;
+
+       /* Generic chip info */
+       len += sprintf(buf+len,"type    : %s\n",chip->chip_type);
+       len += sprintf(buf+len,"index   : %d\n",chip->chip_idx);
+       len += sprintf(buf+len,"irq     : %d\n",chip->chip_irq);
+       len += sprintf(buf+len,"addr    : %lu\n",
+                       can_ioptr2ulong(chip->chip_base_addr));
+       len += sprintf(buf+len,"config  : %s\n",
+                       (chip->flags & CHIP_CONFIGURED) ? "yes":"no");
+       len += sprintf(buf+len,"clock   : %ld Hz\n",chip->clock);
+       len += sprintf(buf+len,"baud    : %ld\n",chip->baudrate);
+       len += sprintf(buf+len,"num obj : %d\n",chip->max_objects);
+
+
+#if 0
+       /* Chip specific info if available */
+       if(chip->chipspecops->get_info)
+               len += (chip->chipspecops->get_info)(chip,buf+len);
+#endif
+
+       *eof = 1;
+       return len;
+}
+
+
 int add_channel_to_procdir(struct candevice_t *candev)
 {
        int i=0;
@@ -186,7 +247,7 @@ int add_channel_to_procdir(struct candevice_t *candev)
                        return -ENOMEM;
 
                sprintf(base->channel[cc]->ch_name, "channel%d",cc);
-                                               
+
                base->channel[cc]->ch_entry = can_create_proc_entry(
                                                base->channel[cc]->ch_name,
                                                S_IFDIR | S_IRUGO |S_IXUGO,
@@ -197,28 +258,36 @@ int add_channel_to_procdir(struct candevice_t *candev)
 
                add_object_to_procdir(cc);
 
+               create_proc_read_entry("chip_info",        /* proc entry name */
+                                      0,                  /* protection mask, 0->default */
+                                      base->channel[cc]->ch_entry,  /* parent dir, NULL->/proc */
+                                      can_chip_procinfo,
+                                      candev->chip[i]);
+
                cc++;
-       } 
+       }
 
        return 0;
 }
 
 int remove_channel_from_procdir(void)
 {
-       
+
        while (cc != 0) {
                cc--;
-               
+
                if(!base->channel[cc]) continue;
-               
+
+               remove_proc_entry("chip_info", base->channel[cc]->ch_entry);
+
                if (remove_object_from_procdir(cc))
-                       return -ENODEV; 
-                       
+                       return -ENODEV;
+
                /* name: base->channel[cc]->ch_name */
                if (can_remove_proc_entry(base->channel[cc]->ch_entry,
                                                        base->can_proc_entry))
                        return -ENODEV;
-                       
+
                can_checked_free(base->channel[cc]);
                base->channel[cc] = NULL;
        }
@@ -242,7 +311,7 @@ int add_object_to_procdir(int chip_nr)
 
                sprintf(base->channel[chip_nr]->object[i]->obj_name,"object%d",i);
                sprintf(base->channel[chip_nr]->object[i]->lnk_name,"dev");
-                                                               
+
                base->channel[chip_nr]->object[i]->obj_entry = can_create_proc_entry(
                                base->channel[chip_nr]->object[i]->obj_name,
                                S_IFDIR | S_IRUGO | S_IXUGO,
@@ -262,7 +331,7 @@ int add_object_to_procdir(int chip_nr)
 
        }
        return 0;
-} 
+}
 
 int remove_object_from_procdir(int chip_nr)
 {
@@ -272,10 +341,10 @@ int remove_object_from_procdir(int chip_nr)
 
        for (i=0; i<obj; i++) {
                if(!base->channel[chip_nr]->object[i]) continue;
-               
+
                /* name: base->channel[chip_nr]->object[i]->lnk_name */
                if (can_remove_proc_entry( base->channel[chip_nr]->object[i]->lnk,
-                               base->channel[chip_nr]->object[i]->obj_entry))  
+                               base->channel[chip_nr]->object[i]->obj_entry))
                        return -ENODEV;
                /* name: base->channel[chip_nr]->object[i]->obj_name */
                if (can_remove_proc_entry(