// SPDX-License-Identifier: GPL-2.0
/*
 * Speakup kobject implementation
 *
 * Copyright (C) 2009 William Hubbs
 *
 * This code is based on kobject-example.c, which came with linux 2.6.x.
 *
 * Copyright (C) 2004-2007 Greg Kroah-Hartman <greg@kroah.com>
 * Copyright (C) 2007 Novell Inc.
 *
 * Released under the GPL version 2 only.
 *
 */
#include <linux/slab.h>		/* For kmalloc. */
#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>

#include "speakup.h"
#include "spk_priv.h"

/*
 * This is called when a user reads the characters or chartab sys file.
 */
static ssize_t chars_chartab_show(struct kobject *kobj,
				  struct kobj_attribute *attr, char *buf)
{
	int i;
	int len = 0;
	char *cp;
	char *buf_pointer = buf;
	size_t bufsize = PAGE_SIZE;
	unsigned long flags;

	spin_lock_irqsave(&speakup_info.spinlock, flags);
	*buf_pointer = '\0';
	for (i = 0; i < 256; i++) {
		if (bufsize <= 1)
			break;
		if (strcmp("characters", attr->attr.name) == 0) {
			len = scnprintf(buf_pointer, bufsize, "%d\t%s\n",
					i, spk_characters[i]);
		} else {	/* show chartab entry */
			if (IS_TYPE(i, B_CTL))
				cp = "B_CTL";
			else if (IS_TYPE(i, WDLM))
				cp = "WDLM";
			else if (IS_TYPE(i, A_PUNC))
				cp = "A_PUNC";
			else if (IS_TYPE(i, PUNC))
				cp = "PUNC";
			else if (IS_TYPE(i, NUM))
				cp = "NUM";
			else if (IS_TYPE(i, A_CAP))
				cp = "A_CAP";
			else if (IS_TYPE(i, ALPHA))
				cp = "ALPHA";
			else if (IS_TYPE(i, B_CAPSYM))
				cp = "B_CAPSYM";
			else if (IS_TYPE(i, B_SYM))
				cp = "B_SYM";
			else
				cp = "0";
			len =
			    scnprintf(buf_pointer, bufsize, "%d\t%s\n", i, cp);
		}
		bufsize -= len;
		buf_pointer += len;
	}
	spin_unlock_irqrestore(&speakup_info.spinlock, flags);
	return buf_pointer - buf;
}

/*
 * Print informational messages or warnings after updating
 * character descriptions or chartab entries.
 */
static void report_char_chartab_status(int reset, int received, int used,
				       int rejected, int do_characters)
{
	static char const *object_type[] = {
		"character class entries",
		"character descriptions",
	};
	int len;
	char buf[80];

	if (reset) {
		pr_info("%s reset to defaults\n", object_type[do_characters]);
	} else if (received) {
		len = scnprintf(buf, sizeof(buf),
				" updated %d of %d %s\n",
				used, received, object_type[do_characters]);
		if (rejected)
			snprintf(buf + (len - 1), sizeof(buf) - (len - 1),
				 " with %d reject%s\n",
				 rejected, str_plural(rejected));
		pr_info("%s", buf);
	}
}

/*
 * This is called when a user changes the characters or chartab parameters.
 */
static ssize_t chars_chartab_store(struct kobject *kobj,
				   struct kobj_attribute *attr,
				   const char *buf, size_t count)
{
	char *cp = (char *)buf;
	char *end = cp + count; /* the null at the end of the buffer */
	char *linefeed = NULL;
	char keyword[MAX_DESC_LEN + 1];
	char *outptr = NULL;	/* Will hold keyword or desc. */
	char *temp = NULL;
	char *desc = NULL;
	ssize_t retval = count;
	unsigned long flags;
	unsigned long index = 0;
	u16 charclass = 0;
	int received = 0;
	int used = 0;
	int rejected = 0;
	int reset = 0;
	int do_characters = !strcmp(attr->attr.name, "characters");
	size_t desc_length = 0;
	int i;

	spin_lock_irqsave(&speakup_info.spinlock, flags);
	while (cp < end) {
		while ((cp < end) && (*cp == ' ' || *cp == '\t'))
			cp++;

		if (cp == end)
			break;
		if ((*cp == '\n') || strchr("dDrR", *cp)) {
			reset = 1;
			break;
		}
		received++;

		linefeed = strchr(cp, '\n');
		if (!linefeed) {
			rejected++;
			break;
		}

		if (!isdigit(*cp)) {
			rejected++;
			cp = linefeed + 1;
			continue;
		}

		/*
		 * Do not replace with kstrtoul:
		 * here we need temp to be updated
		 */
		index = simple_strtoul(cp, &temp, 10);
		if (index > 255) {
			rejected++;
			cp = linefeed + 1;
			continue;
		}

		while ((temp < linefeed) && (*temp == ' ' || *temp == '\t'))
			temp++;

		desc_length = linefeed - temp;
		if (desc_length > MAX_DESC_LEN) {
			rejected++;
			cp = linefeed + 1;
			continue;
		}
		if (do_characters) {
			desc = kmalloc(desc_length + 1, GFP_ATOMIC);
			if (!desc) {
				retval = -ENOMEM;
				reset = 1;	/* just reset on error. */
				break;
			}
			outptr = desc;
		} else {
			outptr = keyword;
		}

		for (i = 0; i < desc_length; i++)
			outptr[i] = temp[i];
		outptr[desc_length] = '\0';

		if (do_characters) {
			if (spk_characters[index] != spk_default_chars[index])
				kfree(spk_characters[index]);
			spk_characters[index] = desc;
			used++;
		} else {
			charclass = spk_chartab_get_value(keyword);
			if (charclass == 0) {
				rejected++;
				cp = linefeed + 1;
				continue;
			}
			if (charclass != spk_chartab[index]) {
				spk_chartab[index] = charclass;
				used++;
			}
		}
		cp = linefeed + 1;
	}

	if (reset) {
		if (do_characters)
			spk_reset_default_chars();
		else
			spk_reset_default_chartab();
	}

	spin_unlock_irqrestore(&speakup_info.spinlock, flags);
	report_char_chartab_status(reset, received, used, rejected,
				   do_characters);
	return retval;
}

/*
 * This is called when a user reads the keymap parameter.
 */
static ssize_t keymap_show(struct kobject *kobj, struct kobj_attribute *attr,
			   char *buf)
{
	char *cp = buf;
	int i;
	int n;
	int num_keys;
	int nstates;
	u_char *cp1;
	u_char ch;
	unsigned long flags;

	spin_lock_irqsave(&speakup_info.spinlock, flags);
	cp1 = spk_key_buf + SHIFT_TBL_SIZE;
	num_keys = (int)(*cp1);
	nstates = (int)cp1[1];
	cp += sprintf(cp, "%d, %d, %d,\n", KEY_MAP_VER, num_keys, nstates);
	cp1 += 2; /* now pointing at shift states */
	/* dump num_keys+1 as first row is shift states + flags,
	 * each subsequent row is key + states
	 */
	for (n = 0; n <= num_keys; n++) {
		for (i = 0; i <= nstates; i++) {
			ch = *cp1++;
			cp += sprintf(cp, "%d,", (int)ch);
			*cp++ = (i < nstates) ? SPACE : '\n';
		}
	}
	cp += sprintf(cp, "0, %d\n", KEY_MAP_VER);
	spin_unlock_irqrestore(&speakup_info.spinlock, flags);
	return (int)(cp - buf);
}

/*
 * This is called when a user changes the keymap parameter.
 */
static ssize_t keymap_store(struct kobject *kobj, struct kobj_attribute *attr,
			    const char *buf, size_t count)
{
	int i;
	ssize_t ret = count;
	char *in_buff = NULL;
	char *cp;
	u_char *cp1;
	unsigned long flags;

	spin_lock_irqsave(&speakup_info.spinlock, flags);
	in_buff = kmemdup(buf, count + 1, GFP_ATOMIC);
	if (!in_buff) {
		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);
		spin_unlock_irqrestore(&speakup_info.spinlock, flags);
		return count;
	}
	if (in_buff[count - 1] == '\n')
		in_buff[count - 1] = '\0';
	cp = in_buff;
	cp1 = (u_char *)in_buff;
	for (i = 0; i < 3; i++) {
		cp = spk_s2uchar(cp, cp1);
		cp1++;
	}
	i = (int)cp1[-2] + 1;
	i *= (int)cp1[-1] + 1;
	i += 2; /* 0 and last map ver */
	if (cp1[-3] != KEY_MAP_VER || cp1[-1] > 10 ||
	    i + SHIFT_TBL_SIZE + 4 >= sizeof(spk_key_buf)) {
		pr_warn("i %d %d %d %d\n", i,
			(int)cp1[-3], (int)cp1[-2], (int)cp1[-1]);
		kfree(in_buff);
		spin_unlock_irqrestore(&speakup_info.spinlock, flags);
		return -EINVAL;
	}
	while (--i >= 0) {
		cp = spk_s2uchar(cp, cp1);
		cp1++;
		if (!(*cp))
			break;
	}
	if (i != 0 || cp1[-1] != KEY_MAP_VER || cp1[-2] != 0) {
		ret = -EINVAL;
		pr_warn("end %d %d %d %d\n", i,
			(int)cp1[-3], (int)cp1[-2], (int)cp1[-1]);
	} else {
		if (spk_set_key_info(in_buff, spk_key_buf)) {
			spk_set_key_info(spk_key_defaults, spk_key_buf);
			ret = -EINVAL;
			pr_warn("set key failed\n");
		}
	}
	kfree(in_buff);
	spin_unlock_irqrestore(&speakup_info.spinlock, flags);
	return ret;
}

/*
 * This is called when a user changes the value of the silent parameter.
 */
static ssize_t silent_store(struct kobject *kobj, struct kobj_attribute *attr,
			    const char *buf, size_t count)
{
	int len;
	struct vc_data *vc = vc_cons[fg_console].d;
	char ch = 0;
	char shut;
	unsigned long flags;

	len = strlen(buf);
	if (len > 0 && len < 3) {
		ch = buf[0];
		if (ch == '\n')
			ch = '0';
	}
	if (ch < '0' || ch > '7') {
		pr_warn("silent value '%c' not in range (0,7)\n", ch);
		return -EINVAL;
	}
	spin_lock_irqsave(&speakup_info.spinlock, flags);
	if (ch & 2) {
		shut = 1;
		spk_do_flush();
	} else {
		shut = 0;
	}
	if (ch & 4)
		shut |= 0x40;
	if (ch & 1)
		spk_shut_up |= shut;
	else
		spk_shut_up &= ~shut;
	spin_unlock_irqrestore(&speakup_info.spinlock, flags);
	return count;
}

/*
 * This is called when a user reads the synth setting.
 */
static ssize_t synth_show(struct kobject *kobj, struct kobj_attribute *attr,
			  char *buf)
{
	int rv;

	if (!synth)
		rv = sprintf(buf, "%s\n", "none");
	else
		rv = sprintf(buf, "%s\n", synth->name);
	return rv;
}

/*
 * This is called when a user requests to change synthesizers.
 */
static ssize_t synth_store(struct kobject *kobj, struct kobj_attribute *attr,
			   const char *buf, size_t count)
{
	int len;
	char new_synth_name[10];

	len = strlen(buf);
	if (len < 2 || len > 9)
		return -EINVAL;
	memcpy(new_synth_name, buf, len);
	if (new_synth_name[len - 1] == '\n')
		len--;
	new_synth_name[len] = '\0';
	spk_strlwr(new_synth_name);
	if (synth && !strcmp(new_synth_name, synth->name)) {
		pr_warn("%s already in use\n", new_synth_name);
	} else if (synth_init(new_synth_name) != 0) {
		pr_warn("failed to init synth %s\n", new_synth_name);
		return -ENODEV;
	}
	return count;
}

/*
 * This is called when text is sent to the synth via the synth_direct file.
 */
static ssize_t synth_direct_store(struct kobject *kobj,
				  struct kobj_attribute *attr,
				  const char *buf, size_t count)
{
	char *unescaped;
	unsigned long flags;

	if (!synth)
		return -EPERM;

	unescaped = kstrdup(buf, GFP_KERNEL);
	if (!unescaped)
		return -ENOMEM;

	string_unescape_any_inplace(unescaped);

	spin_lock_irqsave(&speakup_info.spinlock, flags);
	synth_write(unescaped, strlen(unescaped));
	spin_unlock_irqrestore(&speakup_info.spinlock, flags);

	kfree(unescaped);

	return count;
}

/*
 * This function is called when a user reads the version.
 */
static ssize_t version_show(struct kobject *kobj, struct kobj_attribute *attr,
			    char *buf)
{
	char *cp;

	cp = buf;
	cp += sprintf(cp, "Speakup version %s\n", SPEAKUP_VERSION);
	if (synth)
		cp += sprintf(cp, "%s synthesizer driver version %s\n",
		synth->name, synth->version);
	return cp - buf;
}

/*
 * This is called when a user reads the punctuation settings.
 */
static ssize_t punc_show(struct kobject *kobj, struct kobj_attribute *attr,
			 char *buf)
{
	int i;
	char *cp = buf;
	struct st_var_header *p_header;
	struct punc_var_t *var;
	struct st_bits_data *pb;
	u16 mask;
	unsigned long flags;

	p_header = spk_var_header_by_name(attr->attr.name);
	if (!p_header) {
		pr_warn("p_header is null, attr->attr.name is %s\n",
			attr->attr.name);
		return -EINVAL;
	}

	var = spk_get_punc_var(p_header->var_id);
	if (!var) {
		pr_warn("var is null, p_header->var_id is %i\n",
			p_header->var_id);
		return -EINVAL;
	}

	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++) {
		if (!(spk_chartab[i] & mask))
			continue;
		*cp++ = (char)i;
	}
	spin_unlock_irqrestore(&speakup_info.spinlock, flags);
	return cp - buf;
}

/*
 * This is called when a user changes the punctuation settings.
 */
static ssize_t punc_store(struct kobject *kobj, struct kobj_attribute *attr,
			  const char *buf, size_t count)
{
	int x;
	struct st_var_header *p_header;
	struct punc_var_t *var;
	char punc_buf[100];
	unsigned long flags;

	x = strlen(buf);
	if (x < 1 || x > 99)
		return -EINVAL;

	p_header = spk_var_header_by_name(attr->attr.name);
	if (!p_header) {
		pr_warn("p_header is null, attr->attr.name is %s\n",
			attr->attr.name);
		return -EINVAL;
	}

	var = spk_get_punc_var(p_header->var_id);
	if (!var) {
		pr_warn("var is null, p_header->var_id is %i\n",
			p_header->var_id);
		return -EINVAL;
	}

	memcpy(punc_buf, buf, x);

	while (x && punc_buf[x - 1] == '\n')
		x--;
	punc_buf[x] = '\0';

	spin_lock_irqsave(&speakup_info.spinlock, flags);

	if (*punc_buf == 'd' || *punc_buf == 'r')
		x = spk_set_mask_bits(NULL, var->value, 3);
	else
		x = spk_set_mask_bits(punc_buf, var->value, 3);

	spin_unlock_irqrestore(&speakup_info.spinlock, flags);
	return count;
}

/*
 * This function is called when a user reads one of the variable parameters.
 */
ssize_t spk_var_show(struct kobject *kobj, struct kobj_attribute *attr,
		     char *buf)
{
	int rv = 0;
	struct st_var_header *param;
	struct var_t *var;
	char *cp1;
	char *cp;
	char ch;
	unsigned long flags;

	param = spk_var_header_by_name(attr->attr.name);
	if (!param)
		return -EINVAL;

	spin_lock_irqsave(&speakup_info.spinlock, flags);
	var = (struct var_t *)param->data;
	switch (param->var_type) {
	case VAR_NUM:
	case VAR_TIME:
		if (var)
			rv = sprintf(buf, "%i\n", var->u.n.value);
		else
			rv = sprintf(buf, "0\n");
		break;
	case VAR_STRING:
		if (var) {
			cp1 = buf;
			*cp1++ = '"';
			for (cp = (char *)param->p_val; (ch = *cp); cp++) {
				if (ch >= ' ' && ch < '~')
					*cp1++ = ch;
				else
					cp1 += sprintf(cp1, "\\x%02x", ch);
			}
			*cp1++ = '"';
			*cp1++ = '\n';
			*cp1 = '\0';
			rv = cp1 - buf;
		} else {
			rv = sprintf(buf, "\"\"\n");
		}
		break;
	default:
		rv = sprintf(buf, "Bad parameter  %s, type %i\n",
			     param->name, param->var_type);
		break;
	}
	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.
 */
ssize_t spk_var_store(struct kobject *kobj, struct kobj_attribute *attr,
		      const char *buf, size_t count)
{
	struct st_var_header *param;
	int ret;
	int len;
	char *cp;
	struct var_t *var_data;
	long value;
	unsigned long flags;

	param = spk_var_header_by_name(attr->attr.name);
	if (!param)
		return -EINVAL;
	if (!param->data)
		return 0;
	ret = 0;
	cp = (char *)buf;
	string_unescape_any_inplace(cp);

	spin_lock_irqsave(&speakup_info.spinlock, flags);
	switch (param->var_type) {
	case VAR_NUM:
	case VAR_TIME:
		if (*cp == 'd' || *cp == 'r' || *cp == '\0')
			len = E_DEFAULT;
		else if (*cp == '+' || *cp == '-')
			len = E_INC;
		else
			len = E_SET;
		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",
				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(cp);
		if ((len >= 1) && (cp[len - 1] == '\n'))
			--len;
		if ((len >= 2) && (cp[0] == '"') && (cp[len - 1] == '"')) {
			++cp;
			len -= 2;
		}
		cp[len] = '\0';
		ret = spk_set_string_var(cp, param, len);
		if (ret == -E2BIG)
			pr_warn("value too long for %s\n",
				param->name);
		break;
	default:
		pr_warn("%s unknown type %d\n",
			param->name, (int)param->var_type);
	break;
	}
	spin_unlock_irqrestore(&speakup_info.spinlock, flags);

	if (ret == -ERESTART)
		pr_info("%s reset to default value\n", param->name);
	return count;
}
EXPORT_SYMBOL_GPL(spk_var_store);

/*
 * Functions for reading and writing lists of i18n messages.  Incomplete.
 */

static ssize_t message_show_helper(char *buf, enum msg_index_t first,
				   enum msg_index_t last)
{
	size_t bufsize = PAGE_SIZE;
	char *buf_pointer = buf;
	int printed;
	enum msg_index_t cursor;
	int index = 0;
	*buf_pointer = '\0'; /* buf_pointer always looking at a NUL byte. */

	for (cursor = first; cursor <= last; cursor++, index++) {
		if (bufsize <= 1)
			break;
		printed = scnprintf(buf_pointer, bufsize, "%d\t%s\n",
				    index, spk_msg_get(cursor));
		buf_pointer += printed;
		bufsize -= printed;
	}

	return buf_pointer - buf;
}

static void report_msg_status(int reset, int received, int used,
			      int rejected, char *groupname)
{
	int len;
	char buf[160];

	if (reset) {
		pr_info("i18n messages from group %s reset to defaults\n",
			groupname);
	} else if (received) {
		len = snprintf(buf, sizeof(buf),
			       " updated %d of %d i18n messages from group %s\n",
				       used, received, groupname);
		if (rejected)
			snprintf(buf + (len - 1), sizeof(buf) - (len - 1),
				 " with %d reject%s\n",
				 rejected, str_plural(rejected));
		pr_info("%s", buf);
	}
}

static ssize_t message_store_helper(const char *buf, size_t count,
				    struct msg_group_t *group)
{
	char *cp = (char *)buf;
	char *end = cp + count;
	char *linefeed = NULL;
	char *temp = NULL;
	ssize_t msg_stored = 0;
	ssize_t retval = count;
	size_t desc_length = 0;
	unsigned long index = 0;
	int received = 0;
	int used = 0;
	int rejected = 0;
	int reset = 0;
	enum msg_index_t firstmessage = group->start;
	enum msg_index_t lastmessage = group->end;
	enum msg_index_t curmessage;

	while (cp < end) {
		while ((cp < end) && (*cp == ' ' || *cp == '\t'))
			cp++;

		if (cp == end)
			break;
		if (strchr("dDrR", *cp)) {
			reset = 1;
			break;
		}
		received++;

		linefeed = strchr(cp, '\n');
		if (!linefeed) {
			rejected++;
			break;
		}

		if (!isdigit(*cp)) {
			rejected++;
			cp = linefeed + 1;
			continue;
		}

		/*
		 * Do not replace with kstrtoul:
		 * here we need temp to be updated
		 */
		index = simple_strtoul(cp, &temp, 10);

		while ((temp < linefeed) && (*temp == ' ' || *temp == '\t'))
			temp++;

		desc_length = linefeed - temp;
		curmessage = firstmessage + index;

		/*
		 * Note the check (curmessage < firstmessage).  It is not
		 * redundant.  Suppose that the user gave us an index
		 * equal to ULONG_MAX - 1.  If firstmessage > 1, then
		 * firstmessage + index < firstmessage!
		 */

		if ((curmessage < firstmessage) || (curmessage > lastmessage)) {
			rejected++;
			cp = linefeed + 1;
			continue;
		}

		msg_stored = spk_msg_set(curmessage, temp, desc_length);
		if (msg_stored < 0) {
			retval = msg_stored;
			if (msg_stored == -ENOMEM)
				reset = 1;
			break;
		}

		used++;

		cp = linefeed + 1;
	}

	if (reset)
		spk_reset_msg_group(group);

	report_msg_status(reset, received, used, rejected, group->name);
	return retval;
}

static ssize_t message_show(struct kobject *kobj,
			    struct kobj_attribute *attr, char *buf)
{
	ssize_t retval = 0;
	struct msg_group_t *group = spk_find_msg_group(attr->attr.name);
	unsigned long flags;

	if (WARN_ON(!group))
		return -EINVAL;

	spin_lock_irqsave(&speakup_info.spinlock, flags);
	retval = message_show_helper(buf, group->start, group->end);
	spin_unlock_irqrestore(&speakup_info.spinlock, flags);
	return retval;
}

static ssize_t message_store(struct kobject *kobj, struct kobj_attribute *attr,
			     const char *buf, size_t count)
{
	struct msg_group_t *group = spk_find_msg_group(attr->attr.name);

	if (WARN_ON(!group))
		return -EINVAL;

	return message_store_helper(buf, count, group);
}

/*
 * Declare the attributes.
 */
static struct kobj_attribute keymap_attribute =
	__ATTR_RW(keymap);
static struct kobj_attribute silent_attribute =
	__ATTR_WO(silent);
static struct kobj_attribute synth_attribute =
	__ATTR_RW(synth);
static struct kobj_attribute synth_direct_attribute =
	__ATTR_WO(synth_direct);
static struct kobj_attribute version_attribute =
	__ATTR_RO(version);

static struct kobj_attribute delimiters_attribute =
	__ATTR(delimiters, 0644, punc_show, punc_store);
static struct kobj_attribute ex_num_attribute =
	__ATTR(ex_num, 0644, punc_show, punc_store);
static struct kobj_attribute punc_all_attribute =
	__ATTR(punc_all, 0644, punc_show, punc_store);
static struct kobj_attribute punc_most_attribute =
	__ATTR(punc_most, 0644, punc_show, punc_store);
static struct kobj_attribute punc_some_attribute =
	__ATTR(punc_some, 0644, punc_show, punc_store);
static struct kobj_attribute repeats_attribute =
	__ATTR(repeats, 0644, punc_show, punc_store);

static struct kobj_attribute attrib_bleep_attribute =
	__ATTR(attrib_bleep, 0644, spk_var_show, spk_var_store);
static struct kobj_attribute bell_pos_attribute =
	__ATTR(bell_pos, 0644, spk_var_show, spk_var_store);
static struct kobj_attribute bleep_time_attribute =
	__ATTR(bleep_time, 0644, spk_var_show, spk_var_store);
static struct kobj_attribute bleeps_attribute =
	__ATTR(bleeps, 0644, spk_var_show, spk_var_store);
static struct kobj_attribute cursor_time_attribute =
	__ATTR(cursor_time, 0644, spk_var_show, spk_var_store);
static struct kobj_attribute key_echo_attribute =
	__ATTR(key_echo, 0644, spk_var_show, spk_var_store);
static struct kobj_attribute no_interrupt_attribute =
	__ATTR(no_interrupt, 0644, spk_var_show, spk_var_store);
static struct kobj_attribute punc_level_attribute =
	__ATTR(punc_level, 0644, spk_var_show, spk_var_store);
static struct kobj_attribute reading_punc_attribute =
	__ATTR(reading_punc, 0644, spk_var_show, spk_var_store);
static struct kobj_attribute say_control_attribute =
	__ATTR(say_control, 0644, spk_var_show, spk_var_store);
static struct kobj_attribute say_word_ctl_attribute =
	__ATTR(say_word_ctl, 0644, spk_var_show, spk_var_store);
static struct kobj_attribute spell_delay_attribute =
	__ATTR(spell_delay, 0644, spk_var_show, spk_var_store);
static struct kobj_attribute cur_phonetic_attribute =
	__ATTR(cur_phonetic, 0644, spk_var_show, spk_var_store);

/*
 * These attributes are i18n related.
 */
static struct kobj_attribute announcements_attribute =
	__ATTR(announcements, 0644, message_show, message_store);
static struct kobj_attribute characters_attribute =
	__ATTR(characters, 0644, chars_chartab_show,
	       chars_chartab_store);
static struct kobj_attribute chartab_attribute =
	__ATTR(chartab, 0644, chars_chartab_show,
	       chars_chartab_store);
static struct kobj_attribute ctl_keys_attribute =
	__ATTR(ctl_keys, 0644, message_show, message_store);
static struct kobj_attribute colors_attribute =
	__ATTR(colors, 0644, message_show, message_store);
static struct kobj_attribute formatted_attribute =
	__ATTR(formatted, 0644, message_show, message_store);
static struct kobj_attribute function_names_attribute =
	__ATTR(function_names, 0644, message_show, message_store);
static struct kobj_attribute key_names_attribute =
	__ATTR(key_names, 0644, message_show, message_store);
static struct kobj_attribute states_attribute =
	__ATTR(states, 0644, message_show, message_store);

/*
 * Create groups of attributes so that we can create and destroy them all
 * at once.
 */
static struct attribute *main_attrs[] = {
	&keymap_attribute.attr,
	&silent_attribute.attr,
	&synth_attribute.attr,
	&synth_direct_attribute.attr,
	&version_attribute.attr,
	&delimiters_attribute.attr,
	&ex_num_attribute.attr,
	&punc_all_attribute.attr,
	&punc_most_attribute.attr,
	&punc_some_attribute.attr,
	&repeats_attribute.attr,
	&attrib_bleep_attribute.attr,
	&bell_pos_attribute.attr,
	&bleep_time_attribute.attr,
	&bleeps_attribute.attr,
	&cursor_time_attribute.attr,
	&key_echo_attribute.attr,
	&no_interrupt_attribute.attr,
	&punc_level_attribute.attr,
	&reading_punc_attribute.attr,
	&say_control_attribute.attr,
	&say_word_ctl_attribute.attr,
	&spell_delay_attribute.attr,
	&cur_phonetic_attribute.attr,
	NULL,
};

static struct attribute *i18n_attrs[] = {
	&announcements_attribute.attr,
	&characters_attribute.attr,
	&chartab_attribute.attr,
	&ctl_keys_attribute.attr,
	&colors_attribute.attr,
	&formatted_attribute.attr,
	&function_names_attribute.attr,
	&key_names_attribute.attr,
	&states_attribute.attr,
	NULL,
};

/*
 * An unnamed attribute group will put all of the attributes directly in
 * the kobject directory.  If we specify a name, a subdirectory will be
 * created for the attributes with the directory being the name of the
 * attribute group.
 */
static const struct attribute_group main_attr_group = {
	.attrs = main_attrs,
};

static const struct attribute_group i18n_attr_group = {
	.attrs = i18n_attrs,
	.name = "i18n",
};

static struct kobject *accessibility_kobj;
struct kobject *speakup_kobj;

int speakup_kobj_init(void)
{
	int retval;

	/*
	 * Create a simple kobject with the name of "accessibility",
	 * located under /sys/
	 *
	 * As this is a simple directory, no uevent will be sent to
	 * userspace.  That is why this function should not be used for
	 * any type of dynamic kobjects, where the name and number are
	 * not known ahead of time.
	 */
	accessibility_kobj = kobject_create_and_add("accessibility", NULL);
	if (!accessibility_kobj) {
		retval = -ENOMEM;
		goto out;
	}

	speakup_kobj = kobject_create_and_add("speakup", accessibility_kobj);
	if (!speakup_kobj) {
		retval = -ENOMEM;
		goto err_acc;
	}

	/* Create the files associated with this kobject */
	retval = sysfs_create_group(speakup_kobj, &main_attr_group);
	if (retval)
		goto err_speakup;

	retval = sysfs_create_group(speakup_kobj, &i18n_attr_group);
	if (retval)
		goto err_group;

	goto out;

err_group:
	sysfs_remove_group(speakup_kobj, &main_attr_group);
err_speakup:
	kobject_put(speakup_kobj);
err_acc:
	kobject_put(accessibility_kobj);
out:
	return retval;
}

void speakup_kobj_exit(void)
{
	sysfs_remove_group(speakup_kobj, &i18n_attr_group);
	sysfs_remove_group(speakup_kobj, &main_attr_group);
	kobject_put(speakup_kobj);
	kobject_put(accessibility_kobj);
}
