aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.c63
1 files changed, 49 insertions, 14 deletions
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index bbd52be552db..df5bef6a2517 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -259,6 +259,39 @@ static ssize_t dvb_dvr_read(struct file *file, char __user *buf, size_t count,
259 return ret; 259 return ret;
260} 260}
261 261
262static int dvb_dvr_set_buffer_size(struct dmxdev *dmxdev,
263 unsigned long size)
264{
265 struct dvb_ringbuffer *buf = &dmxdev->dvr_buffer;
266 void *newmem;
267 void *oldmem;
268
269 dprintk("function : %s\n", __func__);
270
271 if (buf->size == size)
272 return 0;
273 if (!size)
274 return -EINVAL;
275
276 newmem = vmalloc(size);
277 if (!newmem)
278 return -ENOMEM;
279
280 oldmem = buf->data;
281
282 spin_lock_irq(&dmxdev->lock);
283 buf->data = newmem;
284 buf->size = size;
285
286 /* reset and not flush in case the buffer shrinks */
287 dvb_ringbuffer_reset(buf);
288 spin_unlock_irq(&dmxdev->lock);
289
290 vfree(oldmem);
291
292 return 0;
293}
294
262static inline void dvb_dmxdev_filter_state_set(struct dmxdev_filter 295static inline void dvb_dmxdev_filter_state_set(struct dmxdev_filter
263 *dmxdevfilter, int state) 296 *dmxdevfilter, int state)
264{ 297{
@@ -271,30 +304,32 @@ static int dvb_dmxdev_set_buffer_size(struct dmxdev_filter *dmxdevfilter,
271 unsigned long size) 304 unsigned long size)
272{ 305{
273 struct dvb_ringbuffer *buf = &dmxdevfilter->buffer; 306 struct dvb_ringbuffer *buf = &dmxdevfilter->buffer;
274 void *mem; 307 void *newmem;
308 void *oldmem;
275 309
276 if (buf->size == size) 310 if (buf->size == size)
277 return 0; 311 return 0;
312 if (!size)
313 return -EINVAL;
278 if (dmxdevfilter->state >= DMXDEV_STATE_GO) 314 if (dmxdevfilter->state >= DMXDEV_STATE_GO)
279 return -EBUSY; 315 return -EBUSY;
316
317 newmem = vmalloc(size);
318 if (!newmem)
319 return -ENOMEM;
320
321 oldmem = buf->data;
322
280 spin_lock_irq(&dmxdevfilter->dev->lock); 323 spin_lock_irq(&dmxdevfilter->dev->lock);
281 mem = buf->data; 324 buf->data = newmem;
282 buf->data = NULL;
283 buf->size = size; 325 buf->size = size;
284 326
285 /* reset and not flush in case the buffer shrinks */ 327 /* reset and not flush in case the buffer shrinks */
286 dvb_ringbuffer_reset(buf); 328 dvb_ringbuffer_reset(buf);
287 spin_unlock_irq(&dmxdevfilter->dev->lock); 329 spin_unlock_irq(&dmxdevfilter->dev->lock);
288 vfree(mem);
289 330
290 if (buf->size) { 331 vfree(oldmem);
291 mem = vmalloc(dmxdevfilter->buffer.size); 332
292 if (!mem)
293 return -ENOMEM;
294 spin_lock_irq(&dmxdevfilter->dev->lock);
295 buf->data = mem;
296 spin_unlock_irq(&dmxdevfilter->dev->lock);
297 }
298 return 0; 333 return 0;
299} 334}
300 335
@@ -1011,6 +1046,7 @@ static int dvb_dvr_do_ioctl(struct inode *inode, struct file *file,
1011{ 1046{
1012 struct dvb_device *dvbdev = file->private_data; 1047 struct dvb_device *dvbdev = file->private_data;
1013 struct dmxdev *dmxdev = dvbdev->priv; 1048 struct dmxdev *dmxdev = dvbdev->priv;
1049 unsigned long arg = (unsigned long)parg;
1014 int ret; 1050 int ret;
1015 1051
1016 if (mutex_lock_interruptible(&dmxdev->mutex)) 1052 if (mutex_lock_interruptible(&dmxdev->mutex))
@@ -1018,8 +1054,7 @@ static int dvb_dvr_do_ioctl(struct inode *inode, struct file *file,
1018 1054
1019 switch (cmd) { 1055 switch (cmd) {
1020 case DMX_SET_BUFFER_SIZE: 1056 case DMX_SET_BUFFER_SIZE:
1021 // FIXME: implement 1057 ret = dvb_dvr_set_buffer_size(dmxdev, arg);
1022 ret = 0;
1023 break; 1058 break;
1024 1059
1025 default: 1060 default: