diff options
-rw-r--r-- | drivers/input/serio/serio_raw.c | 43 |
1 files changed, 25 insertions, 18 deletions
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c index 948fd5a045f7..3e243621c0e3 100644 --- a/drivers/input/serio/serio_raw.c +++ b/drivers/input/serio/serio_raw.c | |||
@@ -165,31 +165,38 @@ static ssize_t serio_raw_read(struct file *file, char __user *buffer, | |||
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 read = 0; | 167 | ssize_t read = 0; |
168 | int retval; | 168 | int error = 0; |
169 | 169 | ||
170 | if (serio_raw->dead) | 170 | do { |
171 | return -ENODEV; | 171 | if (serio_raw->dead) |
172 | return -ENODEV; | ||
172 | 173 | ||
173 | if (serio_raw->head == serio_raw->tail && (file->f_flags & O_NONBLOCK)) | 174 | if (serio_raw->head == serio_raw->tail && |
174 | return -EAGAIN; | 175 | (file->f_flags & O_NONBLOCK)) |
176 | return -EAGAIN; | ||
175 | 177 | ||
176 | retval = wait_event_interruptible(serio_raw->wait, | 178 | if (count == 0) |
177 | serio_raw->head != serio_raw->tail || serio_raw->dead); | 179 | break; |
178 | if (retval) | ||
179 | return retval; | ||
180 | 180 | ||
181 | if (serio_raw->dead) | 181 | while (read < count && serio_raw_fetch_byte(serio_raw, &c)) { |
182 | return -ENODEV; | 182 | if (put_user(c, buffer++)) { |
183 | error = -EFAULT; | ||
184 | goto out; | ||
185 | } | ||
186 | read++; | ||
187 | } | ||
183 | 188 | ||
184 | while (read < count && serio_raw_fetch_byte(serio_raw, &c)) { | 189 | if (read) |
185 | if (put_user(c, buffer++)) { | ||
186 | retval = -EFAULT; | ||
187 | break; | 190 | break; |
188 | } | ||
189 | read++; | ||
190 | } | ||
191 | 191 | ||
192 | return read ?: retval; | 192 | if (!(file->f_flags & O_NONBLOCK)) |
193 | error = wait_event_interruptible(serio_raw->wait, | ||
194 | serio_raw->head != serio_raw->tail || | ||
195 | serio_raw->dead); | ||
196 | } while (!error); | ||
197 | |||
198 | out: | ||
199 | return read ?: error; | ||
193 | } | 200 | } |
194 | 201 | ||
195 | static ssize_t serio_raw_write(struct file *file, const char __user *buffer, | 202 | static ssize_t serio_raw_write(struct file *file, const char __user *buffer, |