aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb
diff options
context:
space:
mode:
authorAndreas Oberritter <obi@linuxtv.org>2006-03-14 15:31:01 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-21 11:53:29 -0500
commit34731df288a5ffe4b0c396caf8cd24c6a710a222 (patch)
tree06738b1c00d2bee0df3b42d125b2ca4e03fc18b0 /drivers/media/dvb
parent4304954eb668ce66fc58f1cab9abb9a9e2584549 (diff)
V4L/DVB (3501): Dmxdev: use dvb_ringbuffer
Use dvb_ringbuffer instead of an own buffer implementation in dmxdev.[ch]. Signed-off-by: Andreas Oberritter <obi@linuxtv.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/dvb')
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.c156
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.h14
2 files changed, 62 insertions, 108 deletions
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index f6932d6c62e3..09e96e9ddbdf 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -40,110 +40,72 @@ MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
40 40
41#define dprintk if (debug) printk 41#define dprintk if (debug) printk
42 42
43static inline void dvb_dmxdev_buffer_init(struct dmxdev_buffer *buffer) 43static int dvb_dmxdev_buffer_write(struct dvb_ringbuffer *buf,
44 const u8 *src, size_t len)
44{ 45{
45 buffer->data = NULL; 46 ssize_t free;
46 buffer->size = 8192;
47 buffer->pread = 0;
48 buffer->pwrite = 0;
49 buffer->error = 0;
50 init_waitqueue_head(&buffer->queue);
51}
52
53static inline int dvb_dmxdev_buffer_write(struct dmxdev_buffer *buf,
54 const u8 *src, int len)
55{
56 int split;
57 int free;
58 int todo;
59 47
60 if (!len) 48 if (!len)
61 return 0; 49 return 0;
62 if (!buf->data) 50 if (!buf->data)
63 return 0; 51 return 0;
64 52
65 free = buf->pread - buf->pwrite; 53 free = dvb_ringbuffer_free(buf);
66 split = 0; 54 if (len > free) {
67 if (free <= 0) {
68 free += buf->size;
69 split = buf->size - buf->pwrite;
70 }
71 if (len >= free) {
72 dprintk("dmxdev: buffer overflow\n"); 55 dprintk("dmxdev: buffer overflow\n");
73 return -1; 56 return -EOVERFLOW;
74 }
75 if (split >= len)
76 split = 0;
77 todo = len;
78 if (split) {
79 memcpy(buf->data + buf->pwrite, src, split);
80 todo -= split;
81 buf->pwrite = 0;
82 } 57 }
83 memcpy(buf->data + buf->pwrite, src + split, todo); 58
84 buf->pwrite = (buf->pwrite + todo) % buf->size; 59 return dvb_ringbuffer_write(buf, src, len);
85 return len;
86} 60}
87 61
88static ssize_t dvb_dmxdev_buffer_read(struct dmxdev_buffer *src, 62static ssize_t dvb_dmxdev_buffer_read(struct dvb_ringbuffer *src,
89 int non_blocking, char __user *buf, 63 int non_blocking, char __user *buf,
90 size_t count, loff_t *ppos) 64 size_t count, loff_t *ppos)
91{ 65{
92 unsigned long todo = count; 66 size_t todo;
93 int split, avail, error; 67 ssize_t avail;
68 ssize_t ret = 0;
94 69
95 if (!src->data) 70 if (!src->data)
96 return 0; 71 return 0;
97 72
98 if ((error = src->error)) { 73 if (src->error) {
99 src->pwrite = src->pread; 74 ret = src->error;
100 src->error = 0; 75 dvb_ringbuffer_flush(src);
101 return error; 76 return ret;
102 } 77 }
103 78
104 if (non_blocking && (src->pwrite == src->pread)) 79 for (todo = count; todo > 0; todo -= ret) {
105 return -EWOULDBLOCK; 80 if (non_blocking && dvb_ringbuffer_empty(src)) {
106 81 ret = -EWOULDBLOCK;
107 while (todo > 0) { 82 break;
108 if (non_blocking && (src->pwrite == src->pread)) 83 }
109 return (count - todo) ? (count - todo) : -EWOULDBLOCK;
110 84
111 if (wait_event_interruptible(src->queue, 85 ret = wait_event_interruptible(src->queue,
112 (src->pread != src->pwrite) || 86 !dvb_ringbuffer_empty(src) ||
113 (src->error)) < 0) 87 (src->error != 0));
114 return count - todo; 88 if (ret < 0)
89 break;
115 90
116 if ((error = src->error)) { 91 if (src->error) {
117 src->pwrite = src->pread; 92 ret = src->error;
118 src->error = 0; 93 dvb_ringbuffer_flush(src);
119 return error; 94 break;
120 } 95 }
121 96
122 split = src->size; 97 avail = dvb_ringbuffer_avail(src);
123 avail = src->pwrite - src->pread;
124 if (avail < 0) {
125 avail += src->size;
126 split = src->size - src->pread;
127 }
128 if (avail > todo) 98 if (avail > todo)
129 avail = todo; 99 avail = todo;
130 if (split < avail) { 100
131 if (copy_to_user(buf, src->data + src->pread, split)) 101 ret = dvb_ringbuffer_read(src, buf, avail, 1);
132 return -EFAULT; 102 if (ret < 0)
133 buf += split; 103 break;
134 src->pread = 0; 104
135 todo -= split; 105 buf += ret;
136 avail -= split;
137 }
138 if (avail) {
139 if (copy_to_user(buf, src->data + src->pread, avail))
140 return -EFAULT;
141 src->pread = (src->pread + avail) % src->size;
142 todo -= avail;
143 buf += avail;
144 }
145 } 106 }
146 return count; 107
108 return (count - todo) ? (count - todo) : ret;
147} 109}
148 110
149static struct dmx_frontend *get_fe(struct dmx_demux *demux, int type) 111static struct dmx_frontend *get_fe(struct dmx_demux *demux, int type)
@@ -179,13 +141,12 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
179 } 141 }
180 142
181 if ((file->f_flags & O_ACCMODE) == O_RDONLY) { 143 if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
182 dvb_dmxdev_buffer_init(&dmxdev->dvr_buffer); 144 void *mem = vmalloc(DVR_BUFFER_SIZE);
183 dmxdev->dvr_buffer.size = DVR_BUFFER_SIZE; 145 if (!mem) {
184 dmxdev->dvr_buffer.data = vmalloc(DVR_BUFFER_SIZE);
185 if (!dmxdev->dvr_buffer.data) {
186 mutex_unlock(&dmxdev->mutex); 146 mutex_unlock(&dmxdev->mutex);
187 return -ENOMEM; 147 return -ENOMEM;
188 } 148 }
149 dvb_ringbuffer_init(&dmxdev->dvr_buffer, mem, DVR_BUFFER_SIZE);
189 } 150 }
190 151
191 if ((file->f_flags & O_ACCMODE) == O_WRONLY) { 152 if ((file->f_flags & O_ACCMODE) == O_WRONLY) {
@@ -280,7 +241,7 @@ static inline void dvb_dmxdev_filter_state_set(struct dmxdev_filter
280static int dvb_dmxdev_set_buffer_size(struct dmxdev_filter *dmxdevfilter, 241static int dvb_dmxdev_set_buffer_size(struct dmxdev_filter *dmxdevfilter,
281 unsigned long size) 242 unsigned long size)
282{ 243{
283 struct dmxdev_buffer *buf = &dmxdevfilter->buffer; 244 struct dvb_ringbuffer *buf = &dmxdevfilter->buffer;
284 void *mem; 245 void *mem;
285 246
286 if (buf->size == size) 247 if (buf->size == size)
@@ -291,7 +252,7 @@ static int dvb_dmxdev_set_buffer_size(struct dmxdev_filter *dmxdevfilter,
291 mem = buf->data; 252 mem = buf->data;
292 buf->data = NULL; 253 buf->data = NULL;
293 buf->size = size; 254 buf->size = size;
294 buf->pwrite = buf->pread = 0; 255 dvb_ringbuffer_flush(buf);
295 spin_unlock_irq(&dmxdevfilter->dev->lock); 256 spin_unlock_irq(&dmxdevfilter->dev->lock);
296 vfree(mem); 257 vfree(mem);
297 258
@@ -359,8 +320,8 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
359 buffer2_len); 320 buffer2_len);
360 } 321 }
361 if (ret < 0) { 322 if (ret < 0) {
362 dmxdevfilter->buffer.pwrite = dmxdevfilter->buffer.pread; 323 dvb_ringbuffer_flush(&dmxdevfilter->buffer);
363 dmxdevfilter->buffer.error = -EOVERFLOW; 324 dmxdevfilter->buffer.error = ret;
364 } 325 }
365 if (dmxdevfilter->params.sec.flags & DMX_ONESHOT) 326 if (dmxdevfilter->params.sec.flags & DMX_ONESHOT)
366 dmxdevfilter->state = DMXDEV_STATE_DONE; 327 dmxdevfilter->state = DMXDEV_STATE_DONE;
@@ -375,7 +336,7 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
375 enum dmx_success success) 336 enum dmx_success success)
376{ 337{
377 struct dmxdev_filter *dmxdevfilter = feed->priv; 338 struct dmxdev_filter *dmxdevfilter = feed->priv;
378 struct dmxdev_buffer *buffer; 339 struct dvb_ringbuffer *buffer;
379 int ret; 340 int ret;
380 341
381 spin_lock(&dmxdevfilter->dev->lock); 342 spin_lock(&dmxdevfilter->dev->lock);
@@ -397,8 +358,8 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
397 if (ret == buffer1_len) 358 if (ret == buffer1_len)
398 ret = dvb_dmxdev_buffer_write(buffer, buffer2, buffer2_len); 359 ret = dvb_dmxdev_buffer_write(buffer, buffer2, buffer2_len);
399 if (ret < 0) { 360 if (ret < 0) {
400 buffer->pwrite = buffer->pread; 361 dvb_ringbuffer_flush(buffer);
401 buffer->error = -EOVERFLOW; 362 buffer->error = ret;
402 } 363 }
403 spin_unlock(&dmxdevfilter->dev->lock); 364 spin_unlock(&dmxdevfilter->dev->lock);
404 wake_up(&buffer->queue); 365 wake_up(&buffer->queue);
@@ -494,7 +455,8 @@ static int dvb_dmxdev_filter_stop(struct dmxdev_filter *dmxdevfilter)
494 return 0; 455 return 0;
495 return -EINVAL; 456 return -EINVAL;
496 } 457 }
497 dmxdevfilter->buffer.pwrite = dmxdevfilter->buffer.pread = 0; 458
459 dvb_ringbuffer_flush(&dmxdevfilter->buffer);
498 return 0; 460 return 0;
499} 461}
500 462
@@ -520,16 +482,16 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
520 if (filter->state >= DMXDEV_STATE_GO) 482 if (filter->state >= DMXDEV_STATE_GO)
521 dvb_dmxdev_filter_stop(filter); 483 dvb_dmxdev_filter_stop(filter);
522 484
523 if (!(mem = filter->buffer.data)) { 485 if (!filter->buffer.data) {
524 mem = vmalloc(filter->buffer.size); 486 mem = vmalloc(filter->buffer.size);
487 if (!mem)
488 return -ENOMEM;
525 spin_lock_irq(&filter->dev->lock); 489 spin_lock_irq(&filter->dev->lock);
526 filter->buffer.data = mem; 490 filter->buffer.data = mem;
527 spin_unlock_irq(&filter->dev->lock); 491 spin_unlock_irq(&filter->dev->lock);
528 if (!filter->buffer.data)
529 return -ENOMEM;
530 } 492 }
531 493
532 filter->buffer.pwrite = filter->buffer.pread = 0; 494 dvb_ringbuffer_flush(&filter->buffer);
533 495
534 switch (filter->type) { 496 switch (filter->type) {
535 case DMXDEV_TYPE_SEC: 497 case DMXDEV_TYPE_SEC:
@@ -692,7 +654,7 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
692 mutex_init(&dmxdevfilter->mutex); 654 mutex_init(&dmxdevfilter->mutex);
693 file->private_data = dmxdevfilter; 655 file->private_data = dmxdevfilter;
694 656
695 dvb_dmxdev_buffer_init(&dmxdevfilter->buffer); 657 dvb_ringbuffer_init(&dmxdevfilter->buffer, NULL, 8192);
696 dmxdevfilter->type = DMXDEV_TYPE_NONE; 658 dmxdevfilter->type = DMXDEV_TYPE_NONE;
697 dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED); 659 dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED);
698 dmxdevfilter->feed.ts = NULL; 660 dmxdevfilter->feed.ts = NULL;
@@ -973,7 +935,7 @@ static unsigned int dvb_demux_poll(struct file *file, poll_table *wait)
973 if (dmxdevfilter->buffer.error) 935 if (dmxdevfilter->buffer.error)
974 mask |= (POLLIN | POLLRDNORM | POLLPRI | POLLERR); 936 mask |= (POLLIN | POLLRDNORM | POLLPRI | POLLERR);
975 937
976 if (dmxdevfilter->buffer.pread != dmxdevfilter->buffer.pwrite) 938 if (!dvb_ringbuffer_empty(&dmxdevfilter->buffer))
977 mask |= (POLLIN | POLLRDNORM | POLLPRI); 939 mask |= (POLLIN | POLLRDNORM | POLLPRI);
978 940
979 return mask; 941 return mask;
@@ -1047,7 +1009,7 @@ static unsigned int dvb_dvr_poll(struct file *file, poll_table *wait)
1047 if (dmxdev->dvr_buffer.error) 1009 if (dmxdev->dvr_buffer.error)
1048 mask |= (POLLIN | POLLRDNORM | POLLPRI | POLLERR); 1010 mask |= (POLLIN | POLLRDNORM | POLLPRI | POLLERR);
1049 1011
1050 if (dmxdev->dvr_buffer.pread != dmxdev->dvr_buffer.pwrite) 1012 if (!dvb_ringbuffer_empty(&dmxdev->dvr_buffer))
1051 mask |= (POLLIN | POLLRDNORM | POLLPRI); 1013 mask |= (POLLIN | POLLRDNORM | POLLPRI);
1052 } else 1014 } else
1053 mask |= (POLLOUT | POLLWRNORM | POLLPRI); 1015 mask |= (POLLOUT | POLLWRNORM | POLLPRI);
@@ -1097,7 +1059,7 @@ int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter)
1097 dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr, 1059 dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr,
1098 dmxdev, DVB_DEVICE_DVR); 1060 dmxdev, DVB_DEVICE_DVR);
1099 1061
1100 dvb_dmxdev_buffer_init(&dmxdev->dvr_buffer); 1062 dvb_ringbuffer_init(&dmxdev->dvr_buffer, NULL, 8192);
1101 1063
1102 return 0; 1064 return 0;
1103} 1065}
diff --git a/drivers/media/dvb/dvb-core/dmxdev.h b/drivers/media/dvb/dvb-core/dmxdev.h
index 1b3e49bd9aa2..d2bee9ffe43c 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.h
+++ b/drivers/media/dvb/dvb-core/dmxdev.h
@@ -36,6 +36,7 @@
36 36
37#include "dvbdev.h" 37#include "dvbdev.h"
38#include "demux.h" 38#include "demux.h"
39#include "dvb_ringbuffer.h"
39 40
40enum dmxdev_type { 41enum dmxdev_type {
41 DMXDEV_TYPE_NONE, 42 DMXDEV_TYPE_NONE,
@@ -52,15 +53,6 @@ enum dmxdev_state {
52 DMXDEV_STATE_TIMEDOUT 53 DMXDEV_STATE_TIMEDOUT
53}; 54};
54 55
55struct dmxdev_buffer {
56 u8 *data;
57 int size;
58 int pread;
59 int pwrite;
60 wait_queue_head_t queue;
61 int error;
62};
63
64struct dmxdev_filter { 56struct dmxdev_filter {
65 union { 57 union {
66 struct dmx_section_filter *sec; 58 struct dmx_section_filter *sec;
@@ -79,7 +71,7 @@ struct dmxdev_filter {
79 enum dmxdev_type type; 71 enum dmxdev_type type;
80 enum dmxdev_state state; 72 enum dmxdev_state state;
81 struct dmxdev *dev; 73 struct dmxdev *dev;
82 struct dmxdev_buffer buffer; 74 struct dvb_ringbuffer buffer;
83 75
84 struct mutex mutex; 76 struct mutex mutex;
85 77
@@ -102,7 +94,7 @@ struct dmxdev {
102#define DMXDEV_CAP_DUPLEX 1 94#define DMXDEV_CAP_DUPLEX 1
103 struct dmx_frontend *dvr_orig_fe; 95 struct dmx_frontend *dvr_orig_fe;
104 96
105 struct dmxdev_buffer dvr_buffer; 97 struct dvb_ringbuffer dvr_buffer;
106#define DVR_BUFFER_SIZE (10*188*1024) 98#define DVR_BUFFER_SIZE (10*188*1024)
107 99
108 struct mutex mutex; 100 struct mutex mutex;