summaryrefslogtreecommitdiff
path: root/drivers/staging/speakup
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/speakup')
-rw-r--r--drivers/staging/speakup/keyhelp.c4
-rw-r--r--drivers/staging/speakup/main.c133
-rw-r--r--drivers/staging/speakup/spk_priv_keyinfo.h44
-rw-r--r--drivers/staging/speakup/spk_types.h18
4 files changed, 124 insertions, 75 deletions
diff --git a/drivers/staging/speakup/keyhelp.c b/drivers/staging/speakup/keyhelp.c
index 236f06d..23cf7f4 100644
--- a/drivers/staging/speakup/keyhelp.c
+++ b/drivers/staging/speakup/keyhelp.c
@@ -161,7 +161,9 @@ int handle_help(struct vc_data *vc, u_char type, u_char ch, u_short key)
}
cur_item = letter_offsets[ch-'a'];
} else if (type == KT_CUR) {
- if (ch == 0 && (cur_item + 1) <= MSG_FUNCNAMES_END)
+ if (ch == 0
+ && (MSG_FUNCNAMES_START + cur_item + 1) <=
+ MSG_FUNCNAMES_END)
cur_item++;
else if (ch == 3 && cur_item > 0)
cur_item--;
diff --git a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c
index 3cd0039..42fcf7e 100644
--- a/drivers/staging/speakup/main.c
+++ b/drivers/staging/speakup/main.c
@@ -1283,7 +1283,7 @@ static int edit_bits(struct vc_data *vc, u_char type, u_char ch, u_short key)
}
/* Allocation concurrency is protected by the console semaphore */
-void speakup_allocate(struct vc_data *vc)
+int speakup_allocate(struct vc_data *vc)
{
int vc_num;
@@ -1292,10 +1292,12 @@ void speakup_allocate(struct vc_data *vc)
speakup_console[vc_num] = kzalloc(sizeof(*speakup_console[0]),
GFP_ATOMIC);
if (speakup_console[vc_num] == NULL)
- return;
+ return -ENOMEM;
speakup_date(vc);
} else if (!spk_parked)
speakup_date(vc);
+
+ return 0;
}
void speakup_deallocate(struct vc_data *vc)
@@ -1303,10 +1305,8 @@ void speakup_deallocate(struct vc_data *vc)
int vc_num;
vc_num = vc->vc_num;
- if (speakup_console[vc_num] != NULL) {
- kfree(speakup_console[vc_num]);
- speakup_console[vc_num] = NULL;
- }
+ kfree(speakup_console[vc_num]);
+ speakup_console[vc_num] = NULL;
}
static u_char is_cursor;
@@ -2217,18 +2217,23 @@ static void __exit speakup_exit(void)
{
int i;
- free_user_msgs();
unregister_keyboard_notifier(&keyboard_notifier_block);
unregister_vt_notifier(&vt_notifier_block);
speakup_unregister_devsynth();
del_timer(&cursor_timer);
-
kthread_stop(speakup_task);
speakup_task = NULL;
mutex_lock(&spk_mutex);
synth_release();
mutex_unlock(&spk_mutex);
+ speakup_kobj_exit();
+
+ for (i = 0; i < MAX_NR_CONSOLES; i++)
+ kfree(speakup_console[i]);
+
+ speakup_remove_virtual_keyboard();
+
for (i = 0; i < MAXVARS; i++)
speakup_unregister_var(i);
@@ -2236,42 +2241,23 @@ static void __exit speakup_exit(void)
if (characters[i] != default_chars[i])
kfree(characters[i]);
}
- for (i = 0; speakup_console[i]; i++)
- kfree(speakup_console[i]);
- speakup_kobj_exit();
- speakup_remove_virtual_keyboard();
+
+ free_user_msgs();
}
/* call by: module_init() */
static int __init speakup_init(void)
{
int i;
- int err;
+ long err = 0;
struct st_spk_t *first_console;
struct vc_data *vc = vc_cons[fg_console].d;
struct var_t *var;
- err = speakup_add_virtual_keyboard();
- if (err)
- goto out;
-
+ /* These first few initializations cannot fail. */
initialize_msgs(); /* Initialize arrays for i18n. */
- first_console = kzalloc(sizeof(*first_console), GFP_KERNEL);
- if (!first_console) {
- err = -ENOMEM;
- goto err_cons;
- }
- err = speakup_kobj_init();
- if (err)
- goto err_kobject;
-
reset_default_chars();
reset_default_chartab();
-
- speakup_console[vc->vc_num] = first_console;
- speakup_date(vc);
- pr_info("speakup %s: initialized\n", SPEAKUP_VERSION);
-
strlwr(synth_name);
spk_vars[0].u.n.high = vc->vc_cols;
for (var = spk_vars; var->var_id != MAXVARS; var++)
@@ -2286,31 +2272,92 @@ static int __init speakup_init(void)
if (quiet_boot)
spk_shut_up |= 0x01;
+ /* From here on out, initializations can fail. */
+ err = speakup_add_virtual_keyboard();
+ if (err)
+ goto error_virtkeyboard;
+
+ first_console = kzalloc(sizeof(*first_console), GFP_KERNEL);
+ if (!first_console) {
+ err = -ENOMEM;
+ goto error_alloc;
+ }
+
+ speakup_console[vc->vc_num] = first_console;
+ speakup_date(vc);
+
for (i = 0; i < MAX_NR_CONSOLES; i++)
- if (vc_cons[i].d)
- speakup_allocate(vc_cons[i].d);
+ if (vc_cons[i].d) {
+ err = speakup_allocate(vc_cons[i].d);
+ if (err)
+ goto error_kobjects;
+ }
+
+ err = speakup_kobj_init();
+ if (err)
+ goto error_kobjects;
- pr_warn("synth name on entry is: %s\n", synth_name);
synth_init(synth_name);
speakup_register_devsynth();
+ /*
+ * register_devsynth might fail, but this error is not fatal.
+ * /dev/synth is an extra feature; the rest of Speakup
+ * will work fine without it.
+ */
- register_keyboard_notifier(&keyboard_notifier_block);
- register_vt_notifier(&vt_notifier_block);
+ err = register_keyboard_notifier(&keyboard_notifier_block);
+ if (err)
+ goto error_kbdnotifier;
+ err = register_vt_notifier(&vt_notifier_block);
+ if (err)
+ goto error_vtnotifier;
speakup_task = kthread_create(speakup_thread, NULL, "speakup");
- set_user_nice(speakup_task, 10);
+
if (IS_ERR(speakup_task)) {
- err = -ENOMEM;
- goto err_kobject;
+ err = PTR_ERR(speakup_task);
+ goto error_task;
}
+
+ set_user_nice(speakup_task, 10);
wake_up_process(speakup_task);
+
+ pr_info("speakup %s: initialized\n", SPEAKUP_VERSION);
+ pr_info("synth name on entry is: %s\n", synth_name);
goto out;
-err_kobject:
-speakup_kobj_exit();
- kfree(first_console);
-err_cons:
+error_task:
+ unregister_vt_notifier(&vt_notifier_block);
+
+error_vtnotifier:
+ unregister_keyboard_notifier(&keyboard_notifier_block);
+ del_timer(&cursor_timer);
+
+error_kbdnotifier:
+ speakup_unregister_devsynth();
+ mutex_lock(&spk_mutex);
+ synth_release();
+ mutex_unlock(&spk_mutex);
+ speakup_kobj_exit();
+
+error_kobjects:
+ for (i = 0; i < MAX_NR_CONSOLES; i++)
+ kfree(speakup_console[i]);
+
+error_alloc:
speakup_remove_virtual_keyboard();
+
+error_virtkeyboard:
+ for (i = 0; i < MAXVARS; i++)
+ speakup_unregister_var(i);
+
+ for (i = 0; i < 256; i++) {
+ if (characters[i] != default_chars[i])
+ kfree(characters[i]);
+ }
+
+ free_user_msgs();
+
out:
return err;
}
diff --git a/drivers/staging/speakup/spk_priv_keyinfo.h b/drivers/staging/speakup/spk_priv_keyinfo.h
index 3fd4b82..95c473a 100644
--- a/drivers/staging/speakup/spk_priv_keyinfo.h
+++ b/drivers/staging/speakup/spk_priv_keyinfo.h
@@ -84,27 +84,27 @@
/* keys for setting variables, must be ordered same as the enum for var_ids */
/* with dec being even and inc being 1 greater */
-#define SPELL_DELAY_DEC VAR_START+0
-#define SPELL_DELAY_INC SPELL_DELAY_DEC+1
-#define PUNC_LEVEL_DEC SPELL_DELAY_DEC+2
-#define PUNC_LEVEL_INC PUNC_LEVEL_DEC+1
-#define READING_PUNC_DEC PUNC_LEVEL_DEC+2
-#define READING_PUNC_INC READING_PUNC_DEC+1
-#define ATTRIB_BLEEP_DEC READING_PUNC_DEC+2
-#define ATTRIB_BLEEP_INC ATTRIB_BLEEP_DEC+1
-#define BLEEPS_DEC ATTRIB_BLEEP_DEC+2
-#define BLEEPS_INC BLEEPS_DEC+1
-#define RATE_DEC BLEEPS_DEC+2
-#define RATE_INC RATE_DEC+1
-#define PITCH_DEC RATE_DEC+2
-#define PITCH_INC PITCH_DEC+1
-#define VOL_DEC PITCH_DEC+2
-#define VOL_INC VOL_DEC+1
-#define TONE_DEC VOL_DEC+2
-#define TONE_INC TONE_DEC+1
-#define PUNCT_DEC TONE_DEC+2
-#define PUNCT_INC PUNCT_DEC+1
-#define VOICE_DEC PUNCT_DEC+2
-#define VOICE_INC VOICE_DEC+1
+#define SPELL_DELAY_DEC (VAR_START+0)
+#define SPELL_DELAY_INC (SPELL_DELAY_DEC+1)
+#define PUNC_LEVEL_DEC (SPELL_DELAY_DEC+2)
+#define PUNC_LEVEL_INC (PUNC_LEVEL_DEC+1)
+#define READING_PUNC_DEC (PUNC_LEVEL_DEC+2)
+#define READING_PUNC_INC (READING_PUNC_DEC+1)
+#define ATTRIB_BLEEP_DEC (READING_PUNC_DEC+2)
+#define ATTRIB_BLEEP_INC (ATTRIB_BLEEP_DEC+1)
+#define BLEEPS_DEC (ATTRIB_BLEEP_DEC+2)
+#define BLEEPS_INC (BLEEPS_DEC+1)
+#define RATE_DEC (BLEEPS_DEC+2)
+#define RATE_INC (RATE_DEC+1)
+#define PITCH_DEC (RATE_DEC+2)
+#define PITCH_INC (PITCH_DEC+1)
+#define VOL_DEC (PITCH_DEC+2)
+#define VOL_INC (VOL_DEC+1)
+#define TONE_DEC (VOL_DEC+2)
+#define TONE_INC (TONE_DEC+1)
+#define PUNCT_DEC (TONE_DEC+2)
+#define PUNCT_INC (PUNCT_DEC+1)
+#define VOICE_DEC (PUNCT_DEC+2)
+#define VOICE_INC (VOICE_DEC+1)
#endif
diff --git a/drivers/staging/speakup/spk_types.h b/drivers/staging/speakup/spk_types.h
index d36c90e..3ac552c 100644
--- a/drivers/staging/speakup/spk_types.h
+++ b/drivers/staging/speakup/spk_types.h
@@ -79,14 +79,14 @@ struct st_spk_t {
};
/* now some defines to make these easier to use. */
-#define spk_shut_up speakup_console[vc->vc_num]->shut_up
+#define spk_shut_up (speakup_console[vc->vc_num]->shut_up)
#define spk_killed (speakup_console[vc->vc_num]->shut_up & 0x40)
-#define spk_x speakup_console[vc->vc_num]->reading_x
-#define spk_cx speakup_console[vc->vc_num]->cursor_x
-#define spk_y speakup_console[vc->vc_num]->reading_y
-#define spk_cy speakup_console[vc->vc_num]->cursor_y
+#define spk_x (speakup_console[vc->vc_num]->reading_x)
+#define spk_cx (speakup_console[vc->vc_num]->cursor_x)
+#define spk_y (speakup_console[vc->vc_num]->reading_y)
+#define spk_cy (speakup_console[vc->vc_num]->cursor_y)
#define spk_pos (speakup_console[vc->vc_num]->reading_pos)
-#define spk_cp speakup_console[vc->vc_num]->cursor_pos
+#define spk_cp (speakup_console[vc->vc_num]->cursor_pos)
#define goto_pos (speakup_console[vc->vc_num]->go_pos)
#define goto_x (speakup_console[vc->vc_num]->go_x)
#define win_top (speakup_console[vc->vc_num]->w_top)
@@ -95,9 +95,9 @@ struct st_spk_t {
#define win_right (speakup_console[vc->vc_num]->w_right)
#define win_start (speakup_console[vc->vc_num]->w_start)
#define win_enabled (speakup_console[vc->vc_num]->w_enabled)
-#define spk_attr speakup_console[vc->vc_num]->reading_attr
-#define spk_old_attr speakup_console[vc->vc_num]->old_attr
-#define spk_parked speakup_console[vc->vc_num]->parked
+#define spk_attr (speakup_console[vc->vc_num]->reading_attr)
+#define spk_old_attr (speakup_console[vc->vc_num]->old_attr)
+#define spk_parked (speakup_console[vc->vc_num]->parked)
struct st_var_header {
char *name;