Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[media] saa6588: add support for non-blocking mode

saa6588 always blocked while waiting for data, even if the filehandle
was in non-blocking mode.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>

authored by

Hans Verkuil and committed by
Mauro Carvalho Chehab
09092787 a101b947

+30 -21
+25 -20
drivers/media/i2c/saa6588.c
··· 150 150 151 151 /* ---------------------------------------------------------------------- */ 152 152 153 - static int block_to_user_buf(struct saa6588 *s, unsigned char __user *user_buf) 153 + static bool block_from_buf(struct saa6588 *s, unsigned char *buf) 154 154 { 155 155 int i; 156 156 157 157 if (s->rd_index == s->wr_index) { 158 158 if (debug > 2) 159 159 dprintk(PREFIX "Read: buffer empty.\n"); 160 - return 0; 160 + return false; 161 161 } 162 162 163 163 if (debug > 2) { ··· 166 166 dprintk("0x%02x ", s->buffer[i]); 167 167 } 168 168 169 - if (copy_to_user(user_buf, &s->buffer[s->rd_index], 3)) 170 - return -EFAULT; 169 + memcpy(buf, &s->buffer[s->rd_index], 3); 171 170 172 171 s->rd_index += 3; 173 172 if (s->rd_index >= s->buf_size) ··· 176 177 if (debug > 2) 177 178 dprintk("%d blocks total.\n", s->block_count); 178 179 179 - return 1; 180 + return true; 180 181 } 181 182 182 183 static void read_from_buf(struct saa6588 *s, struct saa6588_command *a) 183 184 { 184 - unsigned long flags; 185 - 186 185 unsigned char __user *buf_ptr = a->buffer; 187 - unsigned int i; 186 + unsigned char buf[3]; 187 + unsigned long flags; 188 188 unsigned int rd_blocks; 189 + unsigned int i; 189 190 190 191 a->result = 0; 191 192 if (!a->buffer) 192 193 return; 193 194 194 - while (!s->data_available_for_read) { 195 + while (!a->nonblocking && !s->data_available_for_read) { 195 196 int ret = wait_event_interruptible(s->read_queue, 196 197 s->data_available_for_read); 197 198 if (ret == -ERESTARTSYS) { ··· 200 201 } 201 202 } 202 203 203 - spin_lock_irqsave(&s->lock, flags); 204 204 rd_blocks = a->block_count; 205 + spin_lock_irqsave(&s->lock, flags); 205 206 if (rd_blocks > s->block_count) 206 207 rd_blocks = s->block_count; 208 + spin_unlock_irqrestore(&s->lock, flags); 207 209 208 - if (!rd_blocks) { 209 - spin_unlock_irqrestore(&s->lock, flags); 210 + if (!rd_blocks) 210 211 return; 211 - } 212 212 213 213 for (i = 0; i < rd_blocks; i++) { 214 - if (block_to_user_buf(s, buf_ptr)) { 215 - buf_ptr += 3; 216 - a->result++; 217 - } else 214 + bool got_block; 215 + 216 + spin_lock_irqsave(&s->lock, flags); 217 + got_block = block_from_buf(s, buf); 218 + spin_unlock_irqrestore(&s->lock, flags); 219 + if (!got_block) 218 220 break; 221 + if (copy_to_user(buf_ptr, buf, 3)) { 222 + a->result = -EFAULT; 223 + return; 224 + } 225 + buf_ptr += 3; 226 + a->result += 3; 219 227 } 220 - a->result *= 3; 228 + spin_lock_irqsave(&s->lock, flags); 221 229 s->data_available_for_read = (s->block_count > 0); 222 230 spin_unlock_irqrestore(&s->lock, flags); 223 231 } ··· 414 408 /* --- poll() for /dev/radio --- */ 415 409 case SAA6588_CMD_POLL: 416 410 a->result = 0; 417 - if (s->data_available_for_read) { 411 + if (s->data_available_for_read) 418 412 a->result |= POLLIN | POLLRDNORM; 419 - } 420 413 poll_wait(a->instance, &s->read_queue, a->event_list); 421 414 break; 422 415
+3 -1
drivers/media/pci/bt8xx/bttv-driver.c
··· 3266 3266 struct bttv_fh *fh = file->private_data; 3267 3267 struct bttv *btv = fh->btv; 3268 3268 struct saa6588_command cmd; 3269 - cmd.block_count = count/3; 3269 + 3270 + cmd.block_count = count / 3; 3271 + cmd.nonblocking = file->f_flags & O_NONBLOCK; 3270 3272 cmd.buffer = data; 3271 3273 cmd.instance = file; 3272 3274 cmd.result = -ENODEV;
+1
drivers/media/pci/saa7134/saa7134-video.c
··· 1285 1285 struct saa6588_command cmd; 1286 1286 1287 1287 cmd.block_count = count/3; 1288 + cmd.nonblocking = file->f_flags & O_NONBLOCK; 1288 1289 cmd.buffer = data; 1289 1290 cmd.instance = file; 1290 1291 cmd.result = -ENODEV;
+1
include/media/saa6588.h
··· 27 27 28 28 struct saa6588_command { 29 29 unsigned int block_count; 30 + bool nonblocking; 30 31 int result; 31 32 unsigned char __user *buffer; 32 33 struct file *instance;