diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2013-12-14 06:28:36 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-01-07 04:42:19 -0500 |
commit | 09092787e0cf66e705b0d744f5f0c3b2b6495559 (patch) | |
tree | 7200db1a6dd03c476e35f106a4f30bdb2f1bba55 /drivers/media | |
parent | a101b947d405b5c2c94f260867074a4466b7cbea (diff) |
[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>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/i2c/saa6588.c | 45 | ||||
-rw-r--r-- | drivers/media/pci/bt8xx/bttv-driver.c | 4 | ||||
-rw-r--r-- | drivers/media/pci/saa7134/saa7134-video.c | 1 |
3 files changed, 29 insertions, 21 deletions
diff --git a/drivers/media/i2c/saa6588.c b/drivers/media/i2c/saa6588.c index 21cf940f5ea0..2960b5a8362a 100644 --- a/drivers/media/i2c/saa6588.c +++ b/drivers/media/i2c/saa6588.c | |||
@@ -150,14 +150,14 @@ static inline struct saa6588 *to_saa6588(struct v4l2_subdev *sd) | |||
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 | int i; | 155 | int i; |
156 | 156 | ||
157 | if (s->rd_index == s->wr_index) { | 157 | if (s->rd_index == s->wr_index) { |
158 | if (debug > 2) | 158 | if (debug > 2) |
159 | dprintk(PREFIX "Read: buffer empty.\n"); | 159 | dprintk(PREFIX "Read: buffer empty.\n"); |
160 | return 0; | 160 | return false; |
161 | } | 161 | } |
162 | 162 | ||
163 | if (debug > 2) { | 163 | if (debug > 2) { |
@@ -166,8 +166,7 @@ static int block_to_user_buf(struct saa6588 *s, unsigned char __user *user_buf) | |||
166 | dprintk("0x%02x ", s->buffer[i]); | 166 | dprintk("0x%02x ", s->buffer[i]); |
167 | } | 167 | } |
168 | 168 | ||
169 | if (copy_to_user(user_buf, &s->buffer[s->rd_index], 3)) | 169 | memcpy(buf, &s->buffer[s->rd_index], 3); |
170 | return -EFAULT; | ||
171 | 170 | ||
172 | s->rd_index += 3; | 171 | s->rd_index += 3; |
173 | if (s->rd_index >= s->buf_size) | 172 | if (s->rd_index >= s->buf_size) |
@@ -177,22 +176,22 @@ static int block_to_user_buf(struct saa6588 *s, unsigned char __user *user_buf) | |||
177 | if (debug > 2) | 176 | if (debug > 2) |
178 | dprintk("%d blocks total.\n", s->block_count); | 177 | dprintk("%d blocks total.\n", s->block_count); |
179 | 178 | ||
180 | return 1; | 179 | return true; |
181 | } | 180 | } |
182 | 181 | ||
183 | static void read_from_buf(struct saa6588 *s, struct saa6588_command *a) | 182 | static void read_from_buf(struct saa6588 *s, struct saa6588_command *a) |
184 | { | 183 | { |
185 | unsigned long flags; | ||
186 | |||
187 | unsigned char __user *buf_ptr = a->buffer; | 184 | unsigned char __user *buf_ptr = a->buffer; |
188 | unsigned int i; | 185 | unsigned char buf[3]; |
186 | unsigned long flags; | ||
189 | unsigned int rd_blocks; | 187 | unsigned int rd_blocks; |
188 | unsigned int i; | ||
190 | 189 | ||
191 | a->result = 0; | 190 | a->result = 0; |
192 | if (!a->buffer) | 191 | if (!a->buffer) |
193 | return; | 192 | return; |
194 | 193 | ||
195 | while (!s->data_available_for_read) { | 194 | while (!a->nonblocking && !s->data_available_for_read) { |
196 | int ret = wait_event_interruptible(s->read_queue, | 195 | int ret = wait_event_interruptible(s->read_queue, |
197 | s->data_available_for_read); | 196 | s->data_available_for_read); |
198 | if (ret == -ERESTARTSYS) { | 197 | if (ret == -ERESTARTSYS) { |
@@ -201,24 +200,31 @@ static void read_from_buf(struct saa6588 *s, struct saa6588_command *a) | |||
201 | } | 200 | } |
202 | } | 201 | } |
203 | 202 | ||
204 | spin_lock_irqsave(&s->lock, flags); | ||
205 | rd_blocks = a->block_count; | 203 | rd_blocks = a->block_count; |
204 | spin_lock_irqsave(&s->lock, flags); | ||
206 | if (rd_blocks > s->block_count) | 205 | if (rd_blocks > s->block_count) |
207 | rd_blocks = s->block_count; | 206 | rd_blocks = s->block_count; |
207 | spin_unlock_irqrestore(&s->lock, flags); | ||
208 | 208 | ||
209 | if (!rd_blocks) { | 209 | if (!rd_blocks) |
210 | spin_unlock_irqrestore(&s->lock, flags); | ||
211 | return; | 210 | return; |
212 | } | ||
213 | 211 | ||
214 | for (i = 0; i < rd_blocks; i++) { | 212 | for (i = 0; i < rd_blocks; i++) { |
215 | if (block_to_user_buf(s, buf_ptr)) { | 213 | bool got_block; |
216 | buf_ptr += 3; | 214 | |
217 | a->result++; | 215 | spin_lock_irqsave(&s->lock, flags); |
218 | } else | 216 | got_block = block_from_buf(s, buf); |
217 | spin_unlock_irqrestore(&s->lock, flags); | ||
218 | if (!got_block) | ||
219 | break; | 219 | break; |
220 | if (copy_to_user(buf_ptr, buf, 3)) { | ||
221 | a->result = -EFAULT; | ||
222 | return; | ||
223 | } | ||
224 | buf_ptr += 3; | ||
225 | a->result += 3; | ||
220 | } | 226 | } |
221 | a->result *= 3; | 227 | spin_lock_irqsave(&s->lock, flags); |
222 | s->data_available_for_read = (s->block_count > 0); | 228 | s->data_available_for_read = (s->block_count > 0); |
223 | spin_unlock_irqrestore(&s->lock, flags); | 229 | spin_unlock_irqrestore(&s->lock, flags); |
224 | } | 230 | } |
@@ -408,9 +414,8 @@ static long saa6588_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) | |||
408 | /* --- poll() for /dev/radio --- */ | 414 | /* --- poll() for /dev/radio --- */ |
409 | case SAA6588_CMD_POLL: | 415 | case SAA6588_CMD_POLL: |
410 | a->result = 0; | 416 | a->result = 0; |
411 | if (s->data_available_for_read) { | 417 | if (s->data_available_for_read) |
412 | a->result |= POLLIN | POLLRDNORM; | 418 | a->result |= POLLIN | POLLRDNORM; |
413 | } | ||
414 | poll_wait(a->instance, &s->read_queue, a->event_list); | 419 | poll_wait(a->instance, &s->read_queue, a->event_list); |
415 | break; | 420 | break; |
416 | 421 | ||
diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c index 92a06fd85865..c2aaadcd9318 100644 --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c | |||
@@ -3266,7 +3266,9 @@ static ssize_t radio_read(struct file *file, char __user *data, | |||
3266 | struct bttv_fh *fh = file->private_data; | 3266 | struct bttv_fh *fh = file->private_data; |
3267 | struct bttv *btv = fh->btv; | 3267 | struct bttv *btv = fh->btv; |
3268 | struct saa6588_command cmd; | 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 | cmd.buffer = data; | 3272 | cmd.buffer = data; |
3271 | cmd.instance = file; | 3273 | cmd.instance = file; |
3272 | cmd.result = -ENODEV; | 3274 | cmd.result = -ENODEV; |
diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c index 88e64055f0a4..36026b1cb3f8 100644 --- a/drivers/media/pci/saa7134/saa7134-video.c +++ b/drivers/media/pci/saa7134/saa7134-video.c | |||
@@ -1285,6 +1285,7 @@ static ssize_t radio_read(struct file *file, char __user *data, | |||
1285 | struct saa6588_command cmd; | 1285 | struct saa6588_command cmd; |
1286 | 1286 | ||
1287 | cmd.block_count = count/3; | 1287 | cmd.block_count = count/3; |
1288 | cmd.nonblocking = file->f_flags & O_NONBLOCK; | ||
1288 | cmd.buffer = data; | 1289 | cmd.buffer = data; |
1289 | cmd.instance = file; | 1290 | cmd.instance = file; |
1290 | cmd.result = -ENODEV; | 1291 | cmd.result = -ENODEV; |