diff options
| author | Che-Liang Chiou <clchiou@chromium.org> | 2012-02-01 12:25:35 -0500 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-02-01 12:26:18 -0500 |
| commit | 7a0a27d2ce38aee19a31fee8c12095f586eed393 (patch) | |
| tree | 00ee7cccdf137b8f2aa816d9421f5fbba4196662 /drivers/input/serio | |
| parent | d04df0232d6b5172dc1958df1829abd0214c8969 (diff) | |
Input: serio_raw - return proper result when serio_raw_read fails
serio_raw_read now returns (sometimes partially) successful number of
bytes transferred to the caller, and only returns error code to the
caller on completely failed transfers.
Signed-off-by: Che-Liang Chiou <clchiou@chromium.org>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/serio')
| -rw-r--r-- | drivers/input/serio/serio_raw.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c index 8250299fd64..4494233d331 100644 --- a/drivers/input/serio/serio_raw.c +++ b/drivers/input/serio/serio_raw.c | |||
| @@ -164,7 +164,8 @@ static ssize_t serio_raw_read(struct file *file, char __user *buffer, | |||
| 164 | struct serio_raw_client *client = file->private_data; | 164 | struct serio_raw_client *client = file->private_data; |
| 165 | struct serio_raw *serio_raw = client->serio_raw; | 165 | struct serio_raw *serio_raw = client->serio_raw; |
| 166 | char uninitialized_var(c); | 166 | char uninitialized_var(c); |
| 167 | ssize_t retval = 0; | 167 | ssize_t read = 0; |
| 168 | int retval; | ||
| 168 | 169 | ||
| 169 | if (serio_raw->dead) | 170 | if (serio_raw->dead) |
| 170 | return -ENODEV; | 171 | return -ENODEV; |
| @@ -180,13 +181,15 @@ static ssize_t serio_raw_read(struct file *file, char __user *buffer, | |||
| 180 | if (serio_raw->dead) | 181 | if (serio_raw->dead) |
| 181 | return -ENODEV; | 182 | return -ENODEV; |
| 182 | 183 | ||
| 183 | while (retval < count && serio_raw_fetch_byte(serio_raw, &c)) { | 184 | while (read < count && serio_raw_fetch_byte(serio_raw, &c)) { |
| 184 | if (put_user(c, buffer++)) | 185 | if (put_user(c, buffer++)) { |
| 185 | return -EFAULT; | 186 | retval = -EFAULT; |
| 186 | retval++; | 187 | break; |
| 188 | } | ||
| 189 | read++; | ||
| 187 | } | 190 | } |
| 188 | 191 | ||
| 189 | return retval; | 192 | return read ?: retval; |
| 190 | } | 193 | } |
| 191 | 194 | ||
| 192 | static ssize_t serio_raw_write(struct file *file, const char __user *buffer, | 195 | static ssize_t serio_raw_write(struct file *file, const char __user *buffer, |
