diff options
Diffstat (limited to 'drivers/media/dvb/ngene/ngene-dvb.c')
-rw-r--r-- | drivers/media/dvb/ngene/ngene-dvb.c | 71 |
1 files changed, 70 insertions, 1 deletions
diff --git a/drivers/media/dvb/ngene/ngene-dvb.c b/drivers/media/dvb/ngene/ngene-dvb.c index 3832e5983c19..0b4943233166 100644 --- a/drivers/media/dvb/ngene/ngene-dvb.c +++ b/drivers/media/dvb/ngene/ngene-dvb.c | |||
@@ -47,6 +47,64 @@ | |||
47 | /* COMMAND API interface ****************************************************/ | 47 | /* COMMAND API interface ****************************************************/ |
48 | /****************************************************************************/ | 48 | /****************************************************************************/ |
49 | 49 | ||
50 | static ssize_t ts_write(struct file *file, const char *buf, | ||
51 | size_t count, loff_t *ppos) | ||
52 | { | ||
53 | struct dvb_device *dvbdev = file->private_data; | ||
54 | struct ngene_channel *chan = dvbdev->priv; | ||
55 | struct ngene *dev = chan->dev; | ||
56 | |||
57 | if (wait_event_interruptible(dev->tsout_rbuf.queue, | ||
58 | dvb_ringbuffer_free | ||
59 | (&dev->tsout_rbuf) >= count) < 0) | ||
60 | return 0; | ||
61 | |||
62 | dvb_ringbuffer_write(&dev->tsout_rbuf, buf, count); | ||
63 | |||
64 | return count; | ||
65 | } | ||
66 | |||
67 | static ssize_t ts_read(struct file *file, char *buf, | ||
68 | size_t count, loff_t *ppos) | ||
69 | { | ||
70 | struct dvb_device *dvbdev = file->private_data; | ||
71 | struct ngene_channel *chan = dvbdev->priv; | ||
72 | struct ngene *dev = chan->dev; | ||
73 | int left, avail; | ||
74 | |||
75 | left = count; | ||
76 | while (left) { | ||
77 | if (wait_event_interruptible( | ||
78 | dev->tsin_rbuf.queue, | ||
79 | dvb_ringbuffer_avail(&dev->tsin_rbuf) > 0) < 0) | ||
80 | return -EAGAIN; | ||
81 | avail = dvb_ringbuffer_avail(&dev->tsin_rbuf); | ||
82 | if (avail > left) | ||
83 | avail = left; | ||
84 | dvb_ringbuffer_read_user(&dev->tsin_rbuf, buf, avail); | ||
85 | left -= avail; | ||
86 | buf += avail; | ||
87 | } | ||
88 | return count; | ||
89 | } | ||
90 | |||
91 | static const struct file_operations ci_fops = { | ||
92 | .owner = THIS_MODULE, | ||
93 | .read = ts_read, | ||
94 | .write = ts_write, | ||
95 | .open = dvb_generic_open, | ||
96 | .release = dvb_generic_release, | ||
97 | }; | ||
98 | |||
99 | struct dvb_device ngene_dvbdev_ci = { | ||
100 | .priv = 0, | ||
101 | .readers = -1, | ||
102 | .writers = -1, | ||
103 | .users = -1, | ||
104 | .fops = &ci_fops, | ||
105 | }; | ||
106 | |||
107 | |||
50 | /****************************************************************************/ | 108 | /****************************************************************************/ |
51 | /* DVB functions and API interface ******************************************/ | 109 | /* DVB functions and API interface ******************************************/ |
52 | /****************************************************************************/ | 110 | /****************************************************************************/ |
@@ -63,10 +121,21 @@ static void swap_buffer(u32 *p, u32 len) | |||
63 | void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags) | 121 | void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags) |
64 | { | 122 | { |
65 | struct ngene_channel *chan = priv; | 123 | struct ngene_channel *chan = priv; |
124 | struct ngene *dev = chan->dev; | ||
66 | 125 | ||
67 | 126 | ||
68 | if (chan->users > 0) | 127 | if (flags & DF_SWAP32) |
128 | swap_buffer(buf, len); | ||
129 | if (dev->ci.en && chan->number == 2) { | ||
130 | if (dvb_ringbuffer_free(&dev->tsin_rbuf) > len) { | ||
131 | dvb_ringbuffer_write(&dev->tsin_rbuf, buf, len); | ||
132 | wake_up_interruptible(&dev->tsin_rbuf.queue); | ||
133 | } | ||
134 | return 0; | ||
135 | } | ||
136 | if (chan->users > 0) { | ||
69 | dvb_dmx_swfilter(&chan->demux, buf, len); | 137 | dvb_dmx_swfilter(&chan->demux, buf, len); |
138 | } | ||
70 | return NULL; | 139 | return NULL; |
71 | } | 140 | } |
72 | 141 | ||