diff options
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/keyboard.c | 71 |
1 files changed, 23 insertions, 48 deletions
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index cb8d691576da..3d211e8553f7 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c | |||
@@ -159,65 +159,41 @@ static int sysrq_alt_use; | |||
159 | static int sysrq_alt; | 159 | static int sysrq_alt; |
160 | 160 | ||
161 | /* | 161 | /* |
162 | * Translation of scancodes to keycodes. We set them on only the first attached | 162 | * Translation of scancodes to keycodes. We set them on only the first |
163 | * keyboard - for per-keyboard setting, /dev/input/event is more useful. | 163 | * keyboard in the list that accepts the scancode and keycode. |
164 | * Explanation for not choosing the first attached keyboard anymore: | ||
165 | * USB keyboards for example have two event devices: one for all "normal" | ||
166 | * keys and one for extra function keys (like "volume up", "make coffee", | ||
167 | * etc.). So this means that scancodes for the extra function keys won't | ||
168 | * be valid for the first event device, but will be for the second. | ||
164 | */ | 169 | */ |
165 | int getkeycode(unsigned int scancode) | 170 | int getkeycode(unsigned int scancode) |
166 | { | 171 | { |
167 | struct list_head *node; | 172 | struct input_handle *handle; |
168 | struct input_dev *dev = NULL; | 173 | int keycode; |
174 | int error = -ENODEV; | ||
169 | 175 | ||
170 | list_for_each(node, &kbd_handler.h_list) { | 176 | list_for_each_entry(handle, &kbd_handler.h_list, h_node) { |
171 | struct input_handle *handle = to_handle_h(node); | 177 | error = handle->dev->getkeycode(handle->dev, scancode, &keycode); |
172 | if (handle->dev->keycodesize) { | 178 | if (!error) |
173 | dev = handle->dev; | 179 | return keycode; |
174 | break; | ||
175 | } | ||
176 | } | 180 | } |
177 | 181 | ||
178 | if (!dev) | 182 | return error; |
179 | return -ENODEV; | ||
180 | |||
181 | if (scancode >= dev->keycodemax) | ||
182 | return -EINVAL; | ||
183 | |||
184 | return INPUT_KEYCODE(dev, scancode); | ||
185 | } | 183 | } |
186 | 184 | ||
187 | int setkeycode(unsigned int scancode, unsigned int keycode) | 185 | int setkeycode(unsigned int scancode, unsigned int keycode) |
188 | { | 186 | { |
189 | struct list_head *node; | 187 | struct input_handle *handle; |
190 | struct input_dev *dev = NULL; | 188 | int error = -ENODEV; |
191 | unsigned int i, oldkey; | ||
192 | 189 | ||
193 | list_for_each(node, &kbd_handler.h_list) { | 190 | list_for_each_entry(handle, &kbd_handler.h_list, h_node) { |
194 | struct input_handle *handle = to_handle_h(node); | 191 | error = handle->dev->setkeycode(handle->dev, scancode, keycode); |
195 | if (handle->dev->keycodesize) { | 192 | if (!error) |
196 | dev = handle->dev; | ||
197 | break; | 193 | break; |
198 | } | ||
199 | } | 194 | } |
200 | 195 | ||
201 | if (!dev) | 196 | 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 | } | 197 | } |
222 | 198 | ||
223 | /* | 199 | /* |
@@ -225,10 +201,9 @@ int setkeycode(unsigned int scancode, unsigned int keycode) | |||
225 | */ | 201 | */ |
226 | static void kd_nosound(unsigned long ignored) | 202 | static void kd_nosound(unsigned long ignored) |
227 | { | 203 | { |
228 | struct list_head *node; | 204 | struct input_handle *handle; |
229 | 205 | ||
230 | list_for_each(node, &kbd_handler.h_list) { | 206 | 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)) { | 207 | if (test_bit(EV_SND, handle->dev->evbit)) { |
233 | if (test_bit(SND_TONE, handle->dev->sndbit)) | 208 | if (test_bit(SND_TONE, handle->dev->sndbit)) |
234 | input_inject_event(handle, EV_SND, SND_TONE, 0); | 209 | input_inject_event(handle, EV_SND, SND_TONE, 0); |