| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  *  drivers/s390/char/ctrlchar.c | 
 | 3 |  *  Unified handling of special chars. | 
 | 4 |  * | 
 | 5 |  *    Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation | 
 | 6 |  *    Author(s): Fritz Elfert <felfert@millenux.com> <elfert@de.ibm.com> | 
 | 7 |  * | 
 | 8 |  */ | 
 | 9 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 10 | #include <linux/stddef.h> | 
 | 11 | #include <asm/errno.h> | 
 | 12 | #include <linux/sysrq.h> | 
 | 13 | #include <linux/ctype.h> | 
 | 14 |  | 
 | 15 | #include "ctrlchar.h" | 
 | 16 |  | 
 | 17 | #ifdef CONFIG_MAGIC_SYSRQ | 
 | 18 | static int ctrlchar_sysrq_key; | 
| Andrew Morton | e45ccc0 | 2006-12-08 15:53:52 +0100 | [diff] [blame] | 19 | static struct tty_struct *sysrq_tty; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 20 |  | 
 | 21 | static void | 
| Andrew Morton | e45ccc0 | 2006-12-08 15:53:52 +0100 | [diff] [blame] | 22 | ctrlchar_handle_sysrq(struct work_struct *work) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 23 | { | 
| Andrew Morton | e45ccc0 | 2006-12-08 15:53:52 +0100 | [diff] [blame] | 24 | 	handle_sysrq(ctrlchar_sysrq_key, sysrq_tty); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 25 | } | 
 | 26 |  | 
| Andrew Morton | e45ccc0 | 2006-12-08 15:53:52 +0100 | [diff] [blame] | 27 | static DECLARE_WORK(ctrlchar_work, ctrlchar_handle_sysrq); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 28 | #endif | 
 | 29 |  | 
 | 30 |  | 
 | 31 | /** | 
 | 32 |  * Check for special chars at start of input. | 
 | 33 |  * | 
 | 34 |  * @param buf Console input buffer. | 
 | 35 |  * @param len Length of valid data in buffer. | 
 | 36 |  * @param tty The tty struct for this console. | 
 | 37 |  * @return CTRLCHAR_NONE, if nothing matched, | 
 | 38 |  *         CTRLCHAR_SYSRQ, if sysrq was encountered | 
 | 39 |  *         otherwise char to be inserted logically or'ed | 
 | 40 |  *         with CTRLCHAR_CTRL | 
 | 41 |  */ | 
 | 42 | unsigned int | 
 | 43 | ctrlchar_handle(const unsigned char *buf, int len, struct tty_struct *tty) | 
 | 44 | { | 
 | 45 | 	if ((len < 2) || (len > 3)) | 
 | 46 | 		return CTRLCHAR_NONE; | 
 | 47 |  | 
 | 48 | 	/* hat is 0xb1 in codepage 037 (US etc.) and thus */ | 
 | 49 | 	/* converted to 0x5e in ascii ('^') */ | 
 | 50 | 	if ((buf[0] != '^') && (buf[0] != '\252')) | 
 | 51 | 		return CTRLCHAR_NONE; | 
 | 52 |  | 
 | 53 | #ifdef CONFIG_MAGIC_SYSRQ | 
 | 54 | 	/* racy */ | 
 | 55 | 	if (len == 3 && buf[1] == '-') { | 
 | 56 | 		ctrlchar_sysrq_key = buf[2]; | 
| Andrew Morton | e45ccc0 | 2006-12-08 15:53:52 +0100 | [diff] [blame] | 57 | 		sysrq_tty = tty; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 58 | 		schedule_work(&ctrlchar_work); | 
 | 59 | 		return CTRLCHAR_SYSRQ; | 
 | 60 | 	} | 
 | 61 | #endif | 
 | 62 |  | 
 | 63 | 	if (len != 2) | 
 | 64 | 		return CTRLCHAR_NONE; | 
 | 65 |  | 
 | 66 | 	switch (tolower(buf[1])) { | 
 | 67 | 	case 'c': | 
 | 68 | 		return INTR_CHAR(tty) | CTRLCHAR_CTRL; | 
 | 69 | 	case 'd': | 
 | 70 | 		return EOF_CHAR(tty)  | CTRLCHAR_CTRL; | 
 | 71 | 	case 'z': | 
 | 72 | 		return SUSP_CHAR(tty) | CTRLCHAR_CTRL; | 
 | 73 | 	} | 
 | 74 | 	return CTRLCHAR_NONE; | 
 | 75 | } |