summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/input/serio/serio_raw.c33
1 files changed, 18 insertions, 15 deletions
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c
index 3e243621c0e3..59df2e7317a3 100644
--- a/drivers/input/serio/serio_raw.c
+++ b/drivers/input/serio/serio_raw.c
@@ -165,9 +165,9 @@ static ssize_t serio_raw_read(struct file *file, char __user *buffer,
struct serio_raw *serio_raw = client->serio_raw;
char uninitialized_var(c);
ssize_t read = 0;
- int error = 0;
+ int error;
- do {
+ for (;;) {
if (serio_raw->dead)
return -ENODEV;
@@ -179,24 +179,24 @@ static ssize_t serio_raw_read(struct file *file, char __user *buffer,
break;
while (read < count && serio_raw_fetch_byte(serio_raw, &c)) {
- if (put_user(c, buffer++)) {
- error = -EFAULT;
- goto out;
- }
+ if (put_user(c, buffer++))
+ return -EFAULT;
read++;
}
if (read)
break;
- if (!(file->f_flags & O_NONBLOCK))
+ if (!(file->f_flags & O_NONBLOCK)) {
error = wait_event_interruptible(serio_raw->wait,
serio_raw->head != serio_raw->tail ||
serio_raw->dead);
- } while (!error);
+ if (error)
+ return error;
+ }
+ }
-out:
- return read ?: error;
+ return read;
}
static ssize_t serio_raw_write(struct file *file, const char __user *buffer,
@@ -204,8 +204,7 @@ static ssize_t serio_raw_write(struct file *file, const char __user *buffer,
{
struct serio_raw_client *client = file->private_data;
struct serio_raw *serio_raw = client->serio_raw;
- ssize_t written = 0;
- int retval;
+ int retval = 0;
unsigned char c;
retval = mutex_lock_interruptible(&serio_raw_mutex);
@@ -225,16 +224,20 @@ static ssize_t serio_raw_write(struct file *file, const char __user *buffer,
retval = -EFAULT;
goto out;
}
+
if (serio_write(serio_raw->serio, c)) {
- retval = -EIO;
+ /* Either signal error or partial write */
+ if (retval == 0)
+ retval = -EIO;
goto out;
}
- written++;
+
+ retval++;
}
out:
mutex_unlock(&serio_raw_mutex);
- return written ?: retval;
+ return retval;
}
static unsigned int serio_raw_poll(struct file *file, poll_table *wait)