patch-2.1.132 linux/net/irda/irproc.c

Next file: linux/net/irda/irqueue.c
Previous file: linux/net/irda/irobex/irobex.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.131/linux/net/irda/irproc.c linux/net/irda/irproc.c
@@ -0,0 +1,386 @@
+/*********************************************************************
+ *                
+ * Filename:      irproc.c
+ * Version:       
+ * Description:   Various entries in the /proc file system
+ * Status:        Experimental.
+ * Author:        Thomas Davis, <ratbert@radiks.net>
+ * Created at:    Sat Feb 21 21:33:24 1998
+ * Modified at:   Wed Dec  9 02:26:45 1998
+ * Modified by:   Dag Brattli <dagb@cs.uit.no>
+ * 
+ *     Copyright (c) 1998, Thomas Davis, <ratbert@radiks.net>, 
+ *     All Rights Reserved.
+ *      
+ *     This program is free software; you can redistribute it and/or 
+ *     modify it under the terms of the GNU General Public License as 
+ *     published by the Free Software Foundation; either version 2 of 
+ *     the License, or (at your option) any later version.
+ *  
+ *     I, Thomas Davis, provide no warranty for any of this software. 
+ *     This material is provided "AS-IS" and at no charge. 
+ *     
+ *     Portions lifted from the linux/fs/procfs/ files.
+ *
+ ********************************************************************/
+
+#include <linux/miscdevice.h>
+#include <linux/proc_fs.h>
+
+#include <net/irda/irmod.h>
+#include <net/irda/irlap.h>
+#include <net/irda/irlmp.h>
+
+static int proc_irda_21x_lookup(struct inode * dir, struct dentry *dentry);
+
+static int proc_irda_readdir(struct file *filp, void *dirent, 
+ 			     filldir_t filldir);
+
+extern int irda_device_proc_read( char *buf, char **start, off_t offset, 
+				  int len, int unused);
+extern int irlap_proc_read( char *buf, char **start, off_t offset, int len, 
+			    int unused);
+extern int irlmp_proc_read( char *buf, char **start, off_t offset, int len, 
+			    int unused);
+extern int irttp_proc_read( char *buf, char **start, off_t offset, int len, 
+			    int unused);
+extern int irias_proc_read( char *buf, char **start, off_t offset, int len,
+ 			    int unused);
+
+static int proc_discovery_read( char *buf, char **start, off_t offset, int len,
+				int unused);
+
+/* int proc_irda_readdir(struct inode *inode, struct file *filp, void *dirent,  */
+/* 		      filldir_t filldir); */
+
+enum irda_directory_inos {
+	PROC_IRDA_LAP = 1,
+	PROC_IRDA_LMP,
+	PROC_IRDA_TTP,
+	PROC_IRDA_LPT,
+	PROC_IRDA_COMM,
+ 	PROC_IRDA_IRDA_DEVICE,
+	PROC_IRDA_IRIAS
+};
+
+static struct file_operations proc_irda_dir_operations = {
+        NULL,                   /* lseek - default */
+        NULL,                   /* read - bad */
+        NULL,                   /* write - bad */
+        proc_irda_readdir,      /* readdir */
+        NULL,                   /* select - default */
+        NULL,                   /* ioctl - default */
+        NULL,                   /* mmap */
+        NULL,                   /* no special open code */
+        NULL,                   /* no special release code */
+        NULL                    /* can't fsync */
+};
+
+/*
+ * proc directories can do almost nothing..
+ */
+struct inode_operations proc_irda_dir_inode_operations = {
+        &proc_irda_dir_operations,   /* default net directory file-ops */
+        NULL,                   /* create */
+	proc_irda_21x_lookup, 
+        NULL,                   /* link */
+        NULL,                   /* unlink */
+        NULL,                   /* symlink */
+        NULL,                   /* mkdir */
+        NULL,                   /* rmdir */
+        NULL,                   /* mknod */
+        NULL,                   /* rename */ 
+        NULL,                   /* readlink */
+        NULL,                   /* follow_link */
+        NULL,                   /* readpage */
+        NULL,                   /* writepage */
+        NULL,                   /* bmap */
+        NULL,                   /* truncate */   
+        NULL                    /* permission */
+};
+
+struct proc_dir_entry proc_irda = {
+	0, 4, "irda",
+        S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,
+        0, &proc_irda_dir_inode_operations,
+        NULL, NULL,
+        NULL,
+        NULL, NULL
+};
+
+#if 0 
+struct proc_dir_entry proc_lpt = {
+	0, 3, "lpt",
+	S_IFREG | S_IRUGO, 1, 0, 0,
+	0, NULL /* ops -- default to array */,
+	&irlpt_proc_read /* get_info */,
+};
+#endif
+
+struct proc_dir_entry proc_discovery = {
+	0, 9, "discovery",
+	S_IFREG | S_IRUGO, 1, 0, 0,
+	0, NULL /* ops -- default to array */,
+	&proc_discovery_read /* get_info */,
+};
+
+struct proc_dir_entry proc_irda_device = {
+	0, 11, "irda_device",
+	S_IFREG | S_IRUGO, 1, 0, 0,
+	0, NULL,
+	&irda_device_proc_read,
+};
+
+struct proc_dir_entry proc_ttp = {
+	0, 5, "irttp",
+	S_IFREG | S_IRUGO, 1, 0, 0,
+	0, NULL /* ops -- default to array */,
+	&irttp_proc_read /* get_info */,
+};
+
+struct proc_dir_entry proc_lmp = {
+	0, 5, "irlmp",
+	S_IFREG | S_IRUGO, 1, 0, 0,
+	0, NULL /* ops -- default to array */,
+	&irlmp_proc_read /* get_info */,
+};
+
+struct proc_dir_entry proc_lap = {
+	0, 5, "irlap",
+	S_IFREG | S_IRUGO, 1, 0, 0,
+	0, NULL /* ops -- default to array */,
+	&irlap_proc_read /* get_info */,
+};
+
+struct proc_dir_entry proc_ias = {
+	0, 5, "irias",
+	S_IFREG | S_IRUGO, 1, 0, 0,
+	0, NULL /* ops -- default to array */,
+	&irias_proc_read /* get_info */,
+};
+
+/*
+ * Function proc_delete_dentry (dentry)
+ *
+ *    Copy of proc/root.c because this function is invisible to the irda
+ *    module
+ * 
+ */
+static void proc_delete_dentry(struct dentry * dentry)
+{
+	d_drop(dentry);
+}
+
+static struct dentry_operations proc_dentry_operations =
+{
+	NULL,			/* revalidate */
+	NULL,			/* d_hash */
+	NULL,			/* d_compare */
+	proc_delete_dentry	/* d_delete(struct dentry *) */
+};
+
+/*
+ * Function irda_proc_register (void)
+ *
+ *    Register irda entry in /proc file system
+ *
+ */
+void irda_proc_register(void) {
+	proc_net_register( &proc_irda);
+	proc_register( &proc_irda, &proc_lap);
+	proc_register( &proc_irda, &proc_lmp);
+	proc_register( &proc_irda, &proc_ttp);
+	proc_register( &proc_irda, &proc_ias);
+ 	proc_register( &proc_irda, &proc_irda_device); 
+	proc_register( &proc_irda, &proc_discovery);
+}
+
+/*
+ * Function irda_proc_unregister (void)
+ *
+ *    Unregister irda entry in /proc file system
+ *
+ */
+void irda_proc_unregister(void) {
+	proc_unregister( &proc_irda, proc_discovery.low_ino);
+ 	proc_unregister(&proc_irda, proc_irda_device.low_ino);
+	proc_unregister( &proc_irda, proc_ias.low_ino);
+	proc_unregister( &proc_irda, proc_ttp.low_ino);
+	proc_unregister( &proc_irda, proc_lmp.low_ino);
+	proc_unregister( &proc_irda, proc_lap.low_ino);
+	proc_unregister( proc_net, proc_irda.low_ino);
+}
+
+/*
+ * Function proc_irda_21x_lookup (dir, dentry)
+ *
+ *    This is a copy of proc_lookup from the linux-2.1.x 
+ *
+ */
+int proc_irda_21x_lookup(struct inode * dir, struct dentry *dentry)
+{
+	struct inode *inode;
+	struct proc_dir_entry * de;
+	int error;
+
+	error = -ENOTDIR;
+	if (!dir || !S_ISDIR(dir->i_mode))
+		goto out;
+
+	error = -ENOENT;
+	inode = NULL;
+	de = (struct proc_dir_entry *) dir->u.generic_ip;
+	if (de) {
+		for (de = de->subdir; de ; de = de->next) {
+			if (!de || !de->low_ino)
+				continue;
+			if (de->namelen != dentry->d_name.len)
+				continue;
+			if (!memcmp(dentry->d_name.name, de->name, de->namelen)) {
+				int ino = de->low_ino | (dir->i_ino & ~(0xffff));
+				error = -EINVAL;
+				inode = proc_get_inode(dir->i_sb, ino, de);
+				break;
+			}
+		}
+	}
+
+	if (inode) {
+		dentry->d_op = &proc_dentry_operations;
+		d_add(dentry, inode);
+		error = 0;
+	}
+out:
+	return error;
+}
+
+/*
+ * Function proc_irda_readdir (filp, dirent, filldir)
+ *
+ *    This is a copy from linux/fs/proc because the function is invisible
+ *    to the irda module
+ * 
+ */
+static int proc_irda_readdir( struct file *filp, void *dirent, 
+			      filldir_t filldir)
+{
+	struct proc_dir_entry * de;
+	unsigned int ino;
+	int i;
+	
+	struct inode *inode = filp->f_dentry->d_inode;
+	if (!inode || !S_ISDIR(inode->i_mode))
+		return -ENOTDIR;
+	ino = inode->i_ino;
+	de = (struct proc_dir_entry *) inode->u.generic_ip;
+	if (!de)
+		return -EINVAL;
+	i = filp->f_pos;
+	switch (i) {
+	case 0:
+		if (filldir(dirent, ".", 1, i, ino) < 0)
+			return 0;
+		i++;
+		filp->f_pos++;
+		/* fall through */
+	case 1:
+		if (filldir(dirent, "..", 2, i, de->parent->low_ino) < 0)
+			return 0;
+		i++;
+		filp->f_pos++;
+		/* fall through */
+	default:
+		ino &= ~0xffff;
+		de = de->subdir;
+		i -= 2;
+		for (;;) {
+			if (!de)
+				return 1;
+			if (!i)
+				break;
+			de = de->next;
+			i--;
+		}
+		
+		do {
+			if (filldir(dirent, de->name, de->namelen, filp->f_pos,
+				    ino | de->low_ino) < 0)
+				return 0;
+			filp->f_pos++;
+			de = de->next;
+		} while (de);
+	}
+	return 1;
+}
+
+/*
+ * Function proc_discovery_read (buf, start, offset, len, unused)
+ *
+ *    Print discovery information in /proc file system
+ *
+ */
+int proc_discovery_read( char *buf, char **start, off_t offset, int len, 
+			 int unused)
+{
+	DISCOVERY *discovery;
+	struct lap_cb *lap;
+	unsigned long flags;
+
+	if ( !irlmp)
+		return len;
+
+	len = sprintf(buf, "IrLMP: Discovery log:\n\n");	
+
+
+	save_flags(flags);
+	cli();
+
+	lap = ( struct lap_cb *) hashbin_get_first( irlmp->links);
+	while( lap != NULL) {
+		ASSERT( lap->magic == LMP_LAP_MAGIC, return 0;);
+		
+		len += sprintf( buf+len, "Link saddr=0x%08x\n", lap->saddr);
+		discovery = ( DISCOVERY *) hashbin_get_first( lap->cachelog);
+		while ( discovery != NULL) {
+			len += sprintf( buf+len, "  name: %s,", 
+					discovery->info);
+			
+			len += sprintf( buf+len, " hint: ");
+			if ( discovery->hint[0] & HINT_PNP)
+				len += sprintf( buf+len, "PnP Compatible ");
+			if ( discovery->hint[0] & HINT_PDA)
+				len += sprintf( buf+len, "PDA/Palmtop ");
+			if ( discovery->hint[0] & HINT_COMPUTER)
+				len += sprintf( buf+len, "Computer ");
+			if ( discovery->hint[0] & HINT_PRINTER)
+				len += sprintf( buf+len, "Printer ");
+			if ( discovery->hint[0] & HINT_MODEM)
+				len += sprintf( buf+len, "Modem ");
+			if ( discovery->hint[0] & HINT_FAX)
+				len += sprintf( buf+len, "Fax ");
+			if ( discovery->hint[0] & HINT_LAN)
+				len += sprintf( buf+len, "LAN Access");
+			
+			if ( discovery->hint[1] & HINT_TELEPHONY)
+				len += sprintf( buf+len, "Telephony ");
+			if ( discovery->hint[1] & HINT_FILE_SERVER)
+				len += sprintf( buf+len, "File Server ");       
+			if ( discovery->hint[1] & HINT_COMM)
+				len += sprintf( buf+len, "IrCOMM ");
+			if ( discovery->hint[1] & HINT_OBEX)
+				len += sprintf( buf+len, "IrOBEX ");
+			
+			len += sprintf( buf+len, ", daddr: 0x%08x\n", 
+					discovery->daddr);
+			
+			len += sprintf( buf+len, "\n");
+			
+			discovery = ( DISCOVERY *) hashbin_get_next( lap->cachelog);
+		}
+		lap = ( struct lap_cb *) hashbin_get_next( irlmp->links);
+	}
+	restore_flags(flags);
+
+	return len;
+}
+

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov