diff options
Diffstat (limited to 'drivers/char/keyboard.c')
-rw-r--r-- | drivers/char/keyboard.c | 101 |
1 files changed, 44 insertions, 57 deletions
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index cb8d691576da..c06e86ad1dab 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c | |||
@@ -41,7 +41,6 @@ | |||
41 | #include <linux/input.h> | 41 | #include <linux/input.h> |
42 | #include <linux/reboot.h> | 42 | #include <linux/reboot.h> |
43 | 43 | ||
44 | static void kbd_disconnect(struct input_handle *handle); | ||
45 | extern void ctrl_alt_del(void); | 44 | extern void ctrl_alt_del(void); |
46 | 45 | ||
47 | /* | 46 | /* |
@@ -159,65 +158,41 @@ static int sysrq_alt_use; | |||
159 | static int sysrq_alt; | 158 | static int sysrq_alt; |
160 | 159 | ||
161 | /* | 160 | /* |
162 | * Translation of scancodes to keycodes. We set them on only the first attached | 161 | * Translation of scancodes to keycodes. We set them on only the first |
163 | * keyboard - for per-keyboard setting, /dev/input/event is more useful. | 162 | * keyboard in the list that accepts the scancode and keycode. |
163 | * Explanation for not choosing the first attached keyboard anymore: | ||
164 | * USB keyboards for example have two event devices: one for all "normal" | ||
165 | * keys and one for extra function keys (like "volume up", "make coffee", | ||
166 | * etc.). So this means that scancodes for the extra function keys won't | ||
167 | * be valid for the first event device, but will be for the second. | ||
164 | */ | 168 | */ |
165 | int getkeycode(unsigned int scancode) | 169 | int getkeycode(unsigned int scancode) |
166 | { | 170 | { |
167 | struct list_head *node; | 171 | struct input_handle *handle; |
168 | struct input_dev *dev = NULL; | 172 | int keycode; |
173 | int error = -ENODEV; | ||
169 | 174 | ||
170 | list_for_each(node, &kbd_handler.h_list) { | 175 | list_for_each_entry(handle, &kbd_handler.h_list, h_node) { |
171 | struct input_handle *handle = to_handle_h(node); | 176 | error = handle->dev->getkeycode(handle->dev, scancode, &keycode); |
172 | if (handle->dev->keycodesize) { | 177 | if (!error) |
173 | dev = handle->dev; | 178 | return keycode; |
174 | break; | ||
175 | } | ||
176 | } | 179 | } |
177 | 180 | ||
178 | if (!dev) | 181 | return error; |
179 | return -ENODEV; | ||
180 | |||
181 | if (scancode >= dev->keycodemax) | ||
182 | return -EINVAL; | ||
183 | |||
184 | return INPUT_KEYCODE(dev, scancode); | ||
185 | } | 182 | } |
186 | 183 | ||
187 | int setkeycode(unsigned int scancode, unsigned int keycode) | 184 | int setkeycode(unsigned int scancode, unsigned int keycode) |
188 | { | 185 | { |
189 | struct list_head *node; | 186 | struct input_handle *handle; |
190 | struct input_dev *dev = NULL; | 187 | int error = -ENODEV; |
191 | unsigned int i, oldkey; | ||
192 | 188 | ||
193 | list_for_each(node, &kbd_handler.h_list) { | 189 | list_for_each_entry(handle, &kbd_handler.h_list, h_node) { |
194 | struct input_handle *handle = to_handle_h(node); | 190 | error = handle->dev->setkeycode(handle->dev, scancode, keycode); |
195 | if (handle->dev->keycodesize) { | 191 | if (!error) |
196 | dev = handle->dev; | ||
197 | break; | 192 | break; |
198 | } | ||
199 | } | 193 | } |
200 | 194 | ||
201 | if (!dev) | 195 | return error; |
202 | return -ENODEV; | ||
203 | |||
204 | if (scancode >= dev->keycodemax) | ||
205 | return -EINVAL; | ||
206 | if (keycode < 0 || keycode > KEY_MAX) | ||
207 | return -EINVAL; | ||
208 | if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8))) | ||
209 | return -EINVAL; | ||
210 | |||
211 | oldkey = SET_INPUT_KEYCODE(dev, scancode, keycode); | ||
212 | |||
213 | clear_bit(oldkey, dev->keybit); | ||
214 | set_bit(keycode, dev->keybit); | ||
215 | |||
216 | for (i = 0; i < dev->keycodemax; i++) | ||
217 | if (INPUT_KEYCODE(dev,i) == oldkey) | ||
218 | set_bit(oldkey, dev->keybit); | ||
219 | |||
220 | return 0; | ||
221 | } | 196 | } |
222 | 197 | ||
223 | /* | 198 | /* |
@@ -225,10 +200,9 @@ int setkeycode(unsigned int scancode, unsigned int keycode) | |||
225 | */ | 200 | */ |
226 | static void kd_nosound(unsigned long ignored) | 201 | static void kd_nosound(unsigned long ignored) |
227 | { | 202 | { |
228 | struct list_head *node; | 203 | struct input_handle *handle; |
229 | 204 | ||
230 | list_for_each(node, &kbd_handler.h_list) { | 205 | list_for_each_entry(handle, &kbd_handler.h_list, h_node) { |
231 | struct input_handle *handle = to_handle_h(node); | ||
232 | if (test_bit(EV_SND, handle->dev->evbit)) { | 206 | if (test_bit(EV_SND, handle->dev->evbit)) { |
233 | if (test_bit(SND_TONE, handle->dev->sndbit)) | 207 | if (test_bit(SND_TONE, handle->dev->sndbit)) |
234 | input_inject_event(handle, EV_SND, SND_TONE, 0); | 208 | input_inject_event(handle, EV_SND, SND_TONE, 0); |
@@ -1161,7 +1135,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) | |||
1161 | 1135 | ||
1162 | if ((raw_mode = (kbd->kbdmode == VC_RAW)) && !hw_raw) | 1136 | if ((raw_mode = (kbd->kbdmode == VC_RAW)) && !hw_raw) |
1163 | if (emulate_raw(vc, keycode, !down << 7)) | 1137 | if (emulate_raw(vc, keycode, !down << 7)) |
1164 | if (keycode < BTN_MISC) | 1138 | if (keycode < BTN_MISC && printk_ratelimit()) |
1165 | printk(KERN_WARNING "keyboard.c: can't emulate rawmode for keycode %d\n", keycode); | 1139 | printk(KERN_WARNING "keyboard.c: can't emulate rawmode for keycode %d\n", keycode); |
1166 | 1140 | ||
1167 | #ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq Hack */ | 1141 | #ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq Hack */ |
@@ -1285,11 +1259,11 @@ static void kbd_event(struct input_handle *handle, unsigned int event_type, | |||
1285 | * likes it, it can open it and get events from it. In this (kbd_connect) | 1259 | * likes it, it can open it and get events from it. In this (kbd_connect) |
1286 | * function, we should decide which VT to bind that keyboard to initially. | 1260 | * function, we should decide which VT to bind that keyboard to initially. |
1287 | */ | 1261 | */ |
1288 | static struct input_handle *kbd_connect(struct input_handler *handler, | 1262 | static int kbd_connect(struct input_handler *handler, struct input_dev *dev, |
1289 | struct input_dev *dev, | 1263 | const struct input_device_id *id) |
1290 | const struct input_device_id *id) | ||
1291 | { | 1264 | { |
1292 | struct input_handle *handle; | 1265 | struct input_handle *handle; |
1266 | int error; | ||
1293 | int i; | 1267 | int i; |
1294 | 1268 | ||
1295 | for (i = KEY_RESERVED; i < BTN_MISC; i++) | 1269 | for (i = KEY_RESERVED; i < BTN_MISC; i++) |
@@ -1297,24 +1271,37 @@ static struct input_handle *kbd_connect(struct input_handler *handler, | |||
1297 | break; | 1271 | break; |
1298 | 1272 | ||
1299 | if (i == BTN_MISC && !test_bit(EV_SND, dev->evbit)) | 1273 | if (i == BTN_MISC && !test_bit(EV_SND, dev->evbit)) |
1300 | return NULL; | 1274 | return -ENODEV; |
1301 | 1275 | ||
1302 | handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); | 1276 | handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); |
1303 | if (!handle) | 1277 | if (!handle) |
1304 | return NULL; | 1278 | return -ENOMEM; |
1305 | 1279 | ||
1306 | handle->dev = dev; | 1280 | handle->dev = dev; |
1307 | handle->handler = handler; | 1281 | handle->handler = handler; |
1308 | handle->name = "kbd"; | 1282 | handle->name = "kbd"; |
1309 | 1283 | ||
1310 | input_open_device(handle); | 1284 | error = input_register_handle(handle); |
1285 | if (error) | ||
1286 | goto err_free_handle; | ||
1287 | |||
1288 | error = input_open_device(handle); | ||
1289 | if (error) | ||
1290 | goto err_unregister_handle; | ||
1291 | |||
1292 | return 0; | ||
1311 | 1293 | ||
1312 | return handle; | 1294 | err_unregister_handle: |
1295 | input_unregister_handle(handle); | ||
1296 | err_free_handle: | ||
1297 | kfree(handle); | ||
1298 | return error; | ||
1313 | } | 1299 | } |
1314 | 1300 | ||
1315 | static void kbd_disconnect(struct input_handle *handle) | 1301 | static void kbd_disconnect(struct input_handle *handle) |
1316 | { | 1302 | { |
1317 | input_close_device(handle); | 1303 | input_close_device(handle); |
1304 | input_unregister_handle(handle); | ||
1318 | kfree(handle); | 1305 | kfree(handle); |
1319 | } | 1306 | } |
1320 | 1307 | ||