diff options
| -rw-r--r-- | Documentation/braille-console.txt | 34 | ||||
| -rw-r--r-- | Documentation/kernel-parameters.txt | 5 | ||||
| -rw-r--r-- | arch/powerpc/kernel/ppc_ksyms.c | 3 | ||||
| -rw-r--r-- | arch/ppc/kernel/ppc_ksyms.c | 3 | ||||
| -rw-r--r-- | drivers/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/Makefile | 1 | ||||
| -rw-r--r-- | drivers/accessibility/Kconfig | 23 | ||||
| -rw-r--r-- | drivers/accessibility/Makefile | 1 | ||||
| -rw-r--r-- | drivers/accessibility/braille/Makefile | 1 | ||||
| -rw-r--r-- | drivers/accessibility/braille/braille_console.c | 397 | ||||
| -rw-r--r-- | drivers/char/consolemap.c | 1 | ||||
| -rw-r--r-- | drivers/char/keyboard.c | 2 | ||||
| -rw-r--r-- | drivers/char/vt.c | 1 | ||||
| -rw-r--r-- | include/linux/console.h | 4 | ||||
| -rw-r--r-- | kernel/printk.c | 90 |
15 files changed, 538 insertions, 30 deletions
diff --git a/Documentation/braille-console.txt b/Documentation/braille-console.txt new file mode 100644 index 000000000000..000b0fbdc105 --- /dev/null +++ b/Documentation/braille-console.txt | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | Linux Braille Console | ||
| 2 | |||
| 3 | To get early boot messages on a braille device (before userspace screen | ||
| 4 | readers can start), you first need to compile the support for the usual serial | ||
| 5 | console (see serial-console.txt), and for braille device (in Device Drivers - | ||
| 6 | Accessibility). | ||
| 7 | |||
| 8 | Then you need to specify a console=brl, option on the kernel command line, the | ||
| 9 | format is: | ||
| 10 | |||
| 11 | console=brl,serial_options... | ||
| 12 | |||
| 13 | where serial_options... are the same as described in serial-console.txt | ||
| 14 | |||
| 15 | So for instance you can use console=brl,ttyS0 if the braille device is connected | ||
| 16 | to the first serial port, and console=brl,ttyS0,115200 to override the baud rate | ||
| 17 | to 115200, etc. | ||
| 18 | |||
| 19 | By default, the braille device will just show the last kernel message (console | ||
| 20 | mode). To review previous messages, press the Insert key to switch to the VT | ||
| 21 | review mode. In review mode, the arrow keys permit to browse in the VT content, | ||
| 22 | page up/down keys go at the top/bottom of the screen, and the home key goes back | ||
| 23 | to the cursor, hence providing very basic screen reviewing facility. | ||
| 24 | |||
| 25 | Sound feedback can be obtained by adding the braille_console.sound=1 kernel | ||
| 26 | parameter. | ||
| 27 | |||
| 28 | For simplicity, only one braille console can be enabled, other uses of | ||
| 29 | console=brl,... will be discarded. Also note that it does not interfere with | ||
| 30 | the console selection mecanism described in serial-console.txt | ||
| 31 | |||
| 32 | For now, only the VisioBraille device is supported. | ||
| 33 | |||
| 34 | Samuel Thibault <samuel.thibault@ens-lyon.org> | ||
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 3ce193f86565..0ba0861b5d18 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
| @@ -496,6 +496,11 @@ and is between 256 and 4096 characters. It is defined in the file | |||
| 496 | switching to the matching ttyS device later. The | 496 | switching to the matching ttyS device later. The |
| 497 | options are the same as for ttyS, above. | 497 | options are the same as for ttyS, above. |
| 498 | 498 | ||
| 499 | If the device connected to the port is not a TTY but a braille | ||
| 500 | device, prepend "brl," before the device type, for instance | ||
| 501 | console=brl,ttyS0 | ||
| 502 | For now, only VisioBraille is supported. | ||
| 503 | |||
| 499 | earlycon= [KNL] Output early console device and options. | 504 | earlycon= [KNL] Output early console device and options. |
| 500 | uart[8250],io,<addr>[,options] | 505 | uart[8250],io,<addr>[,options] |
| 501 | uart[8250],mmio,<addr>[,options] | 506 | uart[8250],mmio,<addr>[,options] |
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 09fcb50c45ae..cf6b5a7d8b3f 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c | |||
| @@ -133,9 +133,6 @@ EXPORT_SYMBOL(adb_try_handler_change); | |||
| 133 | EXPORT_SYMBOL(cuda_request); | 133 | EXPORT_SYMBOL(cuda_request); |
| 134 | EXPORT_SYMBOL(cuda_poll); | 134 | EXPORT_SYMBOL(cuda_poll); |
| 135 | #endif /* CONFIG_ADB_CUDA */ | 135 | #endif /* CONFIG_ADB_CUDA */ |
| 136 | #ifdef CONFIG_VT | ||
| 137 | EXPORT_SYMBOL(kd_mksound); | ||
| 138 | #endif | ||
| 139 | EXPORT_SYMBOL(to_tm); | 136 | EXPORT_SYMBOL(to_tm); |
| 140 | 137 | ||
| 141 | #ifdef CONFIG_PPC32 | 138 | #ifdef CONFIG_PPC32 |
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c index d9036ef0b658..16ac11ca7ba0 100644 --- a/arch/ppc/kernel/ppc_ksyms.c +++ b/arch/ppc/kernel/ppc_ksyms.c | |||
| @@ -183,9 +183,6 @@ EXPORT_SYMBOL(cuda_poll); | |||
| 183 | #if defined(CONFIG_BOOTX_TEXT) | 183 | #if defined(CONFIG_BOOTX_TEXT) |
| 184 | EXPORT_SYMBOL(btext_update_display); | 184 | EXPORT_SYMBOL(btext_update_display); |
| 185 | #endif | 185 | #endif |
| 186 | #ifdef CONFIG_VT | ||
| 187 | EXPORT_SYMBOL(kd_mksound); | ||
| 188 | #endif | ||
| 189 | EXPORT_SYMBOL(to_tm); | 186 | EXPORT_SYMBOL(to_tm); |
| 190 | 187 | ||
| 191 | EXPORT_SYMBOL(pm_power_off); | 188 | EXPORT_SYMBOL(pm_power_off); |
diff --git a/drivers/Kconfig b/drivers/Kconfig index 80f0ec91e2cf..59f33fa6af3e 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig | |||
| @@ -84,6 +84,8 @@ source "drivers/memstick/Kconfig" | |||
| 84 | 84 | ||
| 85 | source "drivers/leds/Kconfig" | 85 | source "drivers/leds/Kconfig" |
| 86 | 86 | ||
| 87 | source "drivers/accessibility/Kconfig" | ||
| 88 | |||
| 87 | source "drivers/infiniband/Kconfig" | 89 | source "drivers/infiniband/Kconfig" |
| 88 | 90 | ||
| 89 | source "drivers/edac/Kconfig" | 91 | source "drivers/edac/Kconfig" |
diff --git a/drivers/Makefile b/drivers/Makefile index e5e394a7e6c0..f65deda72d61 100644 --- a/drivers/Makefile +++ b/drivers/Makefile | |||
| @@ -70,6 +70,7 @@ obj-$(CONFIG_WATCHDOG) += watchdog/ | |||
| 70 | obj-$(CONFIG_PHONE) += telephony/ | 70 | obj-$(CONFIG_PHONE) += telephony/ |
| 71 | obj-$(CONFIG_MD) += md/ | 71 | obj-$(CONFIG_MD) += md/ |
| 72 | obj-$(CONFIG_BT) += bluetooth/ | 72 | obj-$(CONFIG_BT) += bluetooth/ |
| 73 | obj-$(CONFIG_ACCESSIBILITY) += accessibility/ | ||
| 73 | obj-$(CONFIG_ISDN) += isdn/ | 74 | obj-$(CONFIG_ISDN) += isdn/ |
| 74 | obj-$(CONFIG_EDAC) += edac/ | 75 | obj-$(CONFIG_EDAC) += edac/ |
| 75 | obj-$(CONFIG_MCA) += mca/ | 76 | obj-$(CONFIG_MCA) += mca/ |
diff --git a/drivers/accessibility/Kconfig b/drivers/accessibility/Kconfig new file mode 100644 index 000000000000..1264c4b98094 --- /dev/null +++ b/drivers/accessibility/Kconfig | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | menuconfig ACCESSIBILITY | ||
| 2 | bool "Accessibility support" | ||
| 3 | ---help--- | ||
| 4 | Enable a submenu where accessibility items may be enabled. | ||
| 5 | |||
| 6 | If unsure, say N. | ||
| 7 | |||
| 8 | if ACCESSIBILITY | ||
| 9 | config A11Y_BRAILLE_CONSOLE | ||
| 10 | bool "Console on braille device" | ||
| 11 | depends on VT | ||
| 12 | depends on SERIAL_CORE_CONSOLE | ||
| 13 | ---help--- | ||
| 14 | Enables console output on a braille device connected to a 8250 | ||
| 15 | serial port. For now only the VisioBraille device is supported. | ||
| 16 | |||
| 17 | To actually enable it, you need to pass option | ||
| 18 | console=brl,ttyS0 | ||
| 19 | to the kernel. Options are the same as for serial console. | ||
| 20 | |||
| 21 | If unsure, say N. | ||
| 22 | |||
| 23 | endif # ACCESSIBILITY | ||
diff --git a/drivers/accessibility/Makefile b/drivers/accessibility/Makefile new file mode 100644 index 000000000000..72b01a46546f --- /dev/null +++ b/drivers/accessibility/Makefile | |||
| @@ -0,0 +1 @@ | |||
| obj-y += braille/ | |||
diff --git a/drivers/accessibility/braille/Makefile b/drivers/accessibility/braille/Makefile new file mode 100644 index 000000000000..2e9f16c91347 --- /dev/null +++ b/drivers/accessibility/braille/Makefile | |||
| @@ -0,0 +1 @@ | |||
| obj-$(CONFIG_A11Y_BRAILLE_CONSOLE) += braille_console.o | |||
diff --git a/drivers/accessibility/braille/braille_console.c b/drivers/accessibility/braille/braille_console.c new file mode 100644 index 000000000000..0a5f6b2114c5 --- /dev/null +++ b/drivers/accessibility/braille/braille_console.c | |||
| @@ -0,0 +1,397 @@ | |||
| 1 | /* | ||
| 2 | * Minimalistic braille device kernel support. | ||
| 3 | * | ||
| 4 | * By default, shows console messages on the braille device. | ||
| 5 | * Pressing Insert switches to VC browsing. | ||
| 6 | * | ||
| 7 | * Copyright (C) Samuel Thibault <samuel.thibault@ens-lyon.org> | ||
| 8 | * | ||
| 9 | * This program is free software ; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License as published by | ||
| 11 | * the Free Software Foundation ; either version 2 of the License, or | ||
| 12 | * (at your option) any later version. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, | ||
| 15 | * but WITHOUT ANY WARRANTY ; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | * GNU General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with the program ; if not, write to the Free Software | ||
| 21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 22 | */ | ||
| 23 | |||
| 24 | #include <linux/autoconf.h> | ||
| 25 | #include <linux/kernel.h> | ||
| 26 | #include <linux/module.h> | ||
| 27 | #include <linux/moduleparam.h> | ||
| 28 | #include <linux/console.h> | ||
| 29 | #include <linux/notifier.h> | ||
| 30 | |||
| 31 | #include <linux/selection.h> | ||
| 32 | #include <linux/vt_kern.h> | ||
| 33 | #include <linux/consolemap.h> | ||
| 34 | |||
| 35 | #include <linux/keyboard.h> | ||
| 36 | #include <linux/kbd_kern.h> | ||
| 37 | #include <linux/input.h> | ||
| 38 | |||
| 39 | MODULE_AUTHOR("samuel.thibault@ens-lyon.org"); | ||
| 40 | MODULE_DESCRIPTION("braille device"); | ||
| 41 | MODULE_LICENSE("GPL"); | ||
| 42 | |||
| 43 | /* | ||
| 44 | * Braille device support part. | ||
| 45 | */ | ||
| 46 | |||
| 47 | /* Emit various sounds */ | ||
| 48 | static int sound; | ||
| 49 | module_param(sound, bool, 0); | ||
| 50 | MODULE_PARM_DESC(sound, "emit sounds"); | ||
| 51 | |||
| 52 | static void beep(unsigned int freq) | ||
| 53 | { | ||
| 54 | if (sound) | ||
| 55 | kd_mksound(freq, HZ/10); | ||
| 56 | } | ||
| 57 | |||
| 58 | /* mini console */ | ||
| 59 | #define WIDTH 40 | ||
| 60 | #define BRAILLE_KEY KEY_INSERT | ||
| 61 | static u16 console_buf[WIDTH]; | ||
| 62 | static int console_cursor; | ||
| 63 | |||
| 64 | /* mini view of VC */ | ||
| 65 | static int vc_x, vc_y, lastvc_x, lastvc_y; | ||
| 66 | |||
| 67 | /* show console ? (or show VC) */ | ||
| 68 | static int console_show = 1; | ||
| 69 | /* pending newline ? */ | ||
| 70 | static int console_newline = 1; | ||
| 71 | static int lastVC = -1; | ||
| 72 | |||
| 73 | static struct console *braille_co; | ||
| 74 | |||
| 75 | /* Very VisioBraille-specific */ | ||
| 76 | static void braille_write(u16 *buf) | ||
| 77 | { | ||
| 78 | static u16 lastwrite[WIDTH]; | ||
| 79 | unsigned char data[1 + 1 + 2*WIDTH + 2 + 1], csum = 0, *c; | ||
| 80 | u16 out; | ||
| 81 | int i; | ||
| 82 | |||
| 83 | if (!braille_co) | ||
| 84 | return; | ||
| 85 | |||
| 86 | if (!memcmp(lastwrite, buf, WIDTH * sizeof(*buf))) | ||
| 87 | return; | ||
| 88 | memcpy(lastwrite, buf, WIDTH * sizeof(*buf)); | ||
| 89 | |||
| 90 | #define SOH 1 | ||
| 91 | #define STX 2 | ||
| 92 | #define ETX 2 | ||
| 93 | #define EOT 4 | ||
| 94 | #define ENQ 5 | ||
| 95 | data[0] = STX; | ||
| 96 | data[1] = '>'; | ||
| 97 | csum ^= '>'; | ||
| 98 | c = &data[2]; | ||
| 99 | for (i = 0; i < WIDTH; i++) { | ||
| 100 | out = buf[i]; | ||
| 101 | if (out >= 0x100) | ||
| 102 | out = '?'; | ||
| 103 | else if (out == 0x00) | ||
| 104 | out = ' '; | ||
| 105 | csum ^= out; | ||
| 106 | if (out <= 0x05) { | ||
| 107 | *c++ = SOH; | ||
| 108 | out |= 0x40; | ||
| 109 | } | ||
| 110 | *c++ = out; | ||
| 111 | } | ||
| 112 | |||
| 113 | if (csum <= 0x05) { | ||
| 114 | *c++ = SOH; | ||
| 115 | csum |= 0x40; | ||
| 116 | } | ||
| 117 | *c++ = csum; | ||
| 118 | *c++ = ETX; | ||
| 119 | |||
| 120 | braille_co->write(braille_co, data, c - data); | ||
| 121 | } | ||
| 122 | |||
| 123 | /* Follow the VC cursor*/ | ||
| 124 | static void vc_follow_cursor(struct vc_data *vc) | ||
| 125 | { | ||
| 126 | vc_x = vc->vc_x - (vc->vc_x % WIDTH); | ||
| 127 | vc_y = vc->vc_y; | ||
| 128 | lastvc_x = vc->vc_x; | ||
| 129 | lastvc_y = vc->vc_y; | ||
| 130 | } | ||
| 131 | |||
| 132 | /* Maybe the VC cursor moved, if so follow it */ | ||
| 133 | static void vc_maybe_cursor_moved(struct vc_data *vc) | ||
| 134 | { | ||
| 135 | if (vc->vc_x != lastvc_x || vc->vc_y != lastvc_y) | ||
| 136 | vc_follow_cursor(vc); | ||
| 137 | } | ||
| 138 | |||
| 139 | /* Show portion of VC at vc_x, vc_y */ | ||
| 140 | static void vc_refresh(struct vc_data *vc) | ||
| 141 | { | ||
| 142 | u16 buf[WIDTH]; | ||
| 143 | int i; | ||
| 144 | |||
| 145 | for (i = 0; i < WIDTH; i++) { | ||
| 146 | u16 glyph = screen_glyph(vc, | ||
| 147 | 2 * (vc_x + i) + vc_y * vc->vc_size_row); | ||
| 148 | buf[i] = inverse_translate(vc, glyph, 1); | ||
| 149 | } | ||
| 150 | braille_write(buf); | ||
| 151 | } | ||
| 152 | |||
| 153 | /* | ||
| 154 | * Link to keyboard | ||
| 155 | */ | ||
| 156 | |||
| 157 | static int keyboard_notifier_call(struct notifier_block *blk, | ||
| 158 | unsigned long code, void *_param) | ||
| 159 | { | ||
| 160 | struct keyboard_notifier_param *param = _param; | ||
| 161 | struct vc_data *vc = param->vc; | ||
| 162 | int ret = NOTIFY_OK; | ||
| 163 | |||
| 164 | if (!param->down) | ||
| 165 | return ret; | ||
| 166 | |||
| 167 | switch (code) { | ||
| 168 | case KBD_KEYCODE: | ||
| 169 | if (console_show) { | ||
| 170 | if (param->value == BRAILLE_KEY) { | ||
| 171 | console_show = 0; | ||
| 172 | beep(880); | ||
| 173 | vc_maybe_cursor_moved(vc); | ||
| 174 | vc_refresh(vc); | ||
| 175 | ret = NOTIFY_STOP; | ||
| 176 | } | ||
| 177 | } else { | ||
| 178 | ret = NOTIFY_STOP; | ||
| 179 | switch (param->value) { | ||
| 180 | case KEY_INSERT: | ||
| 181 | beep(440); | ||
| 182 | console_show = 1; | ||
| 183 | lastVC = -1; | ||
| 184 | braille_write(console_buf); | ||
| 185 | break; | ||
| 186 | case KEY_LEFT: | ||
| 187 | if (vc_x > 0) { | ||
| 188 | vc_x -= WIDTH; | ||
| 189 | if (vc_x < 0) | ||
| 190 | vc_x = 0; | ||
| 191 | } else if (vc_y >= 1) { | ||
| 192 | beep(880); | ||
| 193 | vc_y--; | ||
| 194 | vc_x = vc->vc_cols-WIDTH; | ||
| 195 | } else | ||
| 196 | beep(220); | ||
| 197 | break; | ||
| 198 | case KEY_RIGHT: | ||
| 199 | if (vc_x + WIDTH < vc->vc_cols) { | ||
| 200 | vc_x += WIDTH; | ||
| 201 | } else if (vc_y + 1 < vc->vc_rows) { | ||
| 202 | beep(880); | ||
| 203 | vc_y++; | ||
| 204 | vc_x = 0; | ||
| 205 | } else | ||
| 206 | beep(220); | ||
| 207 | break; | ||
| 208 | case KEY_DOWN: | ||
| 209 | if (vc_y + 1 < vc->vc_rows) | ||
| 210 | vc_y++; | ||
| 211 | else | ||
| 212 | beep(220); | ||
| 213 | break; | ||
| 214 | case KEY_UP: | ||
| 215 | if (vc_y >= 1) | ||
| 216 | vc_y--; | ||
| 217 | else | ||
| 218 | beep(220); | ||
| 219 | break; | ||
| 220 | case KEY_HOME: | ||
| 221 | vc_follow_cursor(vc); | ||
| 222 | break; | ||
| 223 | case KEY_PAGEUP: | ||
| 224 | vc_x = 0; | ||
| 225 | vc_y = 0; | ||
| 226 | break; | ||
| 227 | case KEY_PAGEDOWN: | ||
| 228 | vc_x = 0; | ||
| 229 | vc_y = vc->vc_rows-1; | ||
| 230 | break; | ||
| 231 | default: | ||
| 232 | ret = NOTIFY_OK; | ||
| 233 | break; | ||
| 234 | } | ||
| 235 | if (ret == NOTIFY_STOP) | ||
| 236 | vc_refresh(vc); | ||
| 237 | } | ||
| 238 | break; | ||
| 239 | case KBD_POST_KEYSYM: | ||
| 240 | { | ||
| 241 | unsigned char type = KTYP(param->value) - 0xf0; | ||
| 242 | if (type == KT_SPEC) { | ||
| 243 | unsigned char val = KVAL(param->value); | ||
| 244 | int on_off = -1; | ||
| 245 | |||
| 246 | switch (val) { | ||
| 247 | case KVAL(K_CAPS): | ||
| 248 | on_off = vc_kbd_led(kbd_table + fg_console, | ||
| 249 | VC_CAPSLOCK); | ||
| 250 | break; | ||
| 251 | case KVAL(K_NUM): | ||
| 252 | on_off = vc_kbd_led(kbd_table + fg_console, | ||
| 253 | VC_NUMLOCK); | ||
| 254 | break; | ||
| 255 | case KVAL(K_HOLD): | ||
| 256 | on_off = vc_kbd_led(kbd_table + fg_console, | ||
| 257 | VC_SCROLLOCK); | ||
| 258 | break; | ||
| 259 | } | ||
| 260 | if (on_off == 1) | ||
| 261 | beep(880); | ||
| 262 | else if (on_off == 0) | ||
| 263 | beep(440); | ||
| 264 | } | ||
| 265 | } | ||
| 266 | case KBD_UNBOUND_KEYCODE: | ||
| 267 | case KBD_UNICODE: | ||
| 268 | case KBD_KEYSYM: | ||
| 269 | /* Unused */ | ||
| 270 | break; | ||
| 271 | } | ||
| 272 | return ret; | ||
| 273 | } | ||
| 274 | |||
| 275 | static struct notifier_block keyboard_notifier_block = { | ||
| 276 | .notifier_call = keyboard_notifier_call, | ||
| 277 | }; | ||
| 278 | |||
| 279 | static int vt_notifier_call(struct notifier_block *blk, | ||
| 280 | unsigned long code, void *_param) | ||
| 281 | { | ||
| 282 | struct vt_notifier_param *param = _param; | ||
| 283 | struct vc_data *vc = param->vc; | ||
| 284 | switch (code) { | ||
| 285 | case VT_ALLOCATE: | ||
| 286 | break; | ||
| 287 | case VT_DEALLOCATE: | ||
| 288 | break; | ||
| 289 | case VT_WRITE: | ||
| 290 | { | ||
| 291 | unsigned char c = param->c; | ||
| 292 | if (vc->vc_num != fg_console) | ||
| 293 | break; | ||
| 294 | switch (c) { | ||
| 295 | case '\b': | ||
| 296 | case 127: | ||
| 297 | if (console_cursor > 0) { | ||
| 298 | console_cursor--; | ||
| 299 | console_buf[console_cursor] = ' '; | ||
| 300 | } | ||
| 301 | break; | ||
| 302 | case '\n': | ||
| 303 | case '\v': | ||
| 304 | case '\f': | ||
| 305 | case '\r': | ||
| 306 | console_newline = 1; | ||
| 307 | break; | ||
| 308 | case '\t': | ||
| 309 | c = ' '; | ||
| 310 | /* Fallthrough */ | ||
| 311 | default: | ||
| 312 | if (c < 32) | ||
| 313 | /* Ignore other control sequences */ | ||
| 314 | break; | ||
| 315 | if (console_newline) { | ||
| 316 | memset(console_buf, 0, sizeof(console_buf)); | ||
| 317 | console_cursor = 0; | ||
| 318 | console_newline = 0; | ||
| 319 | } | ||
| 320 | if (console_cursor == WIDTH) | ||
| 321 | memmove(console_buf, &console_buf[1], | ||
| 322 | (WIDTH-1) * sizeof(*console_buf)); | ||
| 323 | else | ||
| 324 | console_cursor++; | ||
| 325 | console_buf[console_cursor-1] = c; | ||
| 326 | break; | ||
| 327 | } | ||
| 328 | if (console_show) | ||
| 329 | braille_write(console_buf); | ||
| 330 | else { | ||
| 331 | vc_maybe_cursor_moved(vc); | ||
| 332 | vc_refresh(vc); | ||
| 333 | } | ||
| 334 | break; | ||
| 335 | } | ||
| 336 | case VT_UPDATE: | ||
| 337 | /* Maybe a VT switch, flush */ | ||
| 338 | if (console_show) { | ||
| 339 | if (vc->vc_num != lastVC) { | ||
| 340 | lastVC = vc->vc_num; | ||
| 341 | memset(console_buf, 0, sizeof(console_buf)); | ||
| 342 | console_cursor = 0; | ||
| 343 | braille_write(console_buf); | ||
| 344 | } | ||
| 345 | } else { | ||
| 346 | vc_maybe_cursor_moved(vc); | ||
| 347 | vc_refresh(vc); | ||
| 348 | } | ||
| 349 | break; | ||
| 350 | } | ||
| 351 | return NOTIFY_OK; | ||
| 352 | } | ||
| 353 | |||
| 354 | static struct notifier_block vt_notifier_block = { | ||
| 355 | .notifier_call = vt_notifier_call, | ||
| 356 | }; | ||
| 357 | |||
| 358 | /* | ||
| 359 | * Called from printk.c when console=brl is given | ||
| 360 | */ | ||
| 361 | |||
| 362 | int braille_register_console(struct console *console, int index, | ||
| 363 | char *console_options, char *braille_options) | ||
| 364 | { | ||
| 365 | int ret; | ||
| 366 | if (!console_options) | ||
| 367 | /* Only support VisioBraille for now */ | ||
| 368 | console_options = "57600o8"; | ||
| 369 | if (braille_co) | ||
| 370 | return -ENODEV; | ||
| 371 | if (console->setup) { | ||
| 372 | ret = console->setup(console, console_options); | ||
| 373 | if (ret != 0) | ||
| 374 | return ret; | ||
| 375 | } | ||
| 376 | console->flags |= CON_ENABLED; | ||
| 377 | console->index = index; | ||
| 378 | braille_co = console; | ||
| 379 | return 0; | ||
| 380 | } | ||
| 381 | |||
| 382 | int braille_unregister_console(struct console *console) | ||
| 383 | { | ||
| 384 | if (braille_co != console) | ||
| 385 | return -EINVAL; | ||
| 386 | braille_co = NULL; | ||
| 387 | return 0; | ||
| 388 | } | ||
| 389 | |||
| 390 | static int __init braille_init(void) | ||
| 391 | { | ||
| 392 | register_keyboard_notifier(&keyboard_notifier_block); | ||
| 393 | register_vt_notifier(&vt_notifier_block); | ||
| 394 | return 0; | ||
| 395 | } | ||
| 396 | |||
| 397 | console_initcall(braille_init); | ||
diff --git a/drivers/char/consolemap.c b/drivers/char/consolemap.c index 6b104e45a322..4246b8e36cb3 100644 --- a/drivers/char/consolemap.c +++ b/drivers/char/consolemap.c | |||
| @@ -277,6 +277,7 @@ u16 inverse_translate(struct vc_data *conp, int glyph, int use_unicode) | |||
| 277 | return p->inverse_translations[m][glyph]; | 277 | return p->inverse_translations[m][glyph]; |
| 278 | } | 278 | } |
| 279 | } | 279 | } |
| 280 | EXPORT_SYMBOL_GPL(inverse_translate); | ||
| 280 | 281 | ||
| 281 | static void update_user_maps(void) | 282 | static void update_user_maps(void) |
| 282 | { | 283 | { |
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index d1c50b3302e5..7f7e798c1384 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c | |||
| @@ -110,6 +110,7 @@ const int max_vals[] = { | |||
| 110 | const int NR_TYPES = ARRAY_SIZE(max_vals); | 110 | const int NR_TYPES = ARRAY_SIZE(max_vals); |
| 111 | 111 | ||
| 112 | struct kbd_struct kbd_table[MAX_NR_CONSOLES]; | 112 | struct kbd_struct kbd_table[MAX_NR_CONSOLES]; |
| 113 | EXPORT_SYMBOL_GPL(kbd_table); | ||
| 113 | static struct kbd_struct *kbd = kbd_table; | 114 | static struct kbd_struct *kbd = kbd_table; |
| 114 | 115 | ||
| 115 | struct vt_spawn_console vt_spawn_con = { | 116 | struct vt_spawn_console vt_spawn_con = { |
| @@ -260,6 +261,7 @@ void kd_mksound(unsigned int hz, unsigned int ticks) | |||
| 260 | } else | 261 | } else |
| 261 | kd_nosound(0); | 262 | kd_nosound(0); |
| 262 | } | 263 | } |
| 264 | EXPORT_SYMBOL(kd_mksound); | ||
| 263 | 265 | ||
| 264 | /* | 266 | /* |
| 265 | * Setting the keyboard rate. | 267 | * Setting the keyboard rate. |
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 71cf203d282d..e458b08139af 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
| @@ -4004,6 +4004,7 @@ u16 screen_glyph(struct vc_data *vc, int offset) | |||
| 4004 | c |= 0x100; | 4004 | c |= 0x100; |
| 4005 | return c; | 4005 | return c; |
| 4006 | } | 4006 | } |
| 4007 | EXPORT_SYMBOL_GPL(screen_glyph); | ||
| 4007 | 4008 | ||
| 4008 | /* used by vcs - note the word offset */ | 4009 | /* used by vcs - note the word offset */ |
| 4009 | unsigned short *screen_pos(struct vc_data *vc, int w_offset, int viewed) | 4010 | unsigned short *screen_pos(struct vc_data *vc, int w_offset, int viewed) |
diff --git a/include/linux/console.h b/include/linux/console.h index a5f88a6a259d..a4f27fbdf549 100644 --- a/include/linux/console.h +++ b/include/linux/console.h | |||
| @@ -91,6 +91,7 @@ void give_up_console(const struct consw *sw); | |||
| 91 | #define CON_ENABLED (4) | 91 | #define CON_ENABLED (4) |
| 92 | #define CON_BOOT (8) | 92 | #define CON_BOOT (8) |
| 93 | #define CON_ANYTIME (16) /* Safe to call when cpu is offline */ | 93 | #define CON_ANYTIME (16) /* Safe to call when cpu is offline */ |
| 94 | #define CON_BRL (32) /* Used for a braille device */ | ||
| 94 | 95 | ||
| 95 | struct console { | 96 | struct console { |
| 96 | char name[16]; | 97 | char name[16]; |
| @@ -121,6 +122,9 @@ extern struct tty_driver *console_device(int *); | |||
| 121 | extern void console_stop(struct console *); | 122 | extern void console_stop(struct console *); |
| 122 | extern void console_start(struct console *); | 123 | extern void console_start(struct console *); |
| 123 | extern int is_console_locked(void); | 124 | extern int is_console_locked(void); |
| 125 | extern int braille_register_console(struct console *, int index, | ||
| 126 | char *console_options, char *braille_options); | ||
| 127 | extern int braille_unregister_console(struct console *); | ||
| 124 | 128 | ||
| 125 | extern int console_suspend_enabled; | 129 | extern int console_suspend_enabled; |
| 126 | 130 | ||
diff --git a/kernel/printk.c b/kernel/printk.c index 0d232589a923..e61346faf6a5 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
| @@ -111,6 +111,9 @@ struct console_cmdline | |||
| 111 | char name[8]; /* Name of the driver */ | 111 | char name[8]; /* Name of the driver */ |
| 112 | int index; /* Minor dev. to use */ | 112 | int index; /* Minor dev. to use */ |
| 113 | char *options; /* Options for the driver */ | 113 | char *options; /* Options for the driver */ |
| 114 | #ifdef CONFIG_A11Y_BRAILLE_CONSOLE | ||
| 115 | char *brl_options; /* Options for braille driver */ | ||
| 116 | #endif | ||
| 114 | }; | 117 | }; |
| 115 | 118 | ||
| 116 | #define MAX_CMDLINECONSOLES 8 | 119 | #define MAX_CMDLINECONSOLES 8 |
| @@ -808,15 +811,60 @@ static void call_console_drivers(unsigned start, unsigned end) | |||
| 808 | 811 | ||
| 809 | #endif | 812 | #endif |
| 810 | 813 | ||
| 814 | static int __add_preferred_console(char *name, int idx, char *options, | ||
| 815 | char *brl_options) | ||
| 816 | { | ||
| 817 | struct console_cmdline *c; | ||
| 818 | int i; | ||
| 819 | |||
| 820 | /* | ||
| 821 | * See if this tty is not yet registered, and | ||
| 822 | * if we have a slot free. | ||
| 823 | */ | ||
| 824 | for (i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++) | ||
| 825 | if (strcmp(console_cmdline[i].name, name) == 0 && | ||
| 826 | console_cmdline[i].index == idx) { | ||
| 827 | if (!brl_options) | ||
| 828 | selected_console = i; | ||
| 829 | return 0; | ||
| 830 | } | ||
| 831 | if (i == MAX_CMDLINECONSOLES) | ||
| 832 | return -E2BIG; | ||
| 833 | if (!brl_options) | ||
| 834 | selected_console = i; | ||
| 835 | c = &console_cmdline[i]; | ||
| 836 | strlcpy(c->name, name, sizeof(c->name)); | ||
| 837 | c->options = options; | ||
| 838 | #ifdef CONFIG_A11Y_BRAILLE_CONSOLE | ||
| 839 | c->brl_options = brl_options; | ||
| 840 | #endif | ||
| 841 | c->index = idx; | ||
| 842 | return 0; | ||
| 843 | } | ||
| 811 | /* | 844 | /* |
| 812 | * Set up a list of consoles. Called from init/main.c | 845 | * Set up a list of consoles. Called from init/main.c |
| 813 | */ | 846 | */ |
| 814 | static int __init console_setup(char *str) | 847 | static int __init console_setup(char *str) |
| 815 | { | 848 | { |
| 816 | char buf[sizeof(console_cmdline[0].name) + 4]; /* 4 for index */ | 849 | char buf[sizeof(console_cmdline[0].name) + 4]; /* 4 for index */ |
| 817 | char *s, *options; | 850 | char *s, *options, *brl_options = NULL; |
| 818 | int idx; | 851 | int idx; |
| 819 | 852 | ||
| 853 | #ifdef CONFIG_A11Y_BRAILLE_CONSOLE | ||
| 854 | if (!memcmp(str, "brl,", 4)) { | ||
| 855 | brl_options = ""; | ||
| 856 | str += 4; | ||
| 857 | } else if (!memcmp(str, "brl=", 4)) { | ||
| 858 | brl_options = str + 4; | ||
| 859 | str = strchr(brl_options, ','); | ||
| 860 | if (!str) { | ||
| 861 | printk(KERN_ERR "need port name after brl=\n"); | ||
| 862 | return 1; | ||
| 863 | } | ||
| 864 | *(str++) = 0; | ||
| 865 | } | ||
| 866 | #endif | ||
| 867 | |||
| 820 | /* | 868 | /* |
| 821 | * Decode str into name, index, options. | 869 | * Decode str into name, index, options. |
| 822 | */ | 870 | */ |
| @@ -841,7 +889,7 @@ static int __init console_setup(char *str) | |||
| 841 | idx = simple_strtoul(s, NULL, 10); | 889 | idx = simple_strtoul(s, NULL, 10); |
| 842 | *s = 0; | 890 | *s = 0; |
| 843 | 891 | ||
| 844 | add_preferred_console(buf, idx, options); | 892 | __add_preferred_console(buf, idx, options, brl_options); |
| 845 | return 1; | 893 | return 1; |
| 846 | } | 894 | } |
| 847 | __setup("console=", console_setup); | 895 | __setup("console=", console_setup); |
| @@ -861,28 +909,7 @@ __setup("console=", console_setup); | |||
| 861 | */ | 909 | */ |
| 862 | int add_preferred_console(char *name, int idx, char *options) | 910 | int add_preferred_console(char *name, int idx, char *options) |
| 863 | { | 911 | { |
| 864 | struct console_cmdline *c; | 912 | return __add_preferred_console(name, idx, options, NULL); |
| 865 | int i; | ||
| 866 | |||
| 867 | /* | ||
| 868 | * See if this tty is not yet registered, and | ||
| 869 | * if we have a slot free. | ||
| 870 | */ | ||
| 871 | for (i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++) | ||
| 872 | if (strcmp(console_cmdline[i].name, name) == 0 && | ||
| 873 | console_cmdline[i].index == idx) { | ||
| 874 | selected_console = i; | ||
| 875 | return 0; | ||
| 876 | } | ||
| 877 | if (i == MAX_CMDLINECONSOLES) | ||
| 878 | return -E2BIG; | ||
| 879 | selected_console = i; | ||
| 880 | c = &console_cmdline[i]; | ||
| 881 | memcpy(c->name, name, sizeof(c->name)); | ||
| 882 | c->name[sizeof(c->name) - 1] = 0; | ||
| 883 | c->options = options; | ||
| 884 | c->index = idx; | ||
| 885 | return 0; | ||
| 886 | } | 913 | } |
| 887 | 914 | ||
| 888 | int update_console_cmdline(char *name, int idx, char *name_new, int idx_new, char *options) | 915 | int update_console_cmdline(char *name, int idx, char *name_new, int idx_new, char *options) |
| @@ -1163,6 +1190,16 @@ void register_console(struct console *console) | |||
| 1163 | continue; | 1190 | continue; |
| 1164 | if (console->index < 0) | 1191 | if (console->index < 0) |
| 1165 | console->index = console_cmdline[i].index; | 1192 | console->index = console_cmdline[i].index; |
| 1193 | #ifdef CONFIG_A11Y_BRAILLE_CONSOLE | ||
| 1194 | if (console_cmdline[i].brl_options) { | ||
| 1195 | console->flags |= CON_BRL; | ||
| 1196 | braille_register_console(console, | ||
| 1197 | console_cmdline[i].index, | ||
| 1198 | console_cmdline[i].options, | ||
| 1199 | console_cmdline[i].brl_options); | ||
| 1200 | return; | ||
| 1201 | } | ||
| 1202 | #endif | ||
| 1166 | if (console->setup && | 1203 | if (console->setup && |
| 1167 | console->setup(console, console_cmdline[i].options) != 0) | 1204 | console->setup(console, console_cmdline[i].options) != 0) |
| 1168 | break; | 1205 | break; |
| @@ -1221,6 +1258,11 @@ int unregister_console(struct console *console) | |||
| 1221 | struct console *a, *b; | 1258 | struct console *a, *b; |
| 1222 | int res = 1; | 1259 | int res = 1; |
| 1223 | 1260 | ||
| 1261 | #ifdef CONFIG_A11Y_BRAILLE_CONSOLE | ||
| 1262 | if (console->flags & CON_BRL) | ||
| 1263 | return braille_unregister_console(console); | ||
| 1264 | #endif | ||
| 1265 | |||
| 1224 | acquire_console_sem(); | 1266 | acquire_console_sem(); |
| 1225 | if (console_drivers == console) { | 1267 | if (console_drivers == console) { |
| 1226 | console_drivers=console->next; | 1268 | console_drivers=console->next; |
