diff options
Diffstat (limited to 'drivers/staging/speakup')
28 files changed, 575 insertions, 626 deletions
diff --git a/drivers/staging/speakup/Kconfig b/drivers/staging/speakup/Kconfig index b416aceb13f..efd6f4560d3 100644 --- a/drivers/staging/speakup/Kconfig +++ b/drivers/staging/speakup/Kconfig @@ -11,7 +11,7 @@ config SPEAKUP point your browser at <http://www.linux-speakup.org/>. There is also a mailing list at the above url that you can subscribe to. - + Supported synthesizers are accent sa, accent pc, appollo II., Auddapter, Braille 'n Speak, Dectalk external (old), Dectalk PC (full length isa board), @@ -19,24 +19,24 @@ config SPEAKUP Litetalk, Keynote Gold internal PC, software synthesizers, Speakout, transport, and a dummy module that can be used with a plain text terminal. - + Speakup can either be built in or compiled as a module by answering y or m. If you answer y here, then you must answer either y or m to at least one of the synthesizer drivers below. If you answer m here, then the synthesizer drivers below can only be built as modules. - + These drivers are not standalone drivers, but must be used in conjunction with Speakup. Think of them as video cards for blind people. - - + + The Dectalk pc driver can only be built as a module, and requires software to be pre-loaded on to the card before the module can be loaded. See the decpc choice below for more details. - + If you are not a blind person, or don't have access to one of the listed synthesizers, you should say n. @@ -51,6 +51,7 @@ config SPEAKUP_SYNTH_ACNTSA config SPEAKUP_SYNTH_ACNTPC tristate "Accent PC synthesizer support" + depends on ISA || COMPILE_TEST ---help--- This is the Speakup driver for the accent pc synthesizer. You can say y to build it into the kernel, @@ -84,7 +85,7 @@ config SPEAKUP_SYNTH_BNS config SPEAKUP_SYNTH_DECTLK tristate "DECtalk Express synthesizer support" ---help--- - + This is the Speakup driver for the DecTalk Express synthesizer. You can say y to build it into the kernel, or m to build it as a module. See the configuration @@ -93,7 +94,7 @@ config SPEAKUP_SYNTH_DECTLK config SPEAKUP_SYNTH_DECEXT tristate "DECtalk External (old) synthesizer support" ---help--- - + This is the Speakup driver for the DecTalk External (old) synthesizer. You can say y to build it into the kernel, or m to build it as a module. See the @@ -102,14 +103,15 @@ config SPEAKUP_SYNTH_DECEXT config SPEAKUP_SYNTH_DECPC depends on m + depends on ISA || COMPILE_TEST tristate "DECtalk PC (big ISA card) synthesizer support" ---help--- - + This is the Speakup driver for the DecTalk PC (full length ISA) synthesizer. You can say m to build it as a module. See the configuration help on the Speakup choice above for more info. - + In order to use the DecTalk PC driver, you must download the dec_pc.tgz file from linux-speakup.org. It is in the pub/linux/goodies directory. The dec_pc.tgz file @@ -118,14 +120,15 @@ config SPEAKUP_SYNTH_DECPC This driver must be built as a module, and can not be loaded until the file system is mounted and the DecTalk PC software has been pre-loaded on to the board. - + See the README file in the dec_pc.tgz file for more details. config SPEAKUP_SYNTH_DTLK tristate "DoubleTalk PC synthesizer support" + depends on ISA || COMPILE_TEST ---help--- - + This is the Speakup driver for the internal DoubleTalk PC synthesizer. You can say y to build it into the kernel, or m to build it as a module. See the @@ -134,8 +137,9 @@ config SPEAKUP_SYNTH_DTLK config SPEAKUP_SYNTH_KEYPC tristate "Keynote Gold PC synthesizer support" + depends on ISA || COMPILE_TEST ---help--- - + This is the Speakup driver for the Keynote Gold PC synthesizer. You can say y to build it into the kernel, or m to build it as a module. See the @@ -166,7 +170,7 @@ config SPEAKUP_SYNTH_SOFT config SPEAKUP_SYNTH_SPKOUT tristate "Speak Out synthesizer support" ---help--- - + This is the Speakup driver for the Speakout synthesizer. You can say y to build it into the kernel, or m to build it as a module. See the configuration help on the @@ -175,7 +179,7 @@ config SPEAKUP_SYNTH_SPKOUT config SPEAKUP_SYNTH_TXPRT tristate "Transport synthesizer support" ---help--- - + This is the Speakup driver for the Transport synthesizer. You can say y to build it into the kernel, or m to build it as a module. See the configuration @@ -184,7 +188,7 @@ config SPEAKUP_SYNTH_TXPRT config SPEAKUP_SYNTH_DUMMY tristate "Dummy synthesizer driver (for testing)" ---help--- - + This is a dummy Speakup driver for plugging a mere serial terminal. This is handy if you want to test speakup but don't have the hardware. You can say y to build it into diff --git a/drivers/staging/speakup/devsynth.c b/drivers/staging/speakup/devsynth.c index 940769ef883..71c728acf4c 100644 --- a/drivers/staging/speakup/devsynth.c +++ b/drivers/staging/speakup/devsynth.c @@ -13,11 +13,11 @@ static int misc_registered; static int dev_opened; -static ssize_t speakup_file_write(struct file *fp, const char *buffer, - size_t nbytes, loff_t *ppos) +static ssize_t speakup_file_write(struct file *fp, const char __user *buffer, + size_t nbytes, loff_t *ppos) { size_t count = nbytes; - const char *ptr = buffer; + const char __user *ptr = buffer; size_t bytes; unsigned long flags; u_char buf[256]; @@ -30,15 +30,15 @@ static ssize_t speakup_file_write(struct file *fp, const char *buffer, return -EFAULT; count -= bytes; ptr += bytes; - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); synth_write(buf, bytes); - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); } return (ssize_t) nbytes; } -static ssize_t speakup_file_read(struct file *fp, char *buf, size_t nbytes, - loff_t *ppos) +static ssize_t speakup_file_read(struct file *fp, char __user *buf, + size_t nbytes, loff_t *ppos) { return 0; } diff --git a/drivers/staging/speakup/i18n.c b/drivers/staging/speakup/i18n.c index 2add1fcfd12..9ea16c5b4d6 100644 --- a/drivers/staging/speakup/i18n.c +++ b/drivers/staging/speakup/i18n.c @@ -558,11 +558,11 @@ ssize_t spk_msg_set(enum msg_index_t index, char *text, size_t length) kfree(newstr); return -EINVAL; } - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); if (speakup_msgs[index] != speakup_default_msgs[index]) kfree(speakup_msgs[index]); speakup_msgs[index] = newstr; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); } else { rc = -ENOMEM; } @@ -595,14 +595,14 @@ void spk_reset_msg_group(struct msg_group_t *group) unsigned long flags; enum msg_index_t i; - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); for (i = group->start; i <= group->end; i++) { if (speakup_msgs[i] != speakup_default_msgs[i]) kfree(speakup_msgs[i]); speakup_msgs[i] = speakup_default_msgs[i]; } - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); } /* Called at initialization time, to establish default messages. */ @@ -618,12 +618,12 @@ void spk_free_user_msgs(void) enum msg_index_t index; unsigned long flags; - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); for (index = MSG_FIRST_INDEX; index < MSG_LAST_INDEX; index++) { if (speakup_msgs[index] != speakup_default_msgs[index]) { kfree(speakup_msgs[index]); speakup_msgs[index] = speakup_default_msgs[index]; } } - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); } diff --git a/drivers/staging/speakup/kobjects.c b/drivers/staging/speakup/kobjects.c index 35f647ce1f1..2ef7f6f201a 100644 --- a/drivers/staging/speakup/kobjects.c +++ b/drivers/staging/speakup/kobjects.c @@ -15,6 +15,7 @@ #include <linux/kernel.h> #include <linux/kobject.h> #include <linux/string.h> +#include <linux/string_helpers.h> #include <linux/sysfs.h> #include <linux/ctype.h> @@ -34,7 +35,7 @@ static ssize_t chars_chartab_show(struct kobject *kobj, size_t bufsize = PAGE_SIZE; unsigned long flags; - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); *buf_pointer = '\0'; for (i = 0; i < 256; i++) { if (bufsize <= 1) @@ -69,7 +70,7 @@ static ssize_t chars_chartab_show(struct kobject *kobj, bufsize -= len; buf_pointer += len; } - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); return buf_pointer - buf; } @@ -126,7 +127,7 @@ static ssize_t chars_chartab_store(struct kobject *kobj, size_t desc_length = 0; int i; - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); while (cp < end) { while ((cp < end) && (*cp == ' ' || *cp == '\t')) @@ -211,7 +212,7 @@ static ssize_t chars_chartab_store(struct kobject *kobj, spk_reset_default_chartab(); } - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); report_char_chartab_status(reset, received, used, rejected, do_characters); return retval; @@ -231,7 +232,7 @@ static ssize_t keymap_show(struct kobject *kobj, struct kobj_attribute *attr, u_char *cp1; u_char ch; unsigned long flags; - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); cp1 = spk_key_buf + SHIFT_TBL_SIZE; num_keys = (int)(*cp1); nstates = (int)cp1[1]; @@ -247,7 +248,7 @@ static ssize_t keymap_show(struct kobject *kobj, struct kobj_attribute *attr, } } cp += sprintf(cp, "0, %d\n", KEY_MAP_VER); - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); return (int)(cp-buf); } @@ -264,17 +265,17 @@ static ssize_t keymap_store(struct kobject *kobj, struct kobj_attribute *attr, u_char *cp1; unsigned long flags; - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); in_buff = kmemdup(buf, count + 1, GFP_ATOMIC); if (!in_buff) { - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); return -ENOMEM; } if (strchr("dDrR", *in_buff)) { spk_set_key_info(spk_key_defaults, spk_key_buf); pr_info("keymap set to default values\n"); kfree(in_buff); - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); return count; } if (in_buff[count - 1] == '\n') @@ -293,7 +294,7 @@ static ssize_t keymap_store(struct kobject *kobj, struct kobj_attribute *attr, pr_warn("i %d %d %d %d\n", i, (int)cp1[-3], (int)cp1[-2], (int)cp1[-1]); kfree(in_buff); - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); return -EINVAL; } while (--i >= 0) { @@ -314,7 +315,7 @@ static ssize_t keymap_store(struct kobject *kobj, struct kobj_attribute *attr, } } kfree(in_buff); - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); return ret; } @@ -340,7 +341,7 @@ static ssize_t silent_store(struct kobject *kobj, struct kobj_attribute *attr, pr_warn("silent value '%c' not in range (0,7)\n", ch); return -EINVAL; } - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); if (ch&2) { shut = 1; spk_do_flush(); @@ -353,7 +354,7 @@ static ssize_t silent_store(struct kobject *kobj, struct kobj_attribute *attr, spk_shut_up |= shut; else spk_shut_up &= ~shut; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); return count; } @@ -417,7 +418,7 @@ static ssize_t synth_direct_store(struct kobject *kobj, bytes = min_t(size_t, len, 250); strncpy(tmp, ptr, bytes); tmp[bytes] = '\0'; - spk_xlate(tmp); + string_unescape_any_inplace(tmp); synth_printf("%s", tmp); ptr += bytes; len -= bytes; @@ -469,7 +470,7 @@ static ssize_t punc_show(struct kobject *kobj, struct kobj_attribute *attr, return -EINVAL; } - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); pb = (struct st_bits_data *) &spk_punc_info[var->value]; mask = pb->mask; for (i = 33; i < 128; i++) { @@ -477,7 +478,7 @@ static ssize_t punc_show(struct kobject *kobj, struct kobj_attribute *attr, continue; *cp++ = (char)i; } - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); return cp-buf; } @@ -517,14 +518,14 @@ static ssize_t punc_store(struct kobject *kobj, struct kobj_attribute *attr, x--; punc_buf[x] = '\0'; - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); if (*punc_buf == 'd' || *punc_buf == 'r') - x = spk_set_mask_bits(0, var->value, 3); + x = spk_set_mask_bits(NULL, var->value, 3); else x = spk_set_mask_bits(punc_buf, var->value, 3); - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); return count; } @@ -546,7 +547,7 @@ ssize_t spk_var_show(struct kobject *kobj, struct kobj_attribute *attr, if (param == NULL) return -EINVAL; - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); var = (struct var_t *) param->data; switch (param->var_type) { case VAR_NUM: @@ -579,12 +580,31 @@ ssize_t spk_var_show(struct kobject *kobj, struct kobj_attribute *attr, param->name, param->var_type); break; } - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); return rv; } EXPORT_SYMBOL_GPL(spk_var_show); /* + * Used to reset either default_pitch or default_vol. + */ +static inline void spk_reset_default_value(char *header_name, + int *synth_default_value, int idx) +{ + struct st_var_header *param; + + if (synth && synth_default_value) { + param = spk_var_header_by_name(header_name); + if (param) { + spk_set_num_var(synth_default_value[idx], + param, E_NEW_DEFAULT); + spk_set_num_var(0, param, E_DEFAULT); + pr_info("%s reset to default value\n", param->name); + } + } +} + +/* * This function is called when a user echos a value to one of the * variable parameters. */ @@ -596,7 +616,7 @@ ssize_t spk_var_store(struct kobject *kobj, struct kobj_attribute *attr, int len; char *cp; struct var_t *var_data; - int value; + long value; unsigned long flags; param = spk_var_header_by_name(attr->attr.name); @@ -605,9 +625,10 @@ ssize_t spk_var_store(struct kobject *kobj, struct kobj_attribute *attr, if (param->data == NULL) return 0; ret = 0; - cp = spk_xlate((char *) buf); + cp = (char *)buf; + string_unescape_any_inplace(cp); - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); switch (param->var_type) { case VAR_NUM: case VAR_TIME: @@ -617,61 +638,54 @@ ssize_t spk_var_store(struct kobject *kobj, struct kobj_attribute *attr, len = E_INC; else len = E_SET; - speakup_s2i(cp, &value); - ret = spk_set_num_var(value, param, len); - if (ret == E_RANGE) { + if (kstrtol(cp, 10, &value) == 0) + ret = spk_set_num_var(value, param, len); + else + pr_warn("overflow or parsing error has occurred"); + if (ret == -ERANGE) { var_data = param->data; pr_warn("value for %s out of range, expect %d to %d\n", - attr->attr.name, + param->name, var_data->u.n.low, var_data->u.n.high); } + + /* + * If voice was just changed, we might need to reset our default + * pitch and volume. + */ + if (param->var_id == VOICE && synth && + (ret == 0 || ret == -ERESTART)) { + var_data = param->data; + value = var_data->u.n.value; + spk_reset_default_value("pitch", synth->default_pitch, + value); + spk_reset_default_value("vol", synth->default_vol, + value); + } break; case VAR_STRING: - len = strlen(buf); - if ((len >= 1) && (buf[len - 1] == '\n')) + len = strlen(cp); + if ((len >= 1) && (cp[len - 1] == '\n')) --len; - if ((len >= 2) && (buf[0] == '"') && (buf[len - 1] == '"')) { - ++buf; + if ((len >= 2) && (cp[0] == '"') && (cp[len - 1] == '"')) { + ++cp; len -= 2; } - cp = (char *) buf; cp[len] = '\0'; - ret = spk_set_string_var(buf, param, len); - if (ret == E_TOOLONG) + ret = spk_set_string_var(cp, param, len); + if (ret == -E2BIG) pr_warn("value too long for %s\n", - attr->attr.name); + param->name); break; default: pr_warn("%s unknown type %d\n", param->name, (int)param->var_type); break; } - /* - * If voice was just changed, we might need to reset our default - * pitch and volume. - */ - if (strcmp(attr->attr.name, "voice") == 0) { - if (synth && synth->default_pitch) { - param = spk_var_header_by_name("pitch"); - if (param) { - spk_set_num_var(synth->default_pitch[value], - param, E_NEW_DEFAULT); - spk_set_num_var(0, param, E_DEFAULT); - } - } - if (synth && synth->default_vol) { - param = spk_var_header_by_name("vol"); - if (param) { - spk_set_num_var(synth->default_vol[value], - param, E_NEW_DEFAULT); - spk_set_num_var(0, param, E_DEFAULT); - } - } - } - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); - if (ret == SET_DEFAULT) - pr_info("%s reset to default value\n", attr->attr.name); + if (ret == -ERESTART) + pr_info("%s reset to default value\n", param->name); return count; } EXPORT_SYMBOL_GPL(spk_var_store); @@ -816,9 +830,9 @@ static ssize_t message_show(struct kobject *kobj, unsigned long flags; BUG_ON(!group); - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); retval = message_show_helper(buf, group->start, group->end); - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); return retval; } @@ -837,75 +851,75 @@ static ssize_t message_store(struct kobject *kobj, struct kobj_attribute *attr, * Declare the attributes. */ static struct kobj_attribute keymap_attribute = - __ATTR(keymap, ROOT_W, keymap_show, keymap_store); + __ATTR_RW(keymap); static struct kobj_attribute silent_attribute = - __ATTR(silent, USER_W, NULL, silent_store); + __ATTR_WO(silent); static struct kobj_attribute synth_attribute = - __ATTR(synth, USER_RW, synth_show, synth_store); + __ATTR_RW(synth); static struct kobj_attribute synth_direct_attribute = - __ATTR(synth_direct, USER_W, NULL, synth_direct_store); + __ATTR_WO(synth_direct); static struct kobj_attribute version_attribute = __ATTR_RO(version); static struct kobj_attribute delimiters_attribute = - __ATTR(delimiters, USER_RW, punc_show, punc_store); + __ATTR(delimiters, S_IWUSR|S_IRUGO, punc_show, punc_store); static struct kobj_attribute ex_num_attribute = - __ATTR(ex_num, USER_RW, punc_show, punc_store); + __ATTR(ex_num, S_IWUSR|S_IRUGO, punc_show, punc_store); static struct kobj_attribute punc_all_attribute = - __ATTR(punc_all, USER_RW, punc_show, punc_store); + __ATTR(punc_all, S_IWUSR|S_IRUGO, punc_show, punc_store); static struct kobj_attribute punc_most_attribute = - __ATTR(punc_most, USER_RW, punc_show, punc_store); + __ATTR(punc_most, S_IWUSR|S_IRUGO, punc_show, punc_store); static struct kobj_attribute punc_some_attribute = - __ATTR(punc_some, USER_RW, punc_show, punc_store); + __ATTR(punc_some, S_IWUSR|S_IRUGO, punc_show, punc_store); static struct kobj_attribute repeats_attribute = - __ATTR(repeats, USER_RW, punc_show, punc_store); + __ATTR(repeats, S_IWUSR|S_IRUGO, punc_show, punc_store); static struct kobj_attribute attrib_bleep_attribute = - __ATTR(attrib_bleep, USER_RW, spk_var_show, spk_var_store); + __ATTR(attrib_bleep, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute bell_pos_attribute = - __ATTR(bell_pos, USER_RW, spk_var_show, spk_var_store); + __ATTR(bell_pos, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute bleep_time_attribute = - __ATTR(bleep_time, USER_RW, spk_var_show, spk_var_store); + __ATTR(bleep_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute bleeps_attribute = - __ATTR(bleeps, USER_RW, spk_var_show, spk_var_store); + __ATTR(bleeps, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute cursor_time_attribute = - __ATTR(cursor_time, USER_RW, spk_var_show, spk_var_store); + __ATTR(cursor_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute key_echo_attribute = - __ATTR(key_echo, USER_RW, spk_var_show, spk_var_store); + __ATTR(key_echo, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute no_interrupt_attribute = - __ATTR(no_interrupt, USER_RW, spk_var_show, spk_var_store); + __ATTR(no_interrupt, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute punc_level_attribute = - __ATTR(punc_level, USER_RW, spk_var_show, spk_var_store); + __ATTR(punc_level, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute reading_punc_attribute = - __ATTR(reading_punc, USER_RW, spk_var_show, spk_var_store); + __ATTR(reading_punc, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute say_control_attribute = - __ATTR(say_control, USER_RW, spk_var_show, spk_var_store); + __ATTR(say_control, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute say_word_ctl_attribute = - __ATTR(say_word_ctl, USER_RW, spk_var_show, spk_var_store); + __ATTR(say_word_ctl, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute spell_delay_attribute = - __ATTR(spell_delay, USER_RW, spk_var_show, spk_var_store); + __ATTR(spell_delay, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); /* * These attributes are i18n related. */ static struct kobj_attribute announcements_attribute = - __ATTR(announcements, USER_RW, message_show, message_store); + __ATTR(announcements, S_IWUSR|S_IRUGO, message_show, message_store); static struct kobj_attribute characters_attribute = - __ATTR(characters, USER_RW, chars_chartab_show, chars_chartab_store); + __ATTR(characters, S_IWUSR|S_IRUGO, chars_chartab_show, chars_chartab_store); static struct kobj_attribute chartab_attribute = - __ATTR(chartab, USER_RW, chars_chartab_show, chars_chartab_store); + __ATTR(chartab, S_IWUSR|S_IRUGO, chars_chartab_show, chars_chartab_store); static struct kobj_attribute ctl_keys_attribute = - __ATTR(ctl_keys, USER_RW, message_show, message_store); + __ATTR(ctl_keys, S_IWUSR|S_IRUGO, message_show, message_store); static struct kobj_attribute colors_attribute = - __ATTR(colors, USER_RW, message_show, message_store); + __ATTR(colors, S_IWUSR|S_IRUGO, message_show, message_store); static struct kobj_attribute formatted_attribute = - __ATTR(formatted, USER_RW, message_show, message_store); + __ATTR(formatted, S_IWUSR|S_IRUGO, message_show, message_store); static struct kobj_attribute function_names_attribute = - __ATTR(function_names, USER_RW, message_show, message_store); + __ATTR(function_names, S_IWUSR|S_IRUGO, message_show, message_store); static struct kobj_attribute key_names_attribute = - __ATTR(key_names, USER_RW, message_show, message_store); + __ATTR(key_names, S_IWUSR|S_IRUGO, message_show, message_store); static struct kobj_attribute states_attribute = - __ATTR(states, USER_RW, message_show, message_store); + __ATTR(states, S_IWUSR|S_IRUGO, message_show, message_store); /* * Create groups of attributes so that we can create and destroy them all diff --git a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c index 9916e94aa36..7de79d59a4c 100644 --- a/drivers/staging/speakup/main.c +++ b/drivers/staging/speakup/main.c @@ -37,8 +37,6 @@ #include <linux/input.h> #include <linux/kmod.h> -#include <linux/bootmem.h> /* for alloc_bootmem */ - /* speakup_*_selection */ #include <linux/module.h> #include <linux/sched.h> @@ -90,12 +88,13 @@ const struct st_bits_data spk_punc_info[] = { {"repeats", "()", CH_RPT}, {"extended numeric", "", B_EXNUM}, {"symbols", "", B_SYM}, - {0, 0} + {NULL, NULL} }; static char mark_cut_flag; #define MAX_KEY 160 -u_char *spk_our_keys[MAX_KEY], *spk_shift_table; +static u_char *spk_shift_table; +u_char *spk_our_keys[MAX_KEY]; u_char spk_key_buf[600]; const u_char spk_key_defaults[] = { #include "speakupmap.h" @@ -457,7 +456,7 @@ static void speak_char(u_char ch) synth_buffer_add(SPACE); } -static u16 get_char(struct vc_data *vc, u16 * pos, u_char * attribs) +static u16 get_char(struct vc_data *vc, u16 *pos, u_char *attribs) { u16 ch = ' '; if (vc && pos) { @@ -1129,7 +1128,7 @@ static void do_handle_shift(struct vc_data *vc, u_char value, char up_flag) unsigned long flags; if (synth == NULL || up_flag || spk_killed) return; - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); if (cursor_track == read_all_mode) { switch (value) { case KVAL(K_SHIFT): @@ -1151,20 +1150,20 @@ static void do_handle_shift(struct vc_data *vc, u_char value, char up_flag) } if (spk_say_ctrl && value < NUM_CTL_LABELS) synth_printf("%s", spk_msg_get(MSG_CTL_START + value)); - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); } static void do_handle_latin(struct vc_data *vc, u_char value, char up_flag) { unsigned long flags; - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); if (up_flag) { spk_lastkey = spk_keydown = 0; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); return; } if (synth == NULL || spk_killed) { - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); return; } spk_shut_up &= 0xfe; @@ -1173,7 +1172,7 @@ static void do_handle_latin(struct vc_data *vc, u_char value, char up_flag) spk_parked &= 0xfe; if (spk_key_echo == 2 && value >= MINECHOCHAR) speak_char(value); - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); } int spk_set_key_info(const u_char *key_info, u_char *k_buffer) @@ -1282,7 +1281,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 */ -int speakup_allocate(struct vc_data *vc) +static int speakup_allocate(struct vc_data *vc) { int vc_num; @@ -1299,7 +1298,7 @@ int speakup_allocate(struct vc_data *vc) return 0; } -void speakup_deallocate(struct vc_data *vc) +static void speakup_deallocate(struct vc_data *vc) { int vc_num; @@ -1449,21 +1448,21 @@ static void handle_cursor_read_all(struct vc_data *vc, int command) static int pre_handle_cursor(struct vc_data *vc, u_char value, char up_flag) { unsigned long flags; - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); if (cursor_track == read_all_mode) { spk_parked &= 0xfe; if (synth == NULL || up_flag || spk_shut_up) { - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); return NOTIFY_STOP; } del_timer(&cursor_timer); spk_shut_up &= 0xfe; spk_do_flush(); start_read_all_timer(vc, value + 1); - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); return NOTIFY_STOP; } - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); return NOTIFY_OK; } @@ -1472,10 +1471,10 @@ static void do_handle_cursor(struct vc_data *vc, u_char value, char up_flag) unsigned long flags; struct var_t *cursor_timeout; - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); spk_parked &= 0xfe; if (synth == NULL || up_flag || spk_shut_up || cursor_track == CT_Off) { - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); return; } spk_shut_up &= 0xfe; @@ -1494,7 +1493,7 @@ static void do_handle_cursor(struct vc_data *vc, u_char value, char up_flag) cursor_timeout = spk_get_var(CURSOR_TIME); mod_timer(&cursor_timer, jiffies + msecs_to_jiffies(cursor_timeout->u.n.value)); - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); } static void update_color_buffer(struct vc_data *vc, const char *ic, int len) @@ -1619,7 +1618,7 @@ static void cursor_done(u_long data) struct vc_data *vc = vc_cons[cursor_con].d; unsigned long flags; del_timer(&cursor_timer); - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); if (cursor_con != fg_console) { is_cursor = 0; goto out; @@ -1650,7 +1649,7 @@ static void cursor_done(u_long data) say_char(vc); spk_keydown = is_cursor = 0; out: - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); } /* called by: vt_notifier_call() */ @@ -1659,13 +1658,13 @@ static void speakup_bs(struct vc_data *vc) unsigned long flags; if (!speakup_console[vc->vc_num]) return; - if (!spk_trylock(flags)) + if (!spin_trylock_irqsave(&speakup_info.spinlock, flags)) /* Speakup output, discard */ return; if (!spk_parked) speakup_date(vc); if (spk_shut_up || synth == NULL) { - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); return; } if (vc->vc_num == fg_console && spk_keydown) { @@ -1673,7 +1672,7 @@ static void speakup_bs(struct vc_data *vc) if (!is_cursor) say_char(vc); } - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); } /* called by: vt_notifier_call() */ @@ -1682,7 +1681,7 @@ static void speakup_con_write(struct vc_data *vc, const char *str, int len) unsigned long flags; if ((vc->vc_num != fg_console) || spk_shut_up || synth == NULL) return; - if (!spk_trylock(flags)) + if (!spin_trylock_irqsave(&speakup_info.spinlock, flags)) /* Speakup output, discard */ return; if (spk_bell_pos && spk_keydown && (vc->vc_x == spk_bell_pos - 1)) @@ -1690,31 +1689,31 @@ static void speakup_con_write(struct vc_data *vc, const char *str, int len) if ((is_cursor) || (cursor_track == read_all_mode)) { if (cursor_track == CT_Highlight) update_color_buffer(vc, str, len); - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); return; } if (win_enabled) { if (vc->vc_x >= win_left && vc->vc_x <= win_right && vc->vc_y >= win_top && vc->vc_y <= win_bottom) { - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); return; } } spkup_write(str, len); - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); } -void speakup_con_update(struct vc_data *vc) +static void speakup_con_update(struct vc_data *vc) { unsigned long flags; if (speakup_console[vc->vc_num] == NULL || spk_parked) return; - if (!spk_trylock(flags)) + if (!spin_trylock_irqsave(&speakup_info.spinlock, flags)) /* Speakup output, discard */ return; speakup_date(vc); - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); } static void do_handle_spec(struct vc_data *vc, u_char value, char up_flag) @@ -1724,7 +1723,7 @@ static void do_handle_spec(struct vc_data *vc, u_char value, char up_flag) char *label; if (synth == NULL || up_flag || spk_killed) return; - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); spk_shut_up &= 0xfe; if (spk_no_intr) spk_do_flush(); @@ -1745,13 +1744,13 @@ static void do_handle_spec(struct vc_data *vc, u_char value, char up_flag) break; default: spk_parked &= 0xfe; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); return; } if (on_off < 2) synth_printf("%s %s\n", label, spk_msg_get(MSG_STATUS_START + on_off)); - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); } static int inc_dec_var(u_char value) @@ -1856,8 +1855,9 @@ static int handle_goto(struct vc_data *vc, u_char type, u_char ch, u_short key) { static u_char goto_buf[8]; static int num; - int maxlen, go_pos; + int maxlen; char *cp; + if (type == KT_SPKUP && ch == SPEAKUP_GOTO) goto do_goto; if (type == KT_LATIN && ch == '\n') @@ -1892,25 +1892,24 @@ oops: spk_special_handler = NULL; return 1; } - cp = speakup_s2i(goto_buf, &go_pos); - goto_pos = (u_long) go_pos; + + goto_pos = simple_strtoul(goto_buf, &cp, 10); + if (*cp == 'x') { if (*goto_buf < '0') goto_pos += spk_x; - else + else if (goto_pos > 0) goto_pos--; - if (goto_pos < 0) - goto_pos = 0; + if (goto_pos >= vc->vc_cols) goto_pos = vc->vc_cols - 1; goto_x = 1; } else { if (*goto_buf < '0') goto_pos += spk_y; - else + else if (goto_pos > 0) goto_pos--; - if (goto_pos < 0) - goto_pos = 0; + if (goto_pos >= vc->vc_rows) goto_pos = vc->vc_rows - 1; goto_x = 0; @@ -1964,7 +1963,7 @@ static void speakup_lock(struct vc_data *vc) } typedef void (*spkup_hand) (struct vc_data *); -spkup_hand spkup_handler[] = { +static spkup_hand spkup_handler[] = { /* must be ordered same as defines in speakup.h */ do_nothing, speakup_goto, speech_kill, speakup_shut_up, speakup_cut, speakup_paste, say_first_char, say_last_char, @@ -2002,7 +2001,7 @@ static void do_spkup(struct vc_data *vc, u_char value) static const char *pad_chars = "0123456789+-*/\015,.?()"; -int +static int speakup_key(struct vc_data *vc, int shift_state, int keycode, u_short keysym, int up_flag) { @@ -2015,7 +2014,7 @@ speakup_key(struct vc_data *vc, int shift_state, int keycode, u_short keysym, if (synth == NULL) return 0; - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); tty = vc->port.tty; if (type >= 0xf0) type -= 0xf0; @@ -2033,7 +2032,7 @@ speakup_key(struct vc_data *vc, int shift_state, int keycode, u_short keysym, if (keycode >= MAX_KEY) goto no_map; key_info = spk_our_keys[keycode]; - if (key_info == 0) + if (!key_info) goto no_map; /* Check valid read all mode keys */ if ((cursor_track == read_all_mode) && (!up_flag)) { @@ -2114,7 +2113,7 @@ no_map: } last_keycode = 0; out: - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); return ret; } @@ -2219,6 +2218,7 @@ static void __exit speakup_exit(void) unregister_keyboard_notifier(&keyboard_notifier_block); unregister_vt_notifier(&vt_notifier_block); speakup_unregister_devsynth(); + speakup_cancel_paste(); del_timer(&cursor_timer); kthread_stop(speakup_task); speakup_task = NULL; @@ -2265,7 +2265,7 @@ static int __init speakup_init(void) (var->var_id >= 0) && (var->var_id < MAXVARS); var++) speakup_register_var(var); for (i = 1; spk_punc_info[i].mask != 0; i++) - spk_set_mask_bits(0, i, 2); + spk_set_mask_bits(NULL, i, 2); spk_set_key_info(spk_key_defaults, spk_key_buf); diff --git a/drivers/staging/speakup/selection.c b/drivers/staging/speakup/selection.c index 775af26b991..ca04d3669ac 100644 --- a/drivers/staging/speakup/selection.c +++ b/drivers/staging/speakup/selection.c @@ -4,6 +4,10 @@ #include <linux/sched.h> #include <linux/device.h> /* for dev_warn */ #include <linux/selection.h> +#include <linux/workqueue.h> +#include <linux/tty.h> +#include <linux/tty_flip.h> +#include <asm/cmpxchg.h> #include "speakup.h" @@ -14,7 +18,7 @@ unsigned short spk_xs, spk_ys, spk_xe, spk_ye; /* our region points */ /* Variables for selection control. */ -/* must not be disallocated */ +/* must not be deallocated */ struct vc_data *spk_sel_cons; /* cleared by clear_selection */ static int sel_start = -1; @@ -121,31 +125,61 @@ int speakup_set_selection(struct tty_struct *tty) return 0; } -/* TODO: move to some helper thread, probably. That'd fix having to check for - * in_atomic(). */ -int speakup_paste_selection(struct tty_struct *tty) +struct speakup_paste_work { + struct work_struct work; + struct tty_struct *tty; +}; + +static void __speakup_paste_selection(struct work_struct *work) { + struct speakup_paste_work *spw = + container_of(work, struct speakup_paste_work, work); + struct tty_struct *tty = xchg(&spw->tty, NULL); struct vc_data *vc = (struct vc_data *) tty->driver_data; int pasted = 0, count; + struct tty_ldisc *ld; DECLARE_WAITQUEUE(wait, current); + + ld = tty_ldisc_ref_wait(tty); + tty_buffer_lock_exclusive(&vc->port); + add_wait_queue(&vc->paste_wait, &wait); while (sel_buffer && sel_buffer_lth > pasted) { set_current_state(TASK_INTERRUPTIBLE); if (test_bit(TTY_THROTTLED, &tty->flags)) { - if (in_atomic()) - /* if we are in an interrupt handler, abort */ - break; schedule(); continue; } count = sel_buffer_lth - pasted; - count = min_t(int, count, tty->receive_room); - tty->ldisc->ops->receive_buf(tty, sel_buffer + pasted, - NULL, count); + count = tty_ldisc_receive_buf(ld, sel_buffer + pasted, NULL, + count); pasted += count; } remove_wait_queue(&vc->paste_wait, &wait); current->state = TASK_RUNNING; + + tty_buffer_unlock_exclusive(&vc->port); + tty_ldisc_deref(ld); + tty_kref_put(tty); +} + +static struct speakup_paste_work speakup_paste_work = { + .work = __WORK_INITIALIZER(speakup_paste_work.work, + __speakup_paste_selection) +}; + +int speakup_paste_selection(struct tty_struct *tty) +{ + if (cmpxchg(&speakup_paste_work.tty, NULL, tty) != NULL) + return -EBUSY; + + tty_kref_get(tty); + schedule_work_on(WORK_CPU_UNBOUND, &speakup_paste_work.work); return 0; } +void speakup_cancel_paste(void) +{ + cancel_work_sync(&speakup_paste_work.work); + tty_kref_put(speakup_paste_work.tty); +} diff --git a/drivers/staging/speakup/serialio.c b/drivers/staging/speakup/serialio.c index e4d27aa2898..c62d74c4790 100644 --- a/drivers/staging/speakup/serialio.c +++ b/drivers/staging/speakup/serialio.c @@ -6,6 +6,10 @@ #include "spk_priv.h" #include "serialio.h" +#ifndef SERIAL_PORT_DFNS +#define SERIAL_PORT_DFNS +#endif + static void start_serial_interrupt(int irq); static const struct old_serial_port rs_table[] = { @@ -36,7 +40,7 @@ const struct old_serial_port *spk_serial_init(int index) cval |= UART_LCR_EPAR; if (synth_request_region(ser->port, 8)) { /* try to take it back. */ - printk(KERN_INFO "Ports not available, trying to steal them\n"); + pr_info("Ports not available, trying to steal them\n"); __release_region(&ioport_resource, ser->port, 8); err = synth_request_region(ser->port, 8); if (err) { @@ -79,7 +83,7 @@ static irqreturn_t synth_readbuf_handler(int irq, void *dev_id) /*printk(KERN_ERR "in irq\n"); */ /*pr_warn("in IRQ\n"); */ int c; - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); while (inb_p(speakup_info.port_tts + UART_LSR) & UART_LSR_DR) { c = inb_p(speakup_info.port_tts+UART_RX); @@ -87,7 +91,7 @@ static irqreturn_t synth_readbuf_handler(int irq, void *dev_id) /*printk(KERN_ERR "c = %d\n", c); */ /*pr_warn("C = %d\n", c); */ } - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); return IRQ_HANDLED; } @@ -102,7 +106,7 @@ static void start_serial_interrupt(int irq) "serial", (void *) synth_readbuf_handler); if (rv) - printk(KERN_ERR "Unable to request Speakup serial I R Q\n"); + pr_err("Unable to request Speakup serial I R Q\n"); /* Set MCR */ outb(UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2, speakup_info.port_tts + UART_MCR); diff --git a/drivers/staging/speakup/serialio.h b/drivers/staging/speakup/serialio.h index 55d68b5ad16..0a937732a19 100644 --- a/drivers/staging/speakup/serialio.h +++ b/drivers/staging/speakup/serialio.h @@ -36,30 +36,4 @@ struct old_serial_port { #define spk_serial_tx_busy() ((inb(speakup_info.port_tts + UART_LSR) & BOTH_EMPTY) != BOTH_EMPTY) -/* 2.6.22 doesn't have them any more, hardcode it for now (these values should - * be fine for 99% cases) */ -#ifndef BASE_BAUD -#define BASE_BAUD (1843200 / 16) -#endif -#ifndef STD_COM_FLAGS -#ifdef CONFIG_SERIAL_DETECT_IRQ -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ) -#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ) -#else -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) -#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF -#endif -#endif -#ifndef SERIAL_PORT_DFNS -#define SERIAL_PORT_DFNS \ - /* UART CLK PORT IRQ FLAGS */ \ - { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \ - { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \ - { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \ - { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */ -#endif -#ifndef IRQF_SHARED -#define IRQF_SHARED SA_SHIRQ -#endif - #endif diff --git a/drivers/staging/speakup/speakup.h b/drivers/staging/speakup/speakup.h index 22f0fbb85f4..898dce5e124 100644 --- a/drivers/staging/speakup/speakup.h +++ b/drivers/staging/speakup/speakup.h @@ -12,8 +12,6 @@ /* proc permissions */ #define USER_R (S_IFREG|S_IRUGO) #define USER_W (S_IFREG|S_IWUGO) -#define USER_RW (S_IFREG|S_IRUGO|S_IWUGO) -#define ROOT_W (S_IFREG|S_IRUGO|S_IWUSR) #define TOGGLE_0 .u.n = {NULL, 0, 0, 1, 0, 0, NULL } #define TOGGLE_1 .u.n = {NULL, 1, 0, 1, 0, 0, NULL } @@ -44,11 +42,6 @@ #define IS_CHAR(x, type) (spk_chartab[((u_char)x)]&type) #define IS_TYPE(x, type) ((spk_chartab[((u_char)x)]&type) == type) -#define SET_DEFAULT -4 -#define E_RANGE -3 -#define E_TOOLONG -2 -#define E_UNDEF -1 - extern int speakup_thread(void *data); extern void spk_reset_default_chars(void); extern void spk_reset_default_chartab(void); @@ -58,9 +51,7 @@ void spk_reset_index_count(int sc); void spk_get_index_count(int *linecount, int *sentcount); extern int spk_set_key_info(const u_char *key_info, u_char *k_buffer); extern char *spk_strlwr(char *s); -extern char *speakup_s2i(char *start, int *dest); extern char *spk_s2uchar(char *start, char *dest); -extern char *spk_xlate(char *s); extern int speakup_kobj_init(void); extern void speakup_kobj_exit(void); extern int spk_chartab_get_value(char *keyword); @@ -84,6 +75,7 @@ extern void synth_buffer_clear(void); extern void speakup_clear_selection(void); extern int speakup_set_selection(struct tty_struct *tty); extern int speakup_paste_selection(struct tty_struct *tty); +extern void speakup_cancel_paste(void); extern void speakup_register_devsynth(void); extern void speakup_unregister_devsynth(void); extern void synth_write(const char *buf, size_t count); diff --git a/drivers/staging/speakup/speakup_acntpc.c b/drivers/staging/speakup/speakup_acntpc.c index 1c1f0d56044..31f952b9049 100644 --- a/drivers/staging/speakup/speakup_acntpc.c +++ b/drivers/staging/speakup/speakup_acntpc.c @@ -62,28 +62,28 @@ static struct var_t vars[] = { * These attributes will appear in /sys/accessibility/speakup/acntpc. */ static struct kobj_attribute caps_start_attribute = - __ATTR(caps_start, USER_RW, spk_var_show, spk_var_store); + __ATTR(caps_start, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute caps_stop_attribute = - __ATTR(caps_stop, USER_RW, spk_var_show, spk_var_store); + __ATTR(caps_stop, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute pitch_attribute = - __ATTR(pitch, USER_RW, spk_var_show, spk_var_store); + __ATTR(pitch, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute rate_attribute = - __ATTR(rate, USER_RW, spk_var_show, spk_var_store); + __ATTR(rate, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute tone_attribute = - __ATTR(tone, USER_RW, spk_var_show, spk_var_store); + __ATTR(tone, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute vol_attribute = - __ATTR(vol, USER_RW, spk_var_show, spk_var_store); + __ATTR(vol, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute delay_time_attribute = - __ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute direct_attribute = - __ATTR(direct, USER_RW, spk_var_show, spk_var_store); + __ATTR(direct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute full_time_attribute = - __ATTR(full_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute jiffy_delta_attribute = - __ATTR(jiffy_delta, ROOT_W, spk_var_show, spk_var_store); + __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute trigger_time_attribute = - __ATTR(trigger_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); /* * Create a group of attributes so that we can create and destroy them all @@ -166,7 +166,7 @@ static const char *synth_immediate(struct spk_synth *synth, const char *buf) outb_p(ch, speakup_info.port_tts); buf++; } - return 0; + return NULL; } static void do_catch_up(struct spk_synth *synth) @@ -186,26 +186,26 @@ static void do_catch_up(struct spk_synth *synth) delay_time = spk_get_var(DELAY); full_time = spk_get_var(FULL); - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); jiffy_delta_val = jiffy_delta->u.n.value; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); jiff_max = jiffies + jiffy_delta_val; while (!kthread_should_stop()) { - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); if (speakup_info.flushing) { speakup_info.flushing = 0; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); synth->flush(synth); continue; } if (synth_buffer_empty()) { - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); break; } set_current_state(TASK_INTERRUPTIBLE); full_time_val = full_time->u.n.value; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); if (synth_full()) { schedule_timeout(msecs_to_jiffies(full_time_val)); continue; @@ -217,13 +217,13 @@ static void do_catch_up(struct spk_synth *synth) break; udelay(1); } - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); ch = synth_buffer_getc(); - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); if (ch == '\n') ch = PROCSPEECH; outb_p(ch, speakup_info.port_tts); - if (jiffies >= jiff_max && ch == SPACE) { + if (time_after_eq(jiffies, jiff_max) && ch == SPACE) { timeout = SPK_XMITR_TIMEOUT; while (synth_writable()) { if (!--timeout) @@ -231,10 +231,10 @@ static void do_catch_up(struct spk_synth *synth) udelay(1); } outb_p(PROCSPEECH, speakup_info.port_tts); - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); jiffy_delta_val = jiffy_delta->u.n.value; delay_time_val = delay_time->u.n.value; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); schedule_timeout(msecs_to_jiffies(delay_time_val)); jiff_max = jiffies+jiffy_delta_val; } diff --git a/drivers/staging/speakup/speakup_acntsa.c b/drivers/staging/speakup/speakup_acntsa.c index 22a8b729109..3f2b5698a3d 100644 --- a/drivers/staging/speakup/speakup_acntsa.c +++ b/drivers/staging/speakup/speakup_acntsa.c @@ -47,28 +47,28 @@ static struct var_t vars[] = { * These attributes will appear in /sys/accessibility/speakup/acntsa. */ static struct kobj_attribute caps_start_attribute = - __ATTR(caps_start, USER_RW, spk_var_show, spk_var_store); + __ATTR(caps_start, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute caps_stop_attribute = - __ATTR(caps_stop, USER_RW, spk_var_show, spk_var_store); + __ATTR(caps_stop, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute pitch_attribute = - __ATTR(pitch, USER_RW, spk_var_show, spk_var_store); + __ATTR(pitch, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute rate_attribute = - __ATTR(rate, USER_RW, spk_var_show, spk_var_store); + __ATTR(rate, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute tone_attribute = - __ATTR(tone, USER_RW, spk_var_show, spk_var_store); + __ATTR(tone, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute vol_attribute = - __ATTR(vol, USER_RW, spk_var_show, spk_var_store); + __ATTR(vol, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute delay_time_attribute = - __ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute direct_attribute = - __ATTR(direct, USER_RW, spk_var_show, spk_var_store); + __ATTR(direct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute full_time_attribute = - __ATTR(full_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute jiffy_delta_attribute = - __ATTR(jiffy_delta, ROOT_W, spk_var_show, spk_var_store); + __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute trigger_time_attribute = - __ATTR(trigger_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); /* * Create a group of attributes so that we can create and destroy them all diff --git a/drivers/staging/speakup/speakup_apollo.c b/drivers/staging/speakup/speakup_apollo.c index 3e450ccbda6..678b263e551 100644 --- a/drivers/staging/speakup/speakup_apollo.c +++ b/drivers/staging/speakup/speakup_apollo.c @@ -53,30 +53,30 @@ static struct var_t vars[] = { * These attributes will appear in /sys/accessibility/speakup/apollo. */ static struct kobj_attribute caps_start_attribute = - __ATTR(caps_start, USER_RW, spk_var_show, spk_var_store); + __ATTR(caps_start, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute caps_stop_attribute = - __ATTR(caps_stop, USER_RW, spk_var_show, spk_var_store); + __ATTR(caps_stop, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute lang_attribute = - __ATTR(lang, USER_RW, spk_var_show, spk_var_store); + __ATTR(lang, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute pitch_attribute = - __ATTR(pitch, USER_RW, spk_var_show, spk_var_store); + __ATTR(pitch, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute rate_attribute = - __ATTR(rate, USER_RW, spk_var_show, spk_var_store); + __ATTR(rate, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute voice_attribute = - __ATTR(voice, USER_RW, spk_var_show, spk_var_store); + __ATTR(voice, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute vol_attribute = - __ATTR(vol, USER_RW, spk_var_show, spk_var_store); + __ATTR(vol, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute delay_time_attribute = - __ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute direct_attribute = - __ATTR(direct, USER_RW, spk_var_show, spk_var_store); + __ATTR(direct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute full_time_attribute = - __ATTR(full_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute jiffy_delta_attribute = - __ATTR(jiffy_delta, ROOT_W, spk_var_show, spk_var_store); + __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute trigger_time_attribute = - __ATTR(trigger_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); /* * Create a group of attributes so that we can create and destroy them all @@ -148,30 +148,30 @@ static void do_catch_up(struct spk_synth *synth) jiffy_delta = spk_get_var(JIFFY); delay_time = spk_get_var(DELAY); full_time = spk_get_var(FULL); - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); jiffy_delta_val = jiffy_delta->u.n.value; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); jiff_max = jiffies + jiffy_delta_val; while (!kthread_should_stop()) { - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); jiffy_delta_val = jiffy_delta->u.n.value; full_time_val = full_time->u.n.value; delay_time_val = delay_time->u.n.value; if (speakup_info.flushing) { speakup_info.flushing = 0; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); synth->flush(synth); continue; } if (synth_buffer_empty()) { - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); break; } ch = synth_buffer_peek(); set_current_state(TASK_INTERRUPTIBLE); full_time_val = full_time->u.n.value; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); if (!spk_serial_out(ch)) { outb(UART_MCR_DTR, speakup_info.port_tts + UART_MCR); outb(UART_MCR_DTR | UART_MCR_RTS, @@ -179,12 +179,12 @@ static void do_catch_up(struct spk_synth *synth) schedule_timeout(msecs_to_jiffies(full_time_val)); continue; } - if ((jiffies >= jiff_max) && (ch == SPACE)) { - spk_lock(flags); + if (time_after_eq(jiffies, jiff_max) && (ch == SPACE)) { + spin_lock_irqsave(&speakup_info.spinlock, flags); jiffy_delta_val = jiffy_delta->u.n.value; full_time_val = full_time->u.n.value; delay_time_val = delay_time->u.n.value; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); if (spk_serial_out(synth->procspeech)) schedule_timeout(msecs_to_jiffies (delay_time_val)); @@ -194,9 +194,9 @@ static void do_catch_up(struct spk_synth *synth) jiff_max = jiffies + jiffy_delta_val; } set_current_state(TASK_RUNNING); - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); synth_buffer_getc(); - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); } spk_serial_out(PROCSPEECH); } diff --git a/drivers/staging/speakup/speakup_audptr.c b/drivers/staging/speakup/speakup_audptr.c index 3508aee98ab..362f9747e48 100644 --- a/drivers/staging/speakup/speakup_audptr.c +++ b/drivers/staging/speakup/speakup_audptr.c @@ -39,7 +39,7 @@ static struct var_t vars[] = { { RATE, .u.n = {"\x05[r%d]", 10, 0, 20, 100, -10, NULL } }, { PITCH, .u.n = {"\x05[f%d]", 80, 39, 4500, 0, 0, NULL } }, { VOL, .u.n = {"\x05[g%d]", 21, 0, 40, 0, 0, NULL } }, - { TONE, .u.n = {"\x05[s%d]", 9, 0, 63, 0, 0, 0 } }, + { TONE, .u.n = {"\x05[s%d]", 9, 0, 63, 0, 0, NULL } }, { PUNCT, .u.n = {"\x05[A%c]", 0, 0, 3, 0, 0, "nmsa" } }, { DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL } }, V_LAST_VAR @@ -49,30 +49,30 @@ static struct var_t vars[] = { * These attributes will appear in /sys/accessibility/speakup/audptr. */ static struct kobj_attribute caps_start_attribute = - __ATTR(caps_start, USER_RW, spk_var_show, spk_var_store); + __ATTR(caps_start, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute caps_stop_attribute = - __ATTR(caps_stop, USER_RW, spk_var_show, spk_var_store); + __ATTR(caps_stop, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute pitch_attribute = - __ATTR(pitch, USER_RW, spk_var_show, spk_var_store); + __ATTR(pitch, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute punct_attribute = - __ATTR(punct, USER_RW, spk_var_show, spk_var_store); + __ATTR(punct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute rate_attribute = - __ATTR(rate, USER_RW, spk_var_show, spk_var_store); + __ATTR(rate, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute tone_attribute = - __ATTR(tone, USER_RW, spk_var_show, spk_var_store); + __ATTR(tone, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute vol_attribute = - __ATTR(vol, USER_RW, spk_var_show, spk_var_store); + __ATTR(vol, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute delay_time_attribute = - __ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute direct_attribute = - __ATTR(direct, USER_RW, spk_var_show, spk_var_store); + __ATTR(direct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute full_time_attribute = - __ATTR(full_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute jiffy_delta_attribute = - __ATTR(jiffy_delta, ROOT_W, spk_var_show, spk_var_store); + __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute trigger_time_attribute = - __ATTR(trigger_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); /* * Create a group of attributes so that we can create and destroy them all diff --git a/drivers/staging/speakup/speakup_bns.c b/drivers/staging/speakup/speakup_bns.c index 4bfe3d458dc..2f070282a85 100644 --- a/drivers/staging/speakup/speakup_bns.c +++ b/drivers/staging/speakup/speakup_bns.c @@ -44,28 +44,28 @@ static struct var_t vars[] = { * These attributes will appear in /sys/accessibility/speakup/bns. */ static struct kobj_attribute caps_start_attribute = - __ATTR(caps_start, USER_RW, spk_var_show, spk_var_store); + __ATTR(caps_start, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute caps_stop_attribute = - __ATTR(caps_stop, USER_RW, spk_var_show, spk_var_store); + __ATTR(caps_stop, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute pitch_attribute = - __ATTR(pitch, USER_RW, spk_var_show, spk_var_store); + __ATTR(pitch, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute rate_attribute = - __ATTR(rate, USER_RW, spk_var_show, spk_var_store); + __ATTR(rate, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute tone_attribute = - __ATTR(tone, USER_RW, spk_var_show, spk_var_store); + __ATTR(tone, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute vol_attribute = - __ATTR(vol, USER_RW, spk_var_show, spk_var_store); + __ATTR(vol, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute delay_time_attribute = - __ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute direct_attribute = - __ATTR(direct, USER_RW, spk_var_show, spk_var_store); + __ATTR(direct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute full_time_attribute = - __ATTR(full_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute jiffy_delta_attribute = - __ATTR(jiffy_delta, ROOT_W, spk_var_show, spk_var_store); + __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute trigger_time_attribute = - __ATTR(trigger_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); /* * Create a group of attributes so that we can create and destroy them all diff --git a/drivers/staging/speakup/speakup_decext.c b/drivers/staging/speakup/speakup_decext.c index d39a0de286f..67b7de1d8c7 100644 --- a/drivers/staging/speakup/speakup_decext.c +++ b/drivers/staging/speakup/speakup_decext.c @@ -70,30 +70,30 @@ static struct var_t vars[] = { * These attributes will appear in /sys/accessibility/speakup/decext. */ static struct kobj_attribute caps_start_attribute = - __ATTR(caps_start, USER_RW, spk_var_show, spk_var_store); + __ATTR(caps_start, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute caps_stop_attribute = - __ATTR(caps_stop, USER_RW, spk_var_show, spk_var_store); + __ATTR(caps_stop, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute pitch_attribute = - __ATTR(pitch, USER_RW, spk_var_show, spk_var_store); + __ATTR(pitch, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute punct_attribute = - __ATTR(punct, USER_RW, spk_var_show, spk_var_store); + __ATTR(punct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute rate_attribute = - __ATTR(rate, USER_RW, spk_var_show, spk_var_store); + __ATTR(rate, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute voice_attribute = - __ATTR(voice, USER_RW, spk_var_show, spk_var_store); + __ATTR(voice, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute vol_attribute = - __ATTR(vol, USER_RW, spk_var_show, spk_var_store); + __ATTR(vol, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute delay_time_attribute = - __ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute direct_attribute = - __ATTR(direct, USER_RW, spk_var_show, spk_var_store); + __ATTR(direct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute full_time_attribute = - __ATTR(full_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute jiffy_delta_attribute = - __ATTR(jiffy_delta, ROOT_W, spk_var_show, spk_var_store); + __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute trigger_time_attribute = - __ATTR(trigger_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); /* * Create a group of attributes so that we can create and destroy them all @@ -165,27 +165,27 @@ static void do_catch_up(struct spk_synth *synth) jiffy_delta = spk_get_var(JIFFY); delay_time = spk_get_var(DELAY); - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); jiffy_delta_val = jiffy_delta->u.n.value; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); jiff_max = jiffies + jiffy_delta_val; while (!kthread_should_stop()) { - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); if (speakup_info.flushing) { speakup_info.flushing = 0; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); synth->flush(synth); continue; } if (synth_buffer_empty()) { - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); break; } ch = synth_buffer_peek(); set_current_state(TASK_INTERRUPTIBLE); delay_time_val = delay_time->u.n.value; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); if (ch == '\n') ch = 0x0D; if (synth_full() || !spk_serial_out(ch)) { @@ -193,9 +193,9 @@ static void do_catch_up(struct spk_synth *synth) continue; } set_current_state(TASK_RUNNING); - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); synth_buffer_getc(); - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); if (ch == '[') in_escape = 1; else if (ch == ']') @@ -206,10 +206,10 @@ static void do_catch_up(struct spk_synth *synth) if (jiffies >= jiff_max) { if (!in_escape) spk_serial_out(PROCSPEECH); - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); jiffy_delta_val = jiffy_delta->u.n.value; delay_time_val = delay_time->u.n.value; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); schedule_timeout(msecs_to_jiffies (delay_time_val)); jiff_max = jiffies + jiffy_delta_val; diff --git a/drivers/staging/speakup/speakup_decpc.c b/drivers/staging/speakup/speakup_decpc.c index 6c88b55bdac..67678d8888c 100644 --- a/drivers/staging/speakup/speakup_decpc.c +++ b/drivers/staging/speakup/speakup_decpc.c @@ -164,30 +164,30 @@ static struct var_t vars[] = { * These attributes will appear in /sys/accessibility/speakup/decpc. */ static struct kobj_attribute caps_start_attribute = - __ATTR(caps_start, USER_RW, spk_var_show, spk_var_store); + __ATTR(caps_start, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute caps_stop_attribute = - __ATTR(caps_stop, USER_RW, spk_var_show, spk_var_store); + __ATTR(caps_stop, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute pitch_attribute = - __ATTR(pitch, USER_RW, spk_var_show, spk_var_store); + __ATTR(pitch, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute punct_attribute = - __ATTR(punct, USER_RW, spk_var_show, spk_var_store); + __ATTR(punct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute rate_attribute = - __ATTR(rate, USER_RW, spk_var_show, spk_var_store); + __ATTR(rate, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute voice_attribute = - __ATTR(voice, USER_RW, spk_var_show, spk_var_store); + __ATTR(voice, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute vol_attribute = - __ATTR(vol, USER_RW, spk_var_show, spk_var_store); + __ATTR(vol, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute delay_time_attribute = - __ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute direct_attribute = - __ATTR(direct, USER_RW, spk_var_show, spk_var_store); + __ATTR(direct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute full_time_attribute = - __ATTR(full_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute jiffy_delta_attribute = - __ATTR(jiffy_delta, ROOT_W, spk_var_show, spk_var_store); + __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute trigger_time_attribute = - __ATTR(trigger_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); /* * Create a group of attributes so that we can create and destroy them all @@ -377,27 +377,27 @@ static void do_catch_up(struct spk_synth *synth) jiffy_delta = spk_get_var(JIFFY); delay_time = spk_get_var(DELAY); - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); jiffy_delta_val = jiffy_delta->u.n.value; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); jiff_max = jiffies + jiffy_delta_val; while (!kthread_should_stop()) { - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); if (speakup_info.flushing) { speakup_info.flushing = 0; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); synth->flush(synth); continue; } if (synth_buffer_empty()) { - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); break; } ch = synth_buffer_peek(); set_current_state(TASK_INTERRUPTIBLE); delay_time_val = delay_time->u.n.value; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); if (ch == '\n') ch = 0x0D; if (dt_sendchar(ch)) { @@ -405,9 +405,9 @@ static void do_catch_up(struct spk_synth *synth) continue; } set_current_state(TASK_RUNNING); - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); synth_buffer_getc(); - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); if (ch == '[') in_escape = 1; else if (ch == ']') @@ -418,10 +418,10 @@ static void do_catch_up(struct spk_synth *synth) if (jiffies >= jiff_max) { if (!in_escape) dt_sendchar(PROCSPEECH); - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); jiffy_delta_val = jiffy_delta->u.n.value; delay_time_val = delay_time->u.n.value; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); schedule_timeout(msecs_to_jiffies (delay_time_val)); jiff_max = jiffies + jiffy_delta_val; @@ -444,7 +444,7 @@ static const char *synth_immediate(struct spk_synth *synth, const char *buf) return buf; buf++; } - return 0; + return NULL; } static int synth_probe(struct spk_synth *synth) diff --git a/drivers/staging/speakup/speakup_dectlk.c b/drivers/staging/speakup/speakup_dectlk.c index 0dd2eb96cb2..af848686be7 100644 --- a/drivers/staging/speakup/speakup_dectlk.c +++ b/drivers/staging/speakup/speakup_dectlk.c @@ -70,30 +70,30 @@ static struct var_t vars[] = { * These attributes will appear in /sys/accessibility/speakup/dectlk. */ static struct kobj_attribute caps_start_attribute = - __ATTR(caps_start, USER_RW, spk_var_show, spk_var_store); + __ATTR(caps_start, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute caps_stop_attribute = - __ATTR(caps_stop, USER_RW, spk_var_show, spk_var_store); + __ATTR(caps_stop, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute pitch_attribute = - __ATTR(pitch, USER_RW, spk_var_show, spk_var_store); + __ATTR(pitch, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute punct_attribute = - __ATTR(punct, USER_RW, spk_var_show, spk_var_store); + __ATTR(punct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute rate_attribute = - __ATTR(rate, USER_RW, spk_var_show, spk_var_store); + __ATTR(rate, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute voice_attribute = - __ATTR(voice, USER_RW, spk_var_show, spk_var_store); + __ATTR(voice, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute vol_attribute = - __ATTR(vol, USER_RW, spk_var_show, spk_var_store); + __ATTR(vol, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute delay_time_attribute = - __ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute direct_attribute = - __ATTR(direct, USER_RW, spk_var_show, spk_var_store); + __ATTR(direct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute full_time_attribute = - __ATTR(full_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute jiffy_delta_attribute = - __ATTR(jiffy_delta, ROOT_W, spk_var_show, spk_var_store); + __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute trigger_time_attribute = - __ATTR(trigger_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); /* * Create a group of attributes so that we can create and destroy them all @@ -216,9 +216,9 @@ static void do_catch_up(struct spk_synth *synth) jiffy_delta = spk_get_var(JIFFY); delay_time = spk_get_var(DELAY); - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); jiffy_delta_val = jiffy_delta->u.n.value; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); jiff_max = jiffies + jiffy_delta_val; while (!kthread_should_stop()) { @@ -234,22 +234,22 @@ static void do_catch_up(struct spk_synth *synth) is_flushing = 0; spin_unlock_irqrestore(&flush_lock, flags); - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); if (speakup_info.flushing) { speakup_info.flushing = 0; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); synth->flush(synth); continue; } if (synth_buffer_empty()) { - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); break; } ch = synth_buffer_peek(); set_current_state(TASK_INTERRUPTIBLE); delay_time_val = delay_time->u.n.value; synth_full_val = synth_full(); - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); if (ch == '\n') ch = 0x0D; if (synth_full_val || !spk_serial_out(ch)) { @@ -257,9 +257,9 @@ static void do_catch_up(struct spk_synth *synth) continue; } set_current_state(TASK_RUNNING); - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); synth_buffer_getc(); - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); if (ch == '[') in_escape = 1; else if (ch == ']') @@ -270,10 +270,12 @@ static void do_catch_up(struct spk_synth *synth) if (jiffies >= jiff_max) { if (!in_escape) spk_serial_out(PROCSPEECH); - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, + flags); jiffy_delta_val = jiffy_delta->u.n.value; delay_time_val = delay_time->u.n.value; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, + flags); schedule_timeout(msecs_to_jiffies (delay_time_val)); jiff_max = jiffies + jiffy_delta_val; diff --git a/drivers/staging/speakup/speakup_dtlk.c b/drivers/staging/speakup/speakup_dtlk.c index a9cefbd3ea9..98d1f497e4e 100644 --- a/drivers/staging/speakup/speakup_dtlk.c +++ b/drivers/staging/speakup/speakup_dtlk.c @@ -67,34 +67,34 @@ static struct var_t vars[] = { * These attributes will appear in /sys/accessibility/speakup/dtlk. */ static struct kobj_attribute caps_start_attribute = - __ATTR(caps_start, USER_RW, spk_var_show, spk_var_store); + __ATTR(caps_start, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute caps_stop_attribute = - __ATTR(caps_stop, USER_RW, spk_var_show, spk_var_store); + __ATTR(caps_stop, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute freq_attribute = - __ATTR(freq, USER_RW, spk_var_show, spk_var_store); + __ATTR(freq, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute pitch_attribute = - __ATTR(pitch, USER_RW, spk_var_show, spk_var_store); + __ATTR(pitch, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute punct_attribute = - __ATTR(punct, USER_RW, spk_var_show, spk_var_store); + __ATTR(punct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute rate_attribute = - __ATTR(rate, USER_RW, spk_var_show, spk_var_store); + __ATTR(rate, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute tone_attribute = - __ATTR(tone, USER_RW, spk_var_show, spk_var_store); + __ATTR(tone, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute voice_attribute = - __ATTR(voice, USER_RW, spk_var_show, spk_var_store); + __ATTR(voice, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute vol_attribute = - __ATTR(vol, USER_RW, spk_var_show, spk_var_store); + __ATTR(vol, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute delay_time_attribute = - __ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute direct_attribute = - __ATTR(direct, USER_RW, spk_var_show, spk_var_store); + __ATTR(direct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute full_time_attribute = - __ATTR(full_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute jiffy_delta_attribute = - __ATTR(jiffy_delta, ROOT_W, spk_var_show, spk_var_store); + __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute trigger_time_attribute = - __ATTR(trigger_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); /* * Create a group of attributes so that we can create and destroy them all @@ -200,42 +200,42 @@ static void do_catch_up(struct spk_synth *synth) jiffy_delta = spk_get_var(JIFFY); delay_time = spk_get_var(DELAY); - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); jiffy_delta_val = jiffy_delta->u.n.value; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); jiff_max = jiffies + jiffy_delta_val; while (!kthread_should_stop()) { - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); if (speakup_info.flushing) { speakup_info.flushing = 0; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); synth->flush(synth); continue; } if (synth_buffer_empty()) { - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); break; } set_current_state(TASK_INTERRUPTIBLE); delay_time_val = delay_time->u.n.value; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); if (synth_full()) { schedule_timeout(msecs_to_jiffies(delay_time_val)); continue; } set_current_state(TASK_RUNNING); - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); ch = synth_buffer_getc(); - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); if (ch == '\n') ch = PROCSPEECH; spk_out(ch); if ((jiffies >= jiff_max) && (ch == SPACE)) { spk_out(PROCSPEECH); - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); delay_time_val = delay_time->u.n.value; jiffy_delta_val = jiffy_delta->u.n.value; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); schedule_timeout(msecs_to_jiffies(delay_time_val)); jiff_max = jiffies + jiffy_delta_val; } @@ -254,7 +254,7 @@ static const char *synth_immediate(struct spk_synth *synth, const char *buf) spk_out(ch); buf++; } - return 0; + return NULL; } static void synth_flush(struct spk_synth *synth) diff --git a/drivers/staging/speakup/speakup_dummy.c b/drivers/staging/speakup/speakup_dummy.c index 4a24b9c1e8e..362342a194a 100644 --- a/drivers/staging/speakup/speakup_dummy.c +++ b/drivers/staging/speakup/speakup_dummy.c @@ -46,28 +46,28 @@ static struct var_t vars[] = { * These attributes will appear in /sys/accessibility/speakup/dummy. */ static struct kobj_attribute caps_start_attribute = - __ATTR(caps_start, USER_RW, spk_var_show, spk_var_store); + __ATTR(caps_start, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute caps_stop_attribute = - __ATTR(caps_stop, USER_RW, spk_var_show, spk_var_store); + __ATTR(caps_stop, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute pitch_attribute = - __ATTR(pitch, USER_RW, spk_var_show, spk_var_store); + __ATTR(pitch, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute rate_attribute = - __ATTR(rate, USER_RW, spk_var_show, spk_var_store); + __ATTR(rate, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute tone_attribute = - __ATTR(tone, USER_RW, spk_var_show, spk_var_store); + __ATTR(tone, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute vol_attribute = - __ATTR(vol, USER_RW, spk_var_show, spk_var_store); + __ATTR(vol, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute delay_time_attribute = - __ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute direct_attribute = - __ATTR(direct, USER_RW, spk_var_show, spk_var_store); + __ATTR(direct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute full_time_attribute = - __ATTR(full_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute jiffy_delta_attribute = - __ATTR(jiffy_delta, ROOT_W, spk_var_show, spk_var_store); + __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute trigger_time_attribute = - __ATTR(trigger_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); /* * Create a group of attributes so that we can create and destroy them all diff --git a/drivers/staging/speakup/speakup_keypc.c b/drivers/staging/speakup/speakup_keypc.c index feb5f22cc16..9d30c1945f9 100644 --- a/drivers/staging/speakup/speakup_keypc.c +++ b/drivers/staging/speakup/speakup_keypc.c @@ -59,24 +59,24 @@ static struct var_t vars[] = { * These attributes will appear in /sys/accessibility/speakup/keypc. */ static struct kobj_attribute caps_start_attribute = - __ATTR(caps_start, USER_RW, spk_var_show, spk_var_store); + __ATTR(caps_start, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute caps_stop_attribute = - __ATTR(caps_stop, USER_RW, spk_var_show, spk_var_store); + __ATTR(caps_stop, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute pitch_attribute = - __ATTR(pitch, USER_RW, spk_var_show, spk_var_store); + __ATTR(pitch, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute rate_attribute = - __ATTR(rate, USER_RW, spk_var_show, spk_var_store); + __ATTR(rate, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute delay_time_attribute = - __ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute direct_attribute = - __ATTR(direct, USER_RW, spk_var_show, spk_var_store); + __ATTR(direct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute full_time_attribute = - __ATTR(full_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute jiffy_delta_attribute = - __ATTR(jiffy_delta, ROOT_W, spk_var_show, spk_var_store); + __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute trigger_time_attribute = - __ATTR(trigger_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); /* * Create a group of attributes so that we can create and destroy them all @@ -168,7 +168,7 @@ static const char *synth_immediate(struct spk_synth *synth, const char *buf) udelay(70); buf++; } - return 0; + return NULL; } static void do_catch_up(struct spk_synth *synth) @@ -187,26 +187,26 @@ static void do_catch_up(struct spk_synth *synth) jiffy_delta = spk_get_var(JIFFY); delay_time = spk_get_var(DELAY); full_time = spk_get_var(FULL); -spk_lock(flags); +spin_lock_irqsave(&speakup_info.spinlock, flags); jiffy_delta_val = jiffy_delta->u.n.value; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); jiff_max = jiffies + jiffy_delta_val; while (!kthread_should_stop()) { - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); if (speakup_info.flushing) { speakup_info.flushing = 0; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); synth->flush(synth); continue; } if (synth_buffer_empty()) { - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); break; } set_current_state(TASK_INTERRUPTIBLE); full_time_val = full_time->u.n.value; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); if (synth_full()) { schedule_timeout(msecs_to_jiffies(full_time_val)); continue; @@ -220,9 +220,9 @@ spk_lock(flags); oops(); break; } - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); ch = synth_buffer_getc(); - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); if (ch == '\n') ch = PROCSPEECH; outb_p(ch, synth_port); @@ -237,10 +237,10 @@ spk_lock(flags); break; } outb_p(PROCSPEECH, synth_port); - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); jiffy_delta_val = jiffy_delta->u.n.value; delay_time_val = delay_time->u.n.value; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); schedule_timeout(msecs_to_jiffies(delay_time_val)); jiff_max = jiffies+jiffy_delta_val; } diff --git a/drivers/staging/speakup/speakup_ltlk.c b/drivers/staging/speakup/speakup_ltlk.c index 326f94d6b07..d6de72295d3 100644 --- a/drivers/staging/speakup/speakup_ltlk.c +++ b/drivers/staging/speakup/speakup_ltlk.c @@ -50,34 +50,34 @@ static struct var_t vars[] = { * These attributes will appear in /sys/accessibility/speakup/ltlk. */ static struct kobj_attribute caps_start_attribute = - __ATTR(caps_start, USER_RW, spk_var_show, spk_var_store); + __ATTR(caps_start, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute caps_stop_attribute = - __ATTR(caps_stop, USER_RW, spk_var_show, spk_var_store); + __ATTR(caps_stop, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute freq_attribute = - __ATTR(freq, USER_RW, spk_var_show, spk_var_store); + __ATTR(freq, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute pitch_attribute = - __ATTR(pitch, USER_RW, spk_var_show, spk_var_store); + __ATTR(pitch, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute punct_attribute = - __ATTR(punct, USER_RW, spk_var_show, spk_var_store); + __ATTR(punct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute rate_attribute = - __ATTR(rate, USER_RW, spk_var_show, spk_var_store); + __ATTR(rate, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute tone_attribute = - __ATTR(tone, USER_RW, spk_var_show, spk_var_store); + __ATTR(tone, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute voice_attribute = - __ATTR(voice, USER_RW, spk_var_show, spk_var_store); + __ATTR(voice, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute vol_attribute = - __ATTR(vol, USER_RW, spk_var_show, spk_var_store); + __ATTR(vol, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute delay_time_attribute = - __ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute direct_attribute = - __ATTR(direct, USER_RW, spk_var_show, spk_var_store); + __ATTR(direct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute full_time_attribute = - __ATTR(full_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute jiffy_delta_attribute = - __ATTR(jiffy_delta, ROOT_W, spk_var_show, spk_var_store); + __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute trigger_time_attribute = - __ATTR(trigger_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); /* * Create a group of attributes so that we can create and destroy them all diff --git a/drivers/staging/speakup/speakup_soft.c b/drivers/staging/speakup/speakup_soft.c index e2f5c81e754..9ed72650926 100644 --- a/drivers/staging/speakup/speakup_soft.c +++ b/drivers/staging/speakup/speakup_soft.c @@ -61,41 +61,41 @@ static struct var_t vars[] = { * These attributes will appear in /sys/accessibility/speakup/soft. */ static struct kobj_attribute caps_start_attribute = - __ATTR(caps_start, USER_RW, spk_var_show, spk_var_store); + __ATTR(caps_start, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute caps_stop_attribute = - __ATTR(caps_stop, USER_RW, spk_var_show, spk_var_store); + __ATTR(caps_stop, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute freq_attribute = - __ATTR(freq, USER_RW, spk_var_show, spk_var_store); + __ATTR(freq, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute pitch_attribute = - __ATTR(pitch, USER_RW, spk_var_show, spk_var_store); + __ATTR(pitch, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute punct_attribute = - __ATTR(punct, USER_RW, spk_var_show, spk_var_store); + __ATTR(punct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute rate_attribute = - __ATTR(rate, USER_RW, spk_var_show, spk_var_store); + __ATTR(rate, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute tone_attribute = - __ATTR(tone, USER_RW, spk_var_show, spk_var_store); + __ATTR(tone, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute voice_attribute = - __ATTR(voice, USER_RW, spk_var_show, spk_var_store); + __ATTR(voice, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute vol_attribute = - __ATTR(vol, USER_RW, spk_var_show, spk_var_store); + __ATTR(vol, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); /* * We should uncomment the following definition, when we agree on a * method of passing a language designation to the software synthesizer. * static struct kobj_attribute lang_attribute = - * __ATTR(lang, USER_RW, spk_var_show, spk_var_store); + * __ATTR(lang, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); */ static struct kobj_attribute delay_time_attribute = - __ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute direct_attribute = - __ATTR(direct, USER_RW, spk_var_show, spk_var_store); + __ATTR(direct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute full_time_attribute = - __ATTR(full_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute jiffy_delta_attribute = - __ATTR(jiffy_delta, ROOT_W, spk_var_show, spk_var_store); + __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute trigger_time_attribute = - __ATTR(trigger_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); /* * Create a group of attributes so that we can create and destroy them all @@ -179,45 +179,45 @@ static int softsynth_open(struct inode *inode, struct file *fp) unsigned long flags; /*if ((fp->f_flags & O_ACCMODE) != O_RDONLY) */ /* return -EPERM; */ - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); if (synth_soft.alive) { - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); return -EBUSY; } synth_soft.alive = 1; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); return 0; } static int softsynth_close(struct inode *inode, struct file *fp) { unsigned long flags; - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); synth_soft.alive = 0; init_pos = 0; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); /* Make sure we let applications go before leaving */ speakup_start_ttys(); return 0; } -static ssize_t softsynth_read(struct file *fp, char *buf, size_t count, +static ssize_t softsynth_read(struct file *fp, char __user *buf, size_t count, loff_t *pos) { int chars_sent = 0; - char *cp; + char __user *cp; char *init; char ch; int empty; unsigned long flags; DEFINE_WAIT(wait); - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); while (1) { prepare_to_wait(&speakup_event, &wait, TASK_INTERRUPTIBLE); if (!synth_buffer_empty() || speakup_info.flushing) break; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); if (fp->f_flags & O_NONBLOCK) { finish_wait(&speakup_event, &wait); return -EAGAIN; @@ -227,7 +227,7 @@ static ssize_t softsynth_read(struct file *fp, char *buf, size_t count, return -ERESTARTSYS; } schedule(); - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); } finish_wait(&speakup_event, &wait); @@ -244,16 +244,16 @@ static ssize_t softsynth_read(struct file *fp, char *buf, size_t count, } else { ch = synth_buffer_getc(); } - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); if (copy_to_user(cp, &ch, 1)) return -EFAULT; - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); chars_sent++; cp++; } *pos += chars_sent; empty = synth_buffer_empty(); - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); if (empty) { speakup_start_ttys(); *pos = 0; @@ -263,8 +263,8 @@ static ssize_t softsynth_read(struct file *fp, char *buf, size_t count, static int last_index; -static ssize_t softsynth_write(struct file *fp, const char *buf, size_t count, - loff_t *pos) +static ssize_t softsynth_write(struct file *fp, const char __user *buf, + size_t count, loff_t *pos) { unsigned long supplied_index = 0; int converted; @@ -285,10 +285,10 @@ static unsigned int softsynth_poll(struct file *fp, int ret = 0; poll_wait(fp, &speakup_event, wait); - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); if (!synth_buffer_empty() || speakup_info.flushing) ret = POLLIN | POLLRDNORM; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); return ret; } diff --git a/drivers/staging/speakup/speakup_spkout.c b/drivers/staging/speakup/speakup_spkout.c index e74f85620c6..77f2dc2c3d9 100644 --- a/drivers/staging/speakup/speakup_spkout.c +++ b/drivers/staging/speakup/speakup_spkout.c @@ -48,30 +48,30 @@ static struct var_t vars[] = { * These attributes will appear in /sys/accessibility/speakup/spkout. */ static struct kobj_attribute caps_start_attribute = - __ATTR(caps_start, USER_RW, spk_var_show, spk_var_store); + __ATTR(caps_start, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute caps_stop_attribute = - __ATTR(caps_stop, USER_RW, spk_var_show, spk_var_store); + __ATTR(caps_stop, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute pitch_attribute = - __ATTR(pitch, USER_RW, spk_var_show, spk_var_store); + __ATTR(pitch, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute punct_attribute = - __ATTR(punct, USER_RW, spk_var_show, spk_var_store); + __ATTR(punct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute rate_attribute = - __ATTR(rate, USER_RW, spk_var_show, spk_var_store); + __ATTR(rate, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute tone_attribute = - __ATTR(tone, USER_RW, spk_var_show, spk_var_store); + __ATTR(tone, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute vol_attribute = - __ATTR(vol, USER_RW, spk_var_show, spk_var_store); + __ATTR(vol, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute delay_time_attribute = - __ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute direct_attribute = - __ATTR(direct, USER_RW, spk_var_show, spk_var_store); + __ATTR(direct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute full_time_attribute = - __ATTR(full_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute jiffy_delta_attribute = - __ATTR(jiffy_delta, ROOT_W, spk_var_show, spk_var_store); + __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute trigger_time_attribute = - __ATTR(trigger_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); /* * Create a group of attributes so that we can create and destroy them all diff --git a/drivers/staging/speakup/speakup_txprt.c b/drivers/staging/speakup/speakup_txprt.c index 5a29b9fcc93..dbe84b13772 100644 --- a/drivers/staging/speakup/speakup_txprt.c +++ b/drivers/staging/speakup/speakup_txprt.c @@ -44,28 +44,28 @@ static struct var_t vars[] = { * These attributes will appear in /sys/accessibility/speakup/txprt. */ static struct kobj_attribute caps_start_attribute = - __ATTR(caps_start, USER_RW, spk_var_show, spk_var_store); + __ATTR(caps_start, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute caps_stop_attribute = - __ATTR(caps_stop, USER_RW, spk_var_show, spk_var_store); + __ATTR(caps_stop, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute pitch_attribute = - __ATTR(pitch, USER_RW, spk_var_show, spk_var_store); + __ATTR(pitch, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute rate_attribute = - __ATTR(rate, USER_RW, spk_var_show, spk_var_store); + __ATTR(rate, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute tone_attribute = - __ATTR(tone, USER_RW, spk_var_show, spk_var_store); + __ATTR(tone, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute vol_attribute = - __ATTR(vol, USER_RW, spk_var_show, spk_var_store); + __ATTR(vol, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute delay_time_attribute = - __ATTR(delay_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute direct_attribute = - __ATTR(direct, USER_RW, spk_var_show, spk_var_store); + __ATTR(direct, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute full_time_attribute = - __ATTR(full_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute jiffy_delta_attribute = - __ATTR(jiffy_delta, ROOT_W, spk_var_show, spk_var_store); + __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); static struct kobj_attribute trigger_time_attribute = - __ATTR(trigger_time, ROOT_W, spk_var_show, spk_var_store); + __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store); /* * Create a group of attributes so that we can create and destroy them all diff --git a/drivers/staging/speakup/spk_priv.h b/drivers/staging/speakup/spk_priv.h index 303105b4601..637ba6760ec 100644 --- a/drivers/staging/speakup/spk_priv.h +++ b/drivers/staging/speakup/spk_priv.h @@ -77,17 +77,4 @@ extern struct speakup_info_t speakup_info; extern struct var_t synth_time_vars[]; -/* Protect the whole speakup machinery, must be taken at each kernel->speakup - * transition and released at all corresponding speakup->kernel transitions - * (flags must be the same variable between lock/trylock and unlock). - * - * The progression thread only interferes with the speakup machinery through - * the synth buffer, and so only needs to take the lock while tinkering with - * it. - */ -/* Speakup needs to disable the keyboard IRQ, hence _irqsave/restore */ -#define spk_lock(flags) spin_lock_irqsave(&speakup_info.spinlock, flags) -#define spk_trylock(flags) spin_trylock_irqsave(&speakup_info.spinlock, flags) -#define spk_unlock(flags) spin_unlock_irqrestore(&speakup_info.spinlock, flags) - #endif diff --git a/drivers/staging/speakup/synth.c b/drivers/staging/speakup/synth.c index d867dd9109e..172cf62b1aa 100644 --- a/drivers/staging/speakup/synth.c +++ b/drivers/staging/speakup/synth.c @@ -25,6 +25,18 @@ static int module_status; bool spk_quiet_boot; struct speakup_info_t speakup_info = { + /* + * This spinlock is used to protect the entire speakup machinery, and + * must be taken at each kernel->speakup transition and released at + * each corresponding speakup->kernel transition. + * + * The progression thread only interferes with the speakup machinery through + * the synth buffer, so only needs to take the lock while tinkering with + * the buffer. + * + * We use spin_lock/trylock_irqsave and spin_unlock_irqrestore with this + * spinlock because speakup needs to disable the keyboard IRQ. + */ .spinlock = __SPIN_LOCK_UNLOCKED(speakup_info.spinlock), .flushing = 0, }; @@ -83,27 +95,27 @@ void spk_do_catch_up(struct spk_synth *synth) full_time = spk_get_var(FULL); delay_time = spk_get_var(DELAY); - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); jiffy_delta_val = jiffy_delta->u.n.value; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); jiff_max = jiffies + jiffy_delta_val; while (!kthread_should_stop()) { - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); if (speakup_info.flushing) { speakup_info.flushing = 0; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); synth->flush(synth); continue; } if (synth_buffer_empty()) { - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); break; } ch = synth_buffer_peek(); set_current_state(TASK_INTERRUPTIBLE); full_time_val = full_time->u.n.value; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); if (ch == '\n') ch = synth->procspeech; if (!spk_serial_out(ch)) { @@ -111,11 +123,11 @@ void spk_do_catch_up(struct spk_synth *synth) continue; } if ((jiffies >= jiff_max) && (ch == SPACE)) { - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); jiffy_delta_val = jiffy_delta->u.n.value; delay_time_val = delay_time->u.n.value; full_time_val = full_time->u.n.value; - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); if (spk_serial_out(synth->procspeech)) schedule_timeout( msecs_to_jiffies(delay_time_val)); @@ -125,9 +137,9 @@ void spk_do_catch_up(struct spk_synth *synth) jiff_max = jiffies + jiffy_delta_val; } set_current_state(TASK_RUNNING); - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); synth_buffer_getc(); - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); } spk_serial_out(synth->procspeech); } @@ -145,7 +157,7 @@ const char *spk_synth_immediate(struct spk_synth *synth, const char *buff) return buff; buff++; } - return 0; + return NULL; } EXPORT_SYMBOL_GPL(spk_synth_immediate); @@ -200,6 +212,9 @@ void synth_start(void) void spk_do_flush(void) { + if (!synth) + return; + speakup_info.flushing = 1; synth_buffer_clear(); if (synth->alive) { @@ -403,11 +418,11 @@ void synth_release(void) if (synth == NULL) return; - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); pr_info("releasing synth %s\n", synth->name); synth->alive = 0; del_timer(&thread_timer); - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); if (synth->attributes.name) sysfs_remove_group(speakup_kobj, &(synth->attributes)); for (var = synth->vars; var->var_id != MAXVARS; var++) diff --git a/drivers/staging/speakup/thread.c b/drivers/staging/speakup/thread.c index 42fa660a7e0..4397c8e898c 100644 --- a/drivers/staging/speakup/thread.c +++ b/drivers/staging/speakup/thread.c @@ -22,7 +22,7 @@ int speakup_thread(void *data) while (1) { DEFINE_WAIT(wait); while (1) { - spk_lock(flags); + spin_lock_irqsave(&speakup_info.spinlock, flags); our_sound = spk_unprocessed_sound; spk_unprocessed_sound.active = 0; prepare_to_wait(&speakup_event, &wait, @@ -32,7 +32,7 @@ int speakup_thread(void *data) (synth && synth->catch_up && synth->alive && (speakup_info.flushing || !synth_buffer_empty())); - spk_unlock(flags); + spin_unlock_irqrestore(&speakup_info.spinlock, flags); if (should_break) break; mutex_unlock(&spk_mutex); diff --git a/drivers/staging/speakup/varhandlers.c b/drivers/staging/speakup/varhandlers.c index f8c1e457d38..445a3fda380 100644 --- a/drivers/staging/speakup/varhandlers.c +++ b/drivers/staging/speakup/varhandlers.c @@ -46,7 +46,7 @@ static struct st_var_header var_headers[] = { { "direct", DIRECT, VAR_NUM, NULL, NULL }, }; -static struct st_var_header *var_ptrs[MAXVARS] = { 0, 0, 0 }; +static struct st_var_header *var_ptrs[MAXVARS] = { NULL, NULL, NULL }; static struct punc_var_t punc_vars[] = { { PUNC_SOME, 1 }, @@ -137,18 +137,15 @@ struct st_var_header *spk_get_var_header(enum var_id_t var_id) struct st_var_header *spk_var_header_by_name(const char *name) { int i; - struct st_var_header *where = NULL; - if (name != NULL) { - i = 0; - while ((i < MAXVARS) && (where == NULL)) { - if (strcmp(name, var_ptrs[i]->name) == 0) - where = var_ptrs[i]; - else - i++; - } + if (!name) + return NULL; + + for (i = 0; i < MAXVARS; i++) { + if (strcmp(name, var_ptrs[i]->name) == 0) + return var_ptrs[i]; } - return where; + return NULL; } struct var_t *spk_get_var(enum var_id_t var_id) @@ -184,19 +181,19 @@ int spk_set_num_var(int input, struct st_var_header *var, int how) char buf[32]; char *cp; struct var_t *var_data = var->data; + if (var_data == NULL) - return E_UNDEF; + return -ENODATA; if (how == E_NEW_DEFAULT) { if (input < var_data->u.n.low || input > var_data->u.n.high) - ret = E_RANGE; - else - var_data->u.n.default_val = input; - return ret; + return -ERANGE; + var_data->u.n.default_val = input; + return 0; } if (how == E_DEFAULT) { val = var_data->u.n.default_val; - ret = SET_DEFAULT; + ret = -ERESTART; } else { if (how == E_SET) val = input; @@ -207,7 +204,7 @@ int spk_set_num_var(int input, struct st_var_header *var, int how) else if (how == E_DEC) val -= input; if (val < var_data->u.n.low || val > var_data->u.n.high) - return E_RANGE; + return -ERANGE; } var_data->u.n.value = val; if (var->var_type == VAR_TIME && p_val != NULL) { @@ -246,25 +243,25 @@ int spk_set_num_var(int input, struct st_var_header *var, int how) int spk_set_string_var(const char *page, struct st_var_header *var, int len) { - int ret = 0; struct var_t *var_data = var->data; + if (var_data == NULL) - return E_UNDEF; + return -ENODATA; if (len > MAXVARLEN) - return -E_TOOLONG; + return -E2BIG; if (!len) { if (!var_data->u.s.default_val) return 0; - ret = SET_DEFAULT; if (!var->p_val) var->p_val = var_data->u.s.default_val; if (var->p_val != var_data->u.s.default_val) strcpy((char *)var->p_val, var_data->u.s.default_val); + return -ERESTART; } else if (var->p_val) strcpy((char *)var->p_val, page); else - return -E_TOOLONG; - return ret; + return -E2BIG; + return 0; } /* spk_set_mask_bits sets or clears the punc/delim/repeat bits, @@ -280,10 +277,10 @@ int spk_set_mask_bits(const char *input, const int which, const int how) spk_chartab[*cp] &= ~mask; } cp = (u_char *)input; - if (cp == 0) + if (!cp) cp = spk_punc_info[which].value; else { - for ( ; *cp; cp++) { + for (; *cp; cp++) { if (*cp < SPACE) break; if (mask < PUNC) { @@ -297,11 +294,11 @@ int spk_set_mask_bits(const char *input, const int which, const int how) cp = (u_char *)input; } if (how&2) { - for ( ; *cp; cp++) + for (; *cp; cp++) if (*cp > SPACE) spk_chartab[*cp] |= mask; } else { - for ( ; *cp; cp++) + for (; *cp; cp++) if (*cp > SPACE) spk_chartab[*cp] &= ~mask; } @@ -319,86 +316,12 @@ char *spk_strlwr(char *s) return s; } -char *speakup_s2i(char *start, int *dest) -{ - int val; - char ch = *start; - if (ch == '-' || ch == '+') - start++; - if (*start < '0' || *start > '9') - return start; - val = (*start) - '0'; - start++; - while (*start >= '0' && *start <= '9') { - val *= 10; - val += (*start) - '0'; - start++; - } - if (ch == '-') - *dest = -val; - else - *dest = val; - return start; -} - char *spk_s2uchar(char *start, char *dest) { int val = 0; - while (*start && *start <= SPACE) - start++; - while (*start >= '0' && *start <= '9') { - val *= 10; - val += (*start) - '0'; - start++; - } + val = simple_strtoul(skip_spaces(start), &start, 10); if (*start == ',') start++; *dest = (u_char)val; return start; } - -char *spk_xlate(char *s) -{ - static const char finds[] = "nrtvafe"; - static const char subs[] = "\n\r\t\013\001\014\033"; - static const char hx[] = "0123456789abcdefABCDEF"; - char *p = s, *p1, *p2, c; - int num; - while ((p = strchr(p, '\\'))) { - p1 = p+1; - p2 = strchr(finds, *p1); - if (p2) { - *p++ = subs[p2-finds]; - p1++; - } else if (*p1 >= '0' && *p1 <= '7') { - num = (*p1++)&7; - while (num < 256 && *p1 >= '0' && *p1 <= '7') { - num <<= 3; - num = (*p1++)&7; - } - *p++ = num; - } else if (*p1 == 'x' && - strchr(hx, p1[1]) && strchr(hx, p1[2])) { - p1++; - c = *p1++; - if (c > '9') - c = (c - '7') & 0x0f; - else - c -= '0'; - num = c << 4; - c = *p1++; - if (c > '9') - c = (c-'7')&0x0f; - else - c -= '0'; - num += c; - *p++ = num; - } else - *p++ = *p1++; - p2 = p; - while (*p1) - *p2++ = *p1++; - *p2 = '\0'; - } - return s; -} |
