From: rnhodek@inf2.informatik.uni-erlangen.de (Roman Hodek)
Date: Thu, 31 Jul 1997 21:48:53 +0200 (CEST)
To: linux-m68k@phil.uni-sb.de
Subject: L68K: Misc patches for 2.1.47
Sender: owner-linux-m68k@phil.uni-sb.de
Reply-To: linux-m68k@phil.uni-sb.de


Ok, here's my bunch of patches:

 - In m68kserial.c where the whippet stuff is, the #endif should be
   one line below, the whole if belongs to the m68k part.

 - As I've written the ACSI driver, I thought that the HDIO_GETGEO
   call is just a PCish braindamage... But now that I write Atari
   LILO, I see that that ioctl also returns the start sector of a
   partition, which I need badly...

   So implemented HDIO_GETGEO for ACSI now. The geometry itself is
   always faked (Adaptec 64/32 mapping).

 - The MAGIC_SYSRQ stuff is nice -- if the author wouldn't have
   hardcoded all the scancodes... typical PC programmer :-) I've
   introduced some abstactions for this.

   For m68k, there are two new mach_* variables: mach_sysrq_key, the
   key that triggers the SysRq mode (-1 if undefined), and
   mach_sysrq_keys, which is an array of scancodes for the various
   functions in SysRq mode. Indices in this array are defined in
   sysrq.h. The Amiga codes still need be filled in.

Roman

------------------------------------------------------------------------------

diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.47-orig/arch/m68k/amiga/config.c linux-2.1.47/arch/m68k/amiga/config.c
--- linux-2.1.47-orig/arch/m68k/amiga/config.c	Thu Jul 31 18:17:20 1997
+++ linux-2.1.47/arch/m68k/amiga/config.c	Thu Jul 31 21:07:09 1997
@@ -89,6 +89,27 @@
     NULL, NULL, amiga_wait_key
 };
 
+#ifdef CONFIG_MAGIC_SYSRQ
+static int amiga_sysrq_keys[] = {
+	-1, /* R */
+	-1, /* A */
+	-1, /* B */
+	-1, /* H */
+	-1, /* O */
+	-1, /* S */
+	-1, /* U */
+	-1, /* P */
+	-1, /* T */
+	-1, /* M */
+	-1,	/* 1 */
+	-1, /* 0 */
+	-1, /* E */
+	-1, /* K */
+	-1, /* L */
+	-1
+};
+#endif
+
 extern void (*kd_mksound)(unsigned int, unsigned int);
 
     /*
@@ -347,6 +368,10 @@
   mach_fb_init         = amiga_fb_init;
   mach_video_setup     = amiga_video_setup;
   kd_mksound           = amiga_mksound;
+#ifdef CONFIG_MAGIC_SYSRQ
+  mach_sysrq_key = -1;
+  mach_sysrq_keys = amiga_sysrq_keys;
+#endif
 
   /* Fill in the clock values (based on the 700 kHz E-Clock) */
   amiga_masterclock = 40*amiga_eclock;	/* 28 MHz */
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.47-orig/arch/m68k/atari/config.c linux-2.1.47/arch/m68k/atari/config.c
--- linux-2.1.47-orig/arch/m68k/atari/config.c	Thu Jul 31 18:17:08 1997
+++ linux-2.1.47/arch/m68k/atari/config.c	Thu Jul 31 21:14:05 1997
@@ -94,6 +94,26 @@
  * not be repeated; used by kgdb */
 int atari_SCC_reset_done = 0;
 
+#ifdef CONFIG_MAGIC_SYSRQ
+static int atari_sysrq_keys[] = {
+	19, /* R */
+	30, /* A */
+	48, /* B */
+	35, /* H */
+	24, /* O */
+	31, /* S */
+	22, /* U */
+	25, /* P */
+	20, /* T */
+	50, /* M */
+	2,  /* 1 */
+	11, /* 0 */
+	18, /* E */
+	37, /* K */
+	38, /* L */
+	-1
+};
+#endif
 
 extern void (*kd_mksound)(unsigned int, unsigned int);
 
@@ -275,6 +295,10 @@
     mach_max_dma_address = 0xffffff;
     mach_video_setup	 = atari_video_setup;
     kd_mksound		 = atari_mksound;
+#ifdef CONFIG_MAGIC_SYSRQ
+	mach_sysrq_key = 98; /* HELP */
+	mach_sysrq_keys = atari_sysrq_keys;
+#endif
 
     /* ++bjoern: 
      * Determine hardware present
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.47-orig/arch/m68k/kernel/setup.c linux-2.1.47/arch/m68k/kernel/setup.c
--- linux-2.1.47-orig/arch/m68k/kernel/setup.c	Fri May 16 19:47:11 1997
+++ linux-2.1.47/arch/m68k/kernel/setup.c	Thu Jul 31 21:01:39 1997
@@ -83,6 +83,11 @@
 void (*mach_floppy_eject) (void) = NULL;
 #endif
 
+#ifdef CONFIG_MAGIC_SYSRQ
+int mach_sysrq_key = -1;
+int *mach_sysrq_keys = NULL;
+#endif
+
 extern int amiga_parse_bootinfo(const struct bi_record *);
 extern int atari_parse_bootinfo(const struct bi_record *);
 
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.47-orig/drivers/block/acsi.c linux-2.1.47/drivers/block/acsi.c
--- linux-2.1.47-orig/drivers/block/acsi.c	Thu Jul 17 17:44:39 1997
+++ linux-2.1.47/drivers/block/acsi.c	Thu Jul 31 20:21:58 1997
@@ -59,8 +59,11 @@
 #include <linux/major.h>
 #include <linux/blk.h>
 #include <linux/malloc.h>
-
 #include <linux/interrupt.h>
+#include <scsi/scsi.h> /* for SCSI_IOCTL_GET_IDLUN */
+typedef void Scsi_Device; /* hack to avoid including scsi.h */
+#include <scsi/scsi_ioctl.h>
+#include <linux/hdreg.h> /* for HDIO_GETGEO */
 
 #include <asm/setup.h>
 #include <asm/pgtable.h>
@@ -1121,12 +1124,30 @@
 	if (dev >= NDevices)
 		return -EINVAL;
 	switch (cmd) {
-		/* I left out the GETGEO cmd; This doesn't make much sense for
-		 * ACSI disks...
-		 */
+	  case HDIO_GETGEO:
+		/* HDIO_GETGEO is supported more for getting the partition's start
+		 * sector... */
+	  { struct hd_geometry *geo = (struct hd_geometry *)arg;
+	    /* just fake some geometry here, it's nonsense anyway; to make it
+		 * easy, use Adaptec's usual 64/32 mapping */
+	    put_user( 64, &geo->heads );
+	    put_user( 32, &geo->sectors );
+	    put_user( acsi_info[dev].size >> 11, &geo->cylinders );
+		put_user( acsi_part[MINOR(inode->i_rdev)].start_sect, &geo->start );
+		return 0;
+	  }
+		
+	  case SCSI_IOCTL_GET_IDLUN:
+		/* SCSI compatible GET_IDLUN call to get target's ID and LUN number */
+		put_user( acsi_info[dev].target | (acsi_info[dev].lun << 8),
+				  &((Scsi_Idlun *) arg)->dev_id );
+		put_user( 0, &((Scsi_Idlun *) arg)->host_unique_id );
+		return 0;
+		
 	  case BLKGETSIZE:   /* Return device size */
 		return put_user(acsi_part[MINOR(inode->i_rdev)].nr_sects,
 				(long *) arg);
+		
 	  case BLKFLSBUF:
 		if(!suser())  return -EACCES;
 		if(!inode->i_rdev) return -EINVAL;
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.47-orig/drivers/char/keyboard.c linux-2.1.47/drivers/char/keyboard.c
--- linux-2.1.47-orig/drivers/char/keyboard.c	Tue Jun 17 13:38:33 1997
+++ linux-2.1.47/drivers/char/keyboard.c	Thu Jul 31 21:31:55 1997
@@ -148,7 +148,6 @@
 struct pt_regs * kbd_pt_regs;
 
 #ifdef CONFIG_MAGIC_SYSRQ
-#define SYSRQ_KEY 0x54
 extern void handle_sysrq(int, struct pt_regs *, struct kbd_struct *, struct tty_struct *);
 static int sysrq_pressed;
 #endif
@@ -234,7 +233,7 @@
  		rep = test_and_set_bit(keycode, key_down);
 
 #ifdef CONFIG_MAGIC_SYSRQ		/* Handle the SysRq Hack */
-	if (keycode == SYSRQ_KEY) {
+	if (kbd_is_sysrq(keycode)) {
 		sysrq_pressed = !up_flag;
 		return;
 	} else if (sysrq_pressed) {
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.47-orig/drivers/char/m68kserial.c linux-2.1.47/drivers/char/m68kserial.c
--- linux-2.1.47-orig/drivers/char/m68kserial.c	Thu Jul 31 18:43:13 1997
+++ linux-2.1.47/drivers/char/m68kserial.c	Thu Jul 31 18:51:58 1997
@@ -1530,8 +1530,8 @@
 		if (req->line >= NR_PORTS)
 		    return -EINVAL;
 		if (rs_table[req->line].type != PORT_UNKNOWN ||
-#endif
 		    rs_table[req->line].count > 0) {
+#endif
 		    /* already allocated */
 		    restore_flags(flags);
 		    return -EBUSY;
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.47-orig/drivers/char/pc_keyb.c linux-2.1.47/drivers/char/pc_keyb.c
--- linux-2.1.47-orig/drivers/char/pc_keyb.c	Tue Jun 17 13:38:34 1997
+++ linux-2.1.47/drivers/char/pc_keyb.c	Thu Jul 31 21:34:31 1997
@@ -15,6 +15,7 @@
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/kbd_ll.h>
+#include <linux/sysrq.h>
 
 #include <asm/keyboard.h>
 #include <asm/bitops.h>
@@ -543,6 +544,33 @@
 	if (!send_data(KBD_CMD_SET_LEDS) || !send_data(leds))
 	    send_data(KBD_CMD_ENABLE);	/* re-enable kbd if any errors */
 }
+
+#ifdef CONFIG_MAGIC_SYSRQ
+int pckbd_sysrq_keys[] = {
+	19, /* R */
+	30, /* A */
+	48, /* B */
+	35, /* H */
+	24, /* O */
+	31, /* S */
+	22, /* U */
+	25, /* P */
+	20, /* T */
+	50, /* M */
+	2,  /* 1 */
+	11, /* 0 */
+	18, /* E */
+	37, /* K */
+	38, /* L */
+	-1
+};
+	
+#define SYSRQ_KEY 0x54
+int pckbd_is_sysrq(unsigned char keycode)
+{
+	return( keycode == SYSRQ_KEY );
+}
+#endif /* CONFIG_MAGIC_SYSRQ */
 
 __initfunc(void pckbd_init_hw(void))
 {
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.47-orig/drivers/char/sysrq.c linux-2.1.47/drivers/char/sysrq.c
--- linux-2.1.47-orig/drivers/char/sysrq.c	Thu Jul 31 18:17:08 1997
+++ linux-2.1.47/drivers/char/sysrq.c	Thu Jul 31 21:37:54 1997
@@ -19,8 +19,10 @@
 #include <linux/reboot.h>
 #include <linux/sysrq.h>
 #include <linux/kbd_kern.h>
+#include <linux/sysrq.h>
 #include <asm/ptrace.h>
 #include <asm/smp_lock.h>
+#include <asm/keyboard.h>
 
 #ifdef CONFIG_APM
 #include <linux/apm_bios.h>
@@ -59,80 +61,93 @@
 		  struct kbd_struct *kbd, struct tty_struct *tty)
 {
 	int orig_log_level = console_loglevel;
+	int *p;
 
+	/* ++roman: translate machine-specific keycodes to abstract numbers */
+	if (!kbd_sysrq_keys)
+		return;
+	for( p = kbd_sysrq_keys; *p != -1; ++p )
+		if (key == *p) {
+			key = p - kbd_sysrq_keys;
+			break;
+		}
+	if (*p == -1)
+		key = SYSRQ_HELP;
+	
 	console_loglevel = 7;
 	printk(KERN_INFO "SysRq: ");
 	switch (key) {
-	case 19:					    /* R -- Reset raw mode */
+	case SYSRQ_RAWMODE:				    /* R -- Reset raw mode */
 		kbd->kbdmode = VC_XLATE;
 		printk("Keyboard mode set to XLATE\n");
 		break;
-	case 30:					    /* A -- SAK */
+	case SYSRQ_SAK:					    /* A -- SAK */
 		printk("SAK\n");
 		do_SAK(tty);
 		reset_vc(fg_console);
 		break;
-	case 48:					    /* B -- boot immediately */
+	case SYSRQ_BOOT:				    /* B -- boot immediately */
 		printk("Resetting\n");
 		machine_restart(NULL);
 		break;
 #ifdef __sparc__
-	case 35:					    /* H -- halt immediately */
+	case SYSRQ_HALT:				    /* H -- halt immediately */
 		printk("Halting\n");
 		halt_now();
 		break;
 #endif
 #ifdef CONFIG_APM
-	case 24:					    /* O -- power off */
+	case SYSRQ_PWROFF:				    /* O -- power off */
 		printk("Power off\n");
 		apm_set_power_state(APM_STATE_OFF);
 		break;
 #endif
-	case 31:					    /* S -- emergency sync */
+	case SYSRQ_SYNC:				    /* S -- emergency sync */
 		printk("Emergency Sync\n");
 		emergency_sync_scheduled = EMERG_SYNC;
 		wakeup_bdflush(0);
 		break;
-	case 22:					    /* U -- emergency remount R/O */
+	case SYSRQ_MNTRO:				    /* U -- emergency remount R/O */
 		printk("Emergency Remount R/O\n");
 		emergency_sync_scheduled = EMERG_REMOUNT;
 		wakeup_bdflush(0);
 		break;
-	case 25:					    /* P -- show PC */
+	case SYSRQ_REGS:				    /* P -- show PC */
 		printk("Show Regs\n");
 		if (pt_regs)
 			show_regs(pt_regs);
 		break;
-	case 20:					    /* T -- show task info */
+	case SYSRQ_STATE:				    /* T -- show task info */
 		printk("Show State\n");
 		show_state();
 		break;
-	case 50:					    /* M -- show memory info */
+	case SYSRQ_MEMORY:				    /* M -- show memory info */
 		printk("Show Memory\n");
 		show_mem();
 		break;
-	case 2 ... 11:					    /* 0-9 -- set console logging level */
+	case SYSRQ_NUM1 ... SYSRQ_NUM0:			    /* 0-9 -- set console logging level */
 		key--;
 		if (key == 10)
 			key = 0;
 		orig_log_level = key;
 		printk("Log level set to %d\n", key);
 		break;
-	case 18:					    /* E -- terminate all user processes */
+	case SYSRQ_TERM:				    /* E -- terminate all user processes */
 		printk("Terminate All Tasks\n");
 		send_sig_all(SIGTERM, 0);
 		orig_log_level = 8;			    /* We probably have killed syslogd */
 		break;
-	case 37:					    /* K -- kill all user processes */
+	case SYSRQ_KILL:				    /* K -- kill all user processes */
 		printk("Kill All Tasks\n");
 		send_sig_all(SIGKILL, 0);
 		orig_log_level = 8;
 		break;
-	case 38:					    /* L -- kill all processes including init */
+	case SYSRQ_KILLALL:				    /* L -- kill all processes including init */
 		printk("Kill ALL Tasks (even init)\n");
 		send_sig_all(SIGKILL, 1);
 		orig_log_level = 8;
 		break;
+	case SYSRQ_HELP:
 	default:					    /* Unknown: help */
 		printk("unRaw sAk Boot "
 #ifdef __sparc__
Binary files linux-2.1.47-orig/drivers/sound/configure and linux-2.1.47/drivers/sound/configure differ
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.47-orig/include/asm-alpha/keyboard.h linux-2.1.47/include/asm-alpha/keyboard.h
--- linux-2.1.47-orig/include/asm-alpha/keyboard.h	Tue Jun 17 13:40:17 1997
+++ linux-2.1.47/include/asm-alpha/keyboard.h	Thu Jul 31 21:34:44 1997
@@ -23,7 +23,10 @@
 			   char raw_mode);
 extern char pckbd_unexpected_up(unsigned char keycode);
 extern void pckbd_leds(unsigned char leds);
+extern int pckbd_is_sysrq(unsigned char keycode);
+extern char pckbd_translate_sysrq(unsigned char keycode);
 extern void pckbd_init_hw(void);
+extern int pckbd_sysrq_keys[];
 
 #define kbd_setkeycode		pckbd_setkeycode
 #define kbd_getkeycode		pckbd_getkeycode
@@ -31,6 +34,8 @@
 #define kbd_translate		pckbd_translate
 #define kbd_unexpected_up	pckbd_unexpected_up
 #define kbd_leds		pckbd_leds
+#define kbd_is_sysrq		pckbd_is_sysrq
+#define kbd_sysrq_keys		pckbd_sysrq_keys
 #define kbd_init_hw		pckbd_init_hw
 
 #define INIT_KBD
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.47-orig/include/asm-i386/keyboard.h linux-2.1.47/include/asm-i386/keyboard.h
--- linux-2.1.47-orig/include/asm-i386/keyboard.h	Tue Jun 17 13:40:19 1997
+++ linux-2.1.47/include/asm-i386/keyboard.h	Thu Jul 31 21:34:00 1997
@@ -23,7 +23,9 @@
 			   char raw_mode);
 extern char pckbd_unexpected_up(unsigned char keycode);
 extern void pckbd_leds(unsigned char leds);
+extern int pckbd_is_sysrq(unsigned char keycode);
 extern void pckbd_init_hw(void);
+extern int pckbd_sysrq_keys[];
 
 #define kbd_setkeycode		pckbd_setkeycode
 #define kbd_getkeycode		pckbd_getkeycode
@@ -31,6 +33,8 @@
 #define kbd_translate		pckbd_translate
 #define kbd_unexpected_up	pckbd_unexpected_up
 #define kbd_leds		pckbd_leds
+#define kbd_is_sysrq		pckbd_is_sysrq
+#define kbd_sysrq_keys		pckbd_sysrq_keys
 #define kbd_init_hw		pckbd_init_hw
 
 #endif /* __KERNEL__ */
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.47-orig/include/asm-m68k/keyboard.h linux-2.1.47/include/asm-m68k/keyboard.h
--- linux-2.1.47-orig/include/asm-m68k/keyboard.h	Thu May 22 18:03:59 1997
+++ linux-2.1.47/include/asm-m68k/keyboard.h	Thu Jul 31 21:35:56 1997
@@ -49,6 +49,14 @@
 	mach_kbd_leds(leds);
 }
 
+#ifdef CONFIG_MAGIC_SYSRQ
+static __inline__ int kbd_is_sysrq(unsigned char keycode)
+{
+    return( keycode == mach_sysrq_key );
+}
+#define kbd_sysrq_keys	mach_sysrq_keys
+#endif
+
 #define kbd_init_hw	mach_keyb_init
 
 #endif /* __KERNEL__ */
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.47-orig/include/asm-m68k/machdep.h linux-2.1.47/include/asm-m68k/machdep.h
--- linux-2.1.47-orig/include/asm-m68k/machdep.h	Wed Apr 16 16:59:22 1997
+++ linux-2.1.47/include/asm-m68k/machdep.h	Thu Jul 31 21:01:27 1997
@@ -39,4 +39,9 @@
 extern void (*mach_floppy_setup)(char *, int *);
 extern void (*mach_floppy_eject)(void);
 
+#ifdef CONFIG_MAGIC_SYSRQ
+extern int mach_sysrq_key;
+extern int *mach_sysrq_keys;
+#endif
+
 #endif /* _M68K_MACHDEP_H */
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.47-orig/include/asm-mips/keyboard.h linux-2.1.47/include/asm-mips/keyboard.h
--- linux-2.1.47-orig/include/asm-mips/keyboard.h	Thu Jul 17 17:47:11 1997
+++ linux-2.1.47/include/asm-mips/keyboard.h	Thu Jul 31 21:34:51 1997
@@ -25,7 +25,10 @@
 			   char raw_mode);
 extern char pckbd_unexpected_up(unsigned char keycode);
 extern void pckbd_leds(unsigned char leds);
+extern int pckbd_is_sysrq(unsigned char keycode);
+extern char pckbd_translate_sysrq(unsigned char keycode);
 extern void pckbd_init_hw(void);
+extern int pckbd_sysrq_keys[];
 
 #define kbd_setkeycode		pckbd_setkeycode
 #define kbd_getkeycode		pckbd_getkeycode
@@ -33,6 +36,8 @@
 #define kbd_translate		pckbd_translate
 #define kbd_unexpected_up	pckbd_unexpected_up
 #define kbd_leds		pckbd_leds
+#define kbd_is_sysrq		pckbd_is_sysrq
+#define kbd_sysrq_keys		pckbd_sysrq_keys
 #define kbd_init_hw		pckbd_init_hw
 
 /*
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.47-orig/include/asm-ppc/keyboard.h linux-2.1.47/include/asm-ppc/keyboard.h
--- linux-2.1.47-orig/include/asm-ppc/keyboard.h	Tue Jun 17 13:40:28 1997
+++ linux-2.1.47/include/asm-ppc/keyboard.h	Thu Jul 31 21:34:57 1997
@@ -23,7 +23,10 @@
 			   char raw_mode);
 extern char pckbd_unexpected_up(unsigned char keycode);
 extern void pckbd_leds(unsigned char leds);
+extern int pckbd_is_sysrq(unsigned char keycode);
+extern char pckbd_translate_sysrq(unsigned char keycode);
 extern void pckbd_init_hw(void);
+extern int pckbd_sysrq_keys[];
 
 #define kbd_setkeycode		pckbd_setkeycode
 #define kbd_getkeycode		pckbd_getkeycode
@@ -31,6 +34,8 @@
 #define kbd_translate		pckbd_translate
 #define kbd_unexpected_up	pckbd_unexpected_up
 #define kbd_leds		pckbd_leds
+#define kbd_is_sysrq		pckbd_is_sysrq
+#define kbd_sysrq_keys		pckbd_sysrq_keys
 #define kbd_init_hw		pckbd_init_hw
 
 #define INIT_KBD
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.47-orig/include/linux/sysrq.h linux-2.1.47/include/linux/sysrq.h
--- linux-2.1.47-orig/include/linux/sysrq.h	Thu Jul 31 18:27:18 1997
+++ linux-2.1.47/include/linux/sysrq.h	Thu Jul 31 20:54:49 1997
@@ -9,6 +9,8 @@
 
 #include <linux/config.h>
 
+#ifdef __KERNEL__
+
 extern int emergency_sync_scheduled;
 
 #define EMERG_SYNC 1
@@ -23,3 +25,22 @@
 #else
 #define CHECK_EMERGENCY_SYNC
 #endif
+
+#define SYSRQ_RAWMODE	0	/* R */
+#define SYSRQ_SAK	1	/* A */
+#define SYSRQ_BOOT	2	/* B */
+#define SYSRQ_HALT	3	/* H */
+#define SYSRQ_PWROFF	4	/* O */
+#define SYSRQ_SYNC	5	/* S */
+#define SYSRQ_MNTRO	6	/* U */
+#define SYSRQ_REGS	7	/* P */
+#define SYSRQ_STATE	8	/* T */
+#define SYSRQ_MEMORY	9	/* M */
+#define SYSRQ_NUM1	10	/* 1 */
+#define SYSRQ_NUM0	11	/* 0 */
+#define SYSRQ_TERM	12	/* E */
+#define SYSRQ_KILL	13	/* K */
+#define SYSRQ_KILLALL	14	/* L */
+#define SYSRQ_HELP	99	/* any other key */
+
+#endif /* __KERNEL__ */
