/proc/sys/board patch for SIMpad

Till Harbaum <[email protected]> Wed, 15 Sep 2004 16:06:42 +0200
Newsgroups gmane.comp.handhelds.openembedded,gmane.comp.handhelds.simpad.linux
Organization BeeCon GmbH
Message-ID <[email protected]>
Hi all,

during my work on bluetooth for the simpad i have managed to crash my simpad 
several times when trying to access /proc/cs3.

I think the current interface isn't very user friendly. Therefore i have come 
up with a new interface in /proc/sys/net/board. The new interface has two 
advantages: 

1) Each bit can be accessed seperately, thus avoiding the risk of touching 
   other bits
2) Each bit can be protected seperately. There are bits that shouldn't be 
   accessible to the user. These bits are set read only.

With the attached patch only these bits can be changed from user space:
DISPLAY_ON, DECT_POWER_ON, IRDA_SD, SD_MEDIAQ, LED2_ON, IRDA_MODE, and 
RESET_SIMCARD.

Please tell me if you think one of these should not be user accessible or if 
one of the others should be user accessible.

The /proc/cs3 interface should imho be completely disabled asap, since it has 
the risk of crashing the device (or even damanging it? enabling 3.3v and 5v 
at the same time sounds like a very bad idea ...). In the next days i'll make 
a new patch for libopie2 to make use of the new interface. IMHO all 
applications should use the new interface as soon as possible.

Holger, do you want the new libopie2 patch on top of the old one or 
independant from it?

Example use of the new interface:
root@simpad:~# ls -l /proc/sys/board/
-r--r--r--    1 root     root            0 Jan  1 00:03 cs3
-rw-rw-r--    1 root     root            0 Jan  1 00:03 dect_power_on
-rw-rw-r--    1 root     root            0 Jan  1 00:03 display_on
-r--r--r--    1 root     root            0 Jan  1 00:03 en0
-r--r--r--    1 root     root            0 Jan  1 00:03 en1
-r--r--r--    1 root     root            0 Jan  1 00:03 enable_5v
-rw-rw-r--    1 root     root            0 Jan  1 00:03 irda_mode
-rw-rw-r--    1 root     root            0 Jan  1 00:03 irda_sd
-rw-rw-r--    1 root     root            0 Jan  1 00:03 led2_on
-r--r--r--    1 root     root            0 Jan  1 00:03 mq_reset
-r--r--r--    1 root     root            0 Jan  1 00:03 pcmcia_buff_dis
-r--r--r--    1 root     root            0 Jan  1 00:03 pcmcia_reset
-rw-rw-r--    1 root     root            0 Jan  1 00:03 reset_simcard
-r--r--r--    1 root     root            0 Jan  1 00:03 rs232_on
-rw-rw-r--    1 root     root            0 Jan  1 00:03 sd_mediaq
-r--r--r--    1 root     root            0 Jan  1 00:03 sys_name
-r--r--r--    1 root     root            0 Jan  1 00:03 vcc_3v_en
-r--r--r--    1 root     root            0 Jan  1 00:03 vcc_5v_en
root@simpad:~# cat /proc/sys/board/sys_name
SIMpad
root@simpad:~# cat /proc/sys/board/display_on
1
root@simpad:~# echo 0 >/proc/sys/board/display_on
root@simpad:~# echo 1 >/proc/sys/board/display_on
root@simpad:~# cat /proc/sys/board/vcc_5v_en
0
root@simpad:~# echo 1 >/proc/sys/board/vcc_5v_en
-sh: cannot create /proc/sys/board/vcc_5v_en: Permission denied

BTW: What LED is controlles by the led2_on? This bit obviously cannot be 
written.

Ciao,
  Till

-- 
Dr.-Ing. Till Harbaum                       Tel.:  +49 721 4998963
BeeCon GmbH                                 Fax:   +49 721 4998962
Haid-und-Neu Strasse 7, 76131 Karlsruhe     Mobil: +49 179 9087904
[email protected]                           http://www.beecon.de

_______________________________________________
Oe mailing list
[email protected]
https://handhelds.org/mailman/listinfo/oe
kernel-simpad-proc-sys-board.patch (text/x-diff, 7.8 KB)
--- drivers/char/Makefile~	2004-09-15 12:06:16.000000000 +0200
+++ drivers/char/Makefile	2004-09-15 14:33:43.000000000 +0200
@@ -134,6 +134,9 @@
   ifeq ($(CONFIG_SA1100_CERF_CPLD),y)
     KEYBD    += cerf_keyb.o
   endif
+  ifeq ($(CONFIG_SA1100_SIMPAD),y)
+    obj-$(CONFIG_SA1100_SIMPAD) += sysctl.o
+  endif
   ifeq ($(CONFIG_ARCH_FORTUNET),y)
     KEYMAP   := defkeymap.o
   endif
--- /dev/null	2003-03-14 14:07:09.000000000 +0100
+++ drivers/char/sysctl.c	2004-09-15 15:36:03.000000000 +0200
@@ -0,0 +1,297 @@
+/*
+ *  /proc/sys/board - Interface to the SIMpad cs3 register
+ *
+ *  (c) 2004 by Till Harbaum, BeeCon GmbH, <[email protected]>
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/sysctl.h>
+#include <linux/crc32.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+
+#include <asm/io.h>
+#include <asm/arch/simpad.h>
+#include <asm/uaccess.h>
+
+extern long get_cs3_shadow(void);
+extern void set_cs3_bit(int value);
+extern void clear_cs3_bit(int value);
+
+/*
+ * This is the number for the "board" entry in /proc/sys:
+ */
+#define SIMPAD_SYSCTL 1312
+
+/*
+ * These are the numbers for the entries in /etc/sys/board
+ */
+enum {
+	CTL_NAME=991,
+	CTL_CS3,          // the complete latch
+	CTL_VCC_5V_EN,    // For 5V PCMCIA 
+        CTL_VCC_3V_EN,    // FOR 3.3V PCMCIA
+        CTL_EN1,          // This is only for EPROM's
+        CTL_EN0,          // Both should be enable for 3.3V or 5V
+        CTL_DISPLAY_ON,
+        CTL_PCMCIA_BUFF_DIS,
+        CTL_MQ_RESET,
+        CTL_PCMCIA_RESET,
+        CTL_DECT_POWER_ON,
+        CTL_IRDA_SD,      // Shutdown for powersave
+        CTL_RS232_ON, 
+        CTL_SD_MEDIAQ,    // Shutdown for powersave
+        CTL_LED2_ON,
+        CTL_IRDA_MODE,    // Fast/Slow IrDA mode
+        CTL_ENABLE_5V,    // Enable 5V circuit
+        CTL_RESET_SIMCARD
+};
+
+static const char simpad_board_name[] = "SIMpad";
+static int  dummy_int;
+static char dummy_str[80];
+
+static int
+simpad_sysctl_handler(ctl_table * ctl, int write, struct file *filp,
+		      void *buffer, size_t * lenp)
+{
+	int *valp = ctl->data;
+	int val;
+	int ret;
+
+	// Update parameters from the real registers
+	switch (ctl->ctl_name) {
+	case CTL_CS3:
+	    sprintf(dummy_str, "0x%04lx", get_cs3_shadow());
+	    return proc_dostring(ctl,write,filp,buffer,lenp);
+	    break;
+
+        // the 16 control bits of the cs3 register
+        case CTL_VCC_5V_EN:
+	case CTL_VCC_3V_EN:
+	case CTL_EN1:
+	case CTL_EN0:
+	case CTL_DISPLAY_ON:
+	case CTL_PCMCIA_BUFF_DIS:
+	case CTL_MQ_RESET:
+	case CTL_PCMCIA_RESET:
+	case CTL_DECT_POWER_ON:
+	case CTL_IRDA_SD:
+	case CTL_RS232_ON:
+	case CTL_SD_MEDIAQ:
+	case CTL_LED2_ON:
+	case CTL_IRDA_MODE:
+	case CTL_ENABLE_5V:
+	case CTL_RESET_SIMCARD:
+	        *valp = (get_cs3_shadow() & 
+		        (1u << (ctl->ctl_name-CTL_VCC_5V_EN)))?1:0;
+                break;
+
+	default:
+		// Just ignore unsupported parameters
+		break;
+	}
+
+	// the strings are all handled now and ran onto a return;
+
+	// Save old state
+	val = *valp;
+
+	// Perform the generic integer operation        
+	if ((ret = proc_dointvec(ctl, write, filp, buffer, lenp)) != 0)
+		return (ret);
+
+	// Write changes out to the registers
+	if (write && *valp != val) {
+
+		val = *valp;
+		switch (ctl->ctl_name) {
+
+                // the 16 control bits of the cs3 register
+	        case CTL_DISPLAY_ON:
+	        case CTL_DECT_POWER_ON:
+  	        case CTL_IRDA_SD:
+	        case CTL_SD_MEDIAQ:
+	        case CTL_LED2_ON:
+	        case CTL_IRDA_MODE:
+	        case CTL_RESET_SIMCARD:
+		        if (val) 
+		                set_cs3_bit(1u << (ctl->ctl_name-CTL_VCC_5V_EN));
+		        else     
+		                clear_cs3_bit(1u << (ctl->ctl_name-CTL_VCC_5V_EN));
+                break;
+
+		default:
+			// Just ignore unsupported parameters
+			break;
+		}
+	}
+
+	return ret;
+}
+
+#define PROC_RDONLY 0444
+#define PROC_RDWR   0664
+
+static ctl_table simpad_table[] = {
+        {
+	 procname:	"sys_name",
+	 ctl_name:	CTL_NAME, 
+	 data:		&simpad_board_name,
+	 maxlen:	sizeof(simpad_board_name),
+         proc_handler:	&proc_dostring,
+	 mode:		PROC_RDONLY,
+	}, {
+	 procname:	"cs3",
+	 ctl_name:	CTL_CS3, 
+	 data:		&dummy_str,
+	 maxlen:	sizeof(dummy_str),
+         proc_handler:	&simpad_sysctl_handler,
+	 mode:		PROC_RDONLY,
+	}, {
+	 procname:	"vcc_5v_en",
+	 ctl_name:	CTL_VCC_5V_EN,
+	 data:		&dummy_int,
+	 maxlen:	sizeof(int),
+         proc_handler:	&simpad_sysctl_handler,
+	 mode:		PROC_RDONLY,
+	}, {
+	 procname:	"vcc_3v_en",
+	 ctl_name:	CTL_VCC_3V_EN,
+	 data:		&dummy_int,
+	 maxlen:	sizeof(int),
+         proc_handler:	&simpad_sysctl_handler,
+	 mode:		PROC_RDONLY,
+	}, {
+	 procname:	"en1",
+	 ctl_name:	CTL_EN1,
+	 data:		&dummy_int,
+	 maxlen:	sizeof(int),
+         proc_handler:	&simpad_sysctl_handler,
+	 mode:		PROC_RDONLY,
+	}, {
+	 procname:	"en0",
+	 ctl_name:	CTL_EN0,
+	 data:		&dummy_int,
+	 maxlen:	sizeof(int),
+         proc_handler:	&simpad_sysctl_handler,
+	 mode:		PROC_RDONLY,
+	}, {
+	 procname:	"display_on",
+	 ctl_name:	CTL_DISPLAY_ON,
+	 data:		&dummy_int,
+	 maxlen:	sizeof(int),
+         proc_handler:	&simpad_sysctl_handler,
+	 mode:		PROC_RDWR,
+	}, {
+	 procname:	"pcmcia_buff_dis",
+	 ctl_name:	CTL_PCMCIA_BUFF_DIS,
+	 data:		&dummy_int,
+	 maxlen:	sizeof(int),
+         proc_handler:	&simpad_sysctl_handler,
+	 mode:		PROC_RDONLY,
+	}, {
+	 procname:	"mq_reset",
+	 ctl_name:	CTL_MQ_RESET,
+	 data:		&dummy_int,
+	 maxlen:	sizeof(int),
+         proc_handler:	&simpad_sysctl_handler,
+	 mode:		PROC_RDONLY,
+	}, {
+	 procname:	"pcmcia_reset",
+	 ctl_name:	CTL_PCMCIA_RESET,
+	 data:		&dummy_int,
+	 maxlen:	sizeof(int),
+         proc_handler:	&simpad_sysctl_handler,
+	 mode:		PROC_RDONLY,
+	}, {
+	 procname:	"dect_power_on",
+	 ctl_name:	CTL_DECT_POWER_ON,
+	 data:		&dummy_int,
+	 maxlen:	sizeof(int),
+         proc_handler:	&simpad_sysctl_handler,
+	 mode:		PROC_RDWR,
+	}, {
+	 procname:	"irda_sd",
+	 ctl_name:	CTL_IRDA_SD,
+	 data:		&dummy_int,
+	 maxlen:	sizeof(int),
+         proc_handler:	&simpad_sysctl_handler,
+	 mode:		PROC_RDWR,
+	}, {
+	 procname:	"rs232_on",
+	 ctl_name:	CTL_RS232_ON,
+	 data:		&dummy_int,
+	 maxlen:	sizeof(int),
+         proc_handler:	&simpad_sysctl_handler,
+	 mode:		PROC_RDONLY,
+	}, {
+	 procname:	"sd_mediaq",
+	 ctl_name:	CTL_SD_MEDIAQ,
+	 data:		&dummy_int,
+	 maxlen:	sizeof(int),
+         proc_handler:	&simpad_sysctl_handler,
+	 mode:		PROC_RDWR,
+	}, {
+	 procname:	"led2_on",
+	 ctl_name:	CTL_LED2_ON,
+	 data:		&dummy_int,
+	 maxlen:	sizeof(int),
+         proc_handler:	&simpad_sysctl_handler,
+	 mode:		PROC_RDWR,
+	}, {
+	 procname:	"irda_mode",
+	 ctl_name:	CTL_IRDA_MODE,
+	 data:		&dummy_int,
+	 maxlen:	sizeof(int),
+         proc_handler:	&simpad_sysctl_handler,
+	 mode:		PROC_RDWR,
+	}, {
+	 procname:	"enable_5v",
+	 ctl_name:	CTL_ENABLE_5V,
+	 data:		&dummy_int,
+	 maxlen:	sizeof(int),
+         proc_handler:	&simpad_sysctl_handler,
+	 mode:		PROC_RDONLY,
+	}, {
+	 procname:	"reset_simcard",
+	 ctl_name:	CTL_RESET_SIMCARD,
+	 data:		&dummy_int,
+	 maxlen:	sizeof(int),
+         proc_handler:	&simpad_sysctl_handler,
+	 mode:		PROC_RDWR,
+	},
+        {0}
+        };
+
+static ctl_table simpad_root_table[] = {
+        {SIMPAD_SYSCTL, "board", NULL, 0, 0555, simpad_table},
+        {0}
+        };
+
+
+static struct ctl_table_header *simpad_table_header;
+
+
+static int __init simpad_sysctl_init(void) 
+{
+        simpad_table_header = register_sysctl_table(simpad_root_table, 0);
+        if (!simpad_table_header)
+                return -ENOMEM;
+        return 0;
+}
+
+static void __exit simpad_sysctl_exit(void)
+{
+        unregister_sysctl_table(simpad_table_header);
+}
+
+
+module_init(simpad_sysctl_init);
+module_exit(simpad_sysctl_exit);
+
+MODULE_AUTHOR("Till Harbaum <[email protected]>");
+MODULE_DESCRIPTION("Implements /proc/sys/board");
+MODULE_LICENSE("GPL");