aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/serio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/serio')
-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,
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 error = 0; 168 int error;
169 169
170 do { 170 for (;;) {
171 if (serio_raw->dead) 171 if (serio_raw->dead)
172 return -ENODEV; 172 return -ENODEV;
173 173
@@ -179,24 +179,24 @@ static ssize_t serio_raw_read(struct file *file, char __user *buffer,
179 break; 179 break;
180 180
181 while (read < count && serio_raw_fetch_byte(serio_raw, &c)) { 181 while (read < count && serio_raw_fetch_byte(serio_raw, &c)) {
182 if (put_user(c, buffer++)) { 182 if (put_user(c, buffer++))
183 error = -EFAULT; 183 return -EFAULT;
184 goto out;
185 }
186 read++; 184 read++;
187 } 185 }
188 186
189 if (read) 187 if (read)
190 break; 188 break;
191 189
192 if (!(file->f_flags & O_NONBLOCK)) 190 if (!(file->f_flags & O_NONBLOCK)) {
193 error = wait_event_interruptible(serio_raw->wait, 191 error = wait_event_interruptible(serio_raw->wait,
194 serio_raw->head != serio_raw->tail || 192 serio_raw->head != serio_raw->tail ||
195 serio_raw->dead); 193 serio_raw->dead);
196 } while (!error); 194 if (error)
195 return error;
196 }
197 }
197 198
198out: 199 return read;
199 return read ?: error;
200} 200}
201 201
202static ssize_t serio_raw_write(struct file *file, const char __user *buffer, 202static 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,
204{ 204{
205 struct serio_raw_client *client = file->private_data; 205 struct serio_raw_client *client = file->private_data;
206 struct serio_raw *serio_raw = client->serio_raw; 206 struct serio_raw *serio_raw = client->serio_raw;
207 ssize_t written = 0; 207 int retval = 0;
208 int retval;
209 unsigned char c; 208 unsigned char c;
210 209
211 retval = mutex_lock_interruptible(&serio_raw_mutex); 210 retval = mutex_lock_interruptible(&serio_raw_mutex);
@@ -225,16 +224,20 @@ static ssize_t serio_raw_write(struct file *file, const char __user *buffer,
225 retval = -EFAULT; 224 retval = -EFAULT;
226 goto out; 225 goto out;
227 } 226 }
227
228 if (serio_write(serio_raw->serio, c)) { 228 if (serio_write(serio_raw->serio, c)) {
229 retval = -EIO; 229 /* Either signal error or partial write */
230 if (retval == 0)
231 retval = -EIO;
230 goto out; 232 goto out;
231 } 233 }
232 written++; 234
235 retval++;
233 } 236 }
234 237
235out: 238out:
236 mutex_unlock(&serio_raw_mutex); 239 mutex_unlock(&serio_raw_mutex);
237 return written ?: retval; 240 return retval;
238} 241}
239 242
240static unsigned int serio_raw_poll(struct file *file, poll_table *wait) 243static unsigned int serio_raw_poll(struct file *file, poll_table *wait)