summaryrefslogtreecommitdiffstats
path: root/vt-Drop-K_OFF-for-VC_MUTE.patch
blob: e9bc4fffa95bc82061115d09551fedf47afffc91 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
Path: news.gmane.org!not-for-mail
From: Adam Jackson <ajax@redhat.com>
Newsgroups: gmane.linux.kernel
Subject: [PATCH] vt: Drop K_OFF for VC_MUTE
Date: Fri, 16 Nov 2012 13:32:34 -0500
Lines: 205
Approved: news@gmane.org
Message-ID: <1353090754-30233-1-git-send-email-ajax@redhat.com>
NNTP-Posting-Host: plane.gmane.org
X-Trace: ger.gmane.org 1353090772 20663 80.91.229.3 (16 Nov 2012 18:32:52 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Fri, 16 Nov 2012 18:32:52 +0000 (UTC)
Cc: Arthur Taylor <art@ified.ca>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Original-X-From: linux-kernel-owner@vger.kernel.org Fri Nov 16 19:33:03 2012
Return-path: <linux-kernel-owner@vger.kernel.org>
Envelope-to: glk-linux-kernel-3@plane.gmane.org
Original-Received: from vger.kernel.org ([209.132.180.67])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <linux-kernel-owner@vger.kernel.org>)
	id 1TZQim-0000aG-BI
	for glk-linux-kernel-3@plane.gmane.org; Fri, 16 Nov 2012 19:32:56 +0100
Original-Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
	id S1753232Ab2KPSck (ORCPT <rfc822;glk-linux-kernel-3@m.gmane.org>);
	Fri, 16 Nov 2012 13:32:40 -0500
Original-Received: from mx1.redhat.com ([209.132.183.28]:32172 "EHLO mx1.redhat.com"
	rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP
	id S1752810Ab2KPSci (ORCPT <rfc822;linux-kernel@vger.kernel.org>);
	Fri, 16 Nov 2012 13:32:38 -0500
Original-Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11])
	by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id qAGIWaM7020116
	(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK);
	Fri, 16 Nov 2012 13:32:36 -0500
Original-Received: from ihatethathostname.lab.bos.redhat.com (ihatethathostname.lab.bos.redhat.com [10.16.43.238])
	by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id qAGIWZD7010099;
	Fri, 16 Nov 2012 13:32:35 -0500
X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11
Original-Sender: linux-kernel-owner@vger.kernel.org
Precedence: bulk
List-ID: <linux-kernel.vger.kernel.org>
X-Mailing-List: linux-kernel@vger.kernel.org
Xref: news.gmane.org gmane.linux.kernel:1395620
Archived-At: <http://permalink.gmane.org/gmane.linux.kernel/1395620>

The "don't enqueue stuff" semantics of K_OFF shouldn't be a function of
the keyboard map state; we should be able to switch among cooked/raw/
unicode without changing whether events are delivered.  Otherwise - if
changing to K_UNICODE undoes K_OFF - then suddenly Alt-F2 under
Gnome will switch VT instead of summoning the "run command" dialog.

Drop the K_OFF handling and replace it with a new "mute" ioctl pair.
Anybody using K_OFF would already need to be prepared to handle it
throwing -EINVAL for old kernel compatibility, so userspace will degrade
gracefully.

Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=859485
Cc: Arthur Taylor <art@ified.ca>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Tested-by: Josh Boyer <jwboyer@redhat.com>
Signed-off-by: Adam Jackson <ajax@redhat.com>
---
 drivers/tty/vt/keyboard.c | 40 +++++++++++++++++++++++++++++++++-------
 drivers/tty/vt/vt_ioctl.c | 13 +++++++++++++
 include/linux/kbd_kern.h  |  6 +++---
 include/linux/vt_kern.h   |  2 ++
 include/uapi/linux/kd.h   |  5 +++++
 5 files changed, 56 insertions(+), 10 deletions(-)

diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index 681765b..08d1d57 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -657,7 +657,7 @@ static void k_spec(struct vc_data *vc, unsigned char value, char up_flag)
 		return;
 	if ((kbd->kbdmode == VC_RAW ||
 	     kbd->kbdmode == VC_MEDIUMRAW ||
-	     kbd->kbdmode == VC_OFF) &&
+	     vc_kbd_mode(kbd, VC_MUTE)) &&
 	     value != KVAL(K_SAK))
 		return;		/* SAK is allowed even in raw mode */
 	fn_handler[value](vc);
@@ -1381,7 +1381,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
 	if (rc == NOTIFY_STOP)
 		return;
 
-	if ((raw_mode || kbd->kbdmode == VC_OFF) && type != KT_SPEC && type != KT_SHIFT)
+	if ((raw_mode || vc_kbd_mode(kbd, VC_MUTE)) && type != KT_SPEC && type != KT_SHIFT)
 		return;
 
 	(*k_handler[type])(vc, keysym & 0xff, !down);
@@ -1731,9 +1731,6 @@ int vt_do_kdskbmode(int console, unsigned int arg)
 		kbd->kbdmode = VC_UNICODE;
 		do_compute_shiftstate();
 		break;
-	case K_OFF:
-		kbd->kbdmode = VC_OFF;
-		break;
 	default:
 		ret = -EINVAL;
 	}
@@ -1742,6 +1739,30 @@ int vt_do_kdskbmode(int console, unsigned int arg)
 }
 
 /**
+ *	vt_do_kdskbmute		-	set keyboard event mute
+ *	@console: the console to use
+ *	@arg: the requested mode
+ *
+ *	Update the keyboard mute state while holding the correct locks.
+ *	Return 0 for success or an error code.
+ */
+int vt_do_kdskbmute(int console, unsigned int arg)
+{
+	struct kbd_struct * kbd = kbd_table + console;
+	int ret = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&kbd_event_lock, flags);
+	if (arg)
+		set_vc_kbd_mode(kbd, VC_MUTE);
+	else
+		clr_vc_kbd_mode(kbd, VC_MUTE);
+	spin_unlock_irqrestore(&kbd_event_lock, flags);
+	return ret;
+}
+
+
+/**
  *	vt_do_kdskbmeta		-	set keyboard meta state
  *	@console: the console to use
  *	@arg: the requested meta state
@@ -2068,13 +2089,18 @@ int vt_do_kdgkbmode(int console)
 		return K_MEDIUMRAW;
 	case VC_UNICODE:
 		return K_UNICODE;
-	case VC_OFF:
-		return K_OFF;
 	default:
 		return K_XLATE;
 	}
 }
 
+int vt_do_kdgkbmute(int console)
+{
+	struct kbd_struct * kbd = kbd_table + console;
+	/* This is a spot read so needs no locking */
+	return vc_kbd_mode(kbd, VC_MUTE);
+}
+
 /**
  *	vt_do_kdgkbmeta		-	report meta status
  *	@console: console to report
diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c
index b841f56..f0951e2 100644
--- a/drivers/tty/vt/vt_ioctl.c
+++ b/drivers/tty/vt/vt_ioctl.c
@@ -477,6 +477,19 @@ int vt_ioctl(struct tty_struct *tty,
 		ret = put_user(uival, (int __user *)arg);
 		break;
 
+	case KDSKBMUTE:
+		if (!perm)
+			return -EPERM;
+		ret = vt_do_kdskbmute(console, arg);
+		if (ret == 0)
+			tty_ldisc_flush(tty);
+		break;
+
+	case KDGKBMUTE:
+		uival = vt_do_kdgkbmute(console);
+		ret = put_user(uival, (int __user *)arg);
+		break;
+
 	/* this could be folded into KDSKBMODE, but for compatibility
 	   reasons it is not so easy to fold KDGKBMETA into KDGKBMODE */
 	case KDSKBMETA:
diff --git a/include/linux/kbd_kern.h b/include/linux/kbd_kern.h
index b7c8cdc..9386143 100644
--- a/include/linux/kbd_kern.h
+++ b/include/linux/kbd_kern.h
@@ -48,19 +48,19 @@ struct kbd_struct {
 #define VC_CAPSLOCK	2	/* capslock mode */
 #define VC_KANALOCK	3	/* kanalock mode */
 
-	unsigned char kbdmode:3;	/* one 3-bit value */
+	unsigned char kbdmode:2;	/* one 2-bit value */
 #define VC_XLATE	0	/* translate keycodes using keymap */
 #define VC_MEDIUMRAW	1	/* medium raw (keycode) mode */
 #define VC_RAW		2	/* raw (scancode) mode */
 #define VC_UNICODE	3	/* Unicode mode */
-#define VC_OFF		4	/* disabled mode */
 
-	unsigned char modeflags:5;
+	unsigned char modeflags:6;
 #define VC_APPLIC	0	/* application key mode */
 #define VC_CKMODE	1	/* cursor key mode */
 #define VC_REPEAT	2	/* keyboard repeat */
 #define VC_CRLF		3	/* 0 - enter sends CR, 1 - enter sends CRLF */
 #define VC_META		4	/* 0 - meta, 1 - meta=prefix with ESC */
+#define VC_MUTE		5	/* don't generate events */
 };
 
 extern int kbd_init(void);
diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h
index 50ae7d0..a886915 100644
--- a/include/linux/vt_kern.h
+++ b/include/linux/vt_kern.h
@@ -168,6 +168,7 @@ extern void hide_boot_cursor(bool hide);
 
 /* keyboard  provided interfaces */
 extern int vt_do_diacrit(unsigned int cmd, void __user *up, int eperm);
+extern int vt_do_kdskbmute(int console, unsigned int arg);
 extern int vt_do_kdskbmode(int console, unsigned int arg);
 extern int vt_do_kdskbmeta(int console, unsigned int arg);
 extern int vt_do_kbkeycode_ioctl(int cmd, struct kbkeycode __user *user_kbkc,
@@ -177,6 +178,7 @@ extern int vt_do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe,
 extern int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb,
                                         int perm);
 extern int vt_do_kdskled(int console, int cmd, unsigned long arg, int perm);
+extern int vt_do_kdgkbmute(int console);
 extern int vt_do_kdgkbmode(int console);
 extern int vt_do_kdgkbmeta(int console);
 extern void vt_reset_unicode(int console);
diff --git a/include/uapi/linux/kd.h b/include/uapi/linux/kd.h
index 87b7cc4..c3de63c 100644
--- a/include/uapi/linux/kd.h
+++ b/include/uapi/linux/kd.h
@@ -81,6 +81,7 @@ struct unimapinit {
 #define		K_XLATE		0x01
 #define		K_MEDIUMRAW	0x02
 #define		K_UNICODE	0x03
+/* K_OFF is no longer implemented, but preserved for source compatibility */
 #define		K_OFF		0x04
 #define KDGKBMODE	0x4B44	/* gets current keyboard mode */
 #define KDSKBMODE	0x4B45	/* sets current keyboard mode */
@@ -150,6 +151,10 @@ struct kbd_repeat {
 			/* earlier this field was misnamed "rate" */
 };
 
+/* get/set event mute */
+#define KDGKBMUTE	0x4B50
+#define KDSKBMUTE	0x4B51
+
 #define KDKBDREP        0x4B52  /* set keyboard delay/repeat rate;
 				 * actually used values are returned */
 
-- 
1.7.11.7