diff options
author | Varun Wadekar <vwadekar@nvidia.com> | 2011-05-03 09:40:11 +0530 |
---|---|---|
committer | Varun Colbert <vcolbert@nvidia.com> | 2011-05-04 10:56:07 -0700 |
commit | 548114012593e4cdd448d33497d30f093cabfe5f (patch) | |
tree | 0935e128622029fe7c9a1b5939b0b0cc6250e908 /arch | |
parent | 9cf05750fa9824e06338d7a933f6c9cabcab3408 (diff) |
ARM: tegra: fuse: fix sysfs programming/reading logic
some testing revealed certain loopholes in the
code. also the way the shell sends data down to
the sysfs handlers changed which warranted the
change in the handlers.
Change-Id: I131ab43691321a864ad5afd4f9852a7ba8842130
Signed-off-by: Varun Wadekar <vwadekar@nvidia.com>
Reviewed-on: http://git-master/r/30134
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-tegra/tegra2_fuse.c | 25 |
1 files changed, 10 insertions, 15 deletions
diff --git a/arch/arm/mach-tegra/tegra2_fuse.c b/arch/arm/mach-tegra/tegra2_fuse.c index ac2f02cfb669..97cf6e070f2b 100644 --- a/arch/arm/mach-tegra/tegra2_fuse.c +++ b/arch/arm/mach-tegra/tegra2_fuse.c @@ -665,6 +665,7 @@ static ssize_t fuse_store(struct kobject *kobj, struct kobj_attribute *attr, int ret, i = 0; struct fuse_data data = {0}; u32 *raw_data = ((u32 *)&data) + fuse_info_tbl[param].data_offset; + u8 *raw_byte_data = (u8 *)raw_data; struct wake_lock fuse_wk_lock; if ((param == -1) || (param == -ENODATA)) { @@ -672,10 +673,8 @@ static ssize_t fuse_store(struct kobject *kobj, struct kobj_attribute *attr, return -EINVAL; } - if (!isxdigit(*buf)) { - pr_err("%s: isxdigit fail\n", __func__); + if (!isxdigit(*buf)) return count; - } if (fuse_odm_prod_mode()) { pr_err("%s: device locked. odm fuse already blown\n", __func__); @@ -684,7 +683,7 @@ static ssize_t fuse_store(struct kobject *kobj, struct kobj_attribute *attr, count--; if (DIV_ROUND_UP(count, 2) > fuse_info_tbl[param].sz) { - pr_err("%s: fuse parameter too long, should be %d bytes\n", + pr_err("%s: fuse parameter too long, should be %d character(s)\n", __func__, fuse_info_tbl[param].sz * 2); return -EINVAL; } @@ -693,17 +692,13 @@ static ssize_t fuse_store(struct kobject *kobj, struct kobj_attribute *attr, wake_lock_init(&fuse_wk_lock, WAKE_LOCK_SUSPEND, "fuse_wk_lock"); wake_lock(&fuse_wk_lock); - raw_data += (count / CHARS_PER_WORD); - *raw_data = 0; - while (isxdigit(*buf)) { - *raw_data <<= 4; - *raw_data += char_to_xdigit(*buf); + raw_byte_data += DIV_ROUND_UP(count, 2) - 1; + for (i = 0; i < DIV_ROUND_UP(count, 2); i++, buf++) { + *raw_byte_data = char_to_xdigit(*buf); + *raw_byte_data <<= 4; buf++; - if (++i == 8) { - raw_data--; - *raw_data = 0; - i = 0; - } + *raw_byte_data |= (char_to_xdigit(*buf) & 0xF); + raw_byte_data--; } ret = tegra_fuse_program(&data, BIT(param)); @@ -757,7 +752,7 @@ static ssize_t fuse_show(struct kobject *kobj, struct kobj_attribute *attr, char } strcpy(buf, ""); - for (i = 0; i < (fuse_info_tbl[param].sz/sizeof(u32)) ; i++) { + for (i = (fuse_info_tbl[param].sz/sizeof(u32)) - 1; i >= 0 ; i--) { sprintf(str, "%08x", data[i]); strcat(buf, str); } |