0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/module.h>
0014 #include <linux/init.h>
0015 #include <linux/delay.h>
0016 #include <linux/slab.h>
0017 #include <linux/poll.h>
0018 #include <linux/io.h>
0019 #include <asm/div64.h>
0020 #include <linux/pci.h>
0021 #include <linux/timer.h>
0022 #include <linux/byteorder/generic.h>
0023 #include <linux/firmware.h>
0024 #include <linux/vmalloc.h>
0025
0026 #include "ngene.h"
0027
0028 static int ci_tsfix = 1;
0029 module_param(ci_tsfix, int, 0444);
0030 MODULE_PARM_DESC(ci_tsfix, "Detect and fix TS buffer offset shifts in conjunction with CI expansions (default: 1/enabled)");
0031
0032
0033
0034
0035
0036 static ssize_t ts_write(struct file *file, const char __user *buf,
0037 size_t count, loff_t *ppos)
0038 {
0039 struct dvb_device *dvbdev = file->private_data;
0040 struct ngene_channel *chan = dvbdev->priv;
0041 struct ngene *dev = chan->dev;
0042
0043 if (wait_event_interruptible(dev->tsout_rbuf.queue,
0044 dvb_ringbuffer_free
0045 (&dev->tsout_rbuf) >= count) < 0)
0046 return 0;
0047
0048 dvb_ringbuffer_write_user(&dev->tsout_rbuf, buf, count);
0049
0050 return count;
0051 }
0052
0053 static ssize_t ts_read(struct file *file, char __user *buf,
0054 size_t count, loff_t *ppos)
0055 {
0056 struct dvb_device *dvbdev = file->private_data;
0057 struct ngene_channel *chan = dvbdev->priv;
0058 struct ngene *dev = chan->dev;
0059 int left, avail;
0060
0061 left = count;
0062 while (left) {
0063 if (wait_event_interruptible(
0064 dev->tsin_rbuf.queue,
0065 dvb_ringbuffer_avail(&dev->tsin_rbuf) > 0) < 0)
0066 return -EAGAIN;
0067 avail = dvb_ringbuffer_avail(&dev->tsin_rbuf);
0068 if (avail > left)
0069 avail = left;
0070 dvb_ringbuffer_read_user(&dev->tsin_rbuf, buf, avail);
0071 left -= avail;
0072 buf += avail;
0073 }
0074 return count;
0075 }
0076
0077 static __poll_t ts_poll(struct file *file, poll_table *wait)
0078 {
0079 struct dvb_device *dvbdev = file->private_data;
0080 struct ngene_channel *chan = dvbdev->priv;
0081 struct ngene *dev = chan->dev;
0082 struct dvb_ringbuffer *rbuf = &dev->tsin_rbuf;
0083 struct dvb_ringbuffer *wbuf = &dev->tsout_rbuf;
0084 __poll_t mask = 0;
0085
0086 poll_wait(file, &rbuf->queue, wait);
0087 poll_wait(file, &wbuf->queue, wait);
0088
0089 if (!dvb_ringbuffer_empty(rbuf))
0090 mask |= EPOLLIN | EPOLLRDNORM;
0091 if (dvb_ringbuffer_free(wbuf) >= 188)
0092 mask |= EPOLLOUT | EPOLLWRNORM;
0093
0094 return mask;
0095 }
0096
0097 static const struct file_operations ci_fops = {
0098 .owner = THIS_MODULE,
0099 .read = ts_read,
0100 .write = ts_write,
0101 .open = dvb_generic_open,
0102 .release = dvb_generic_release,
0103 .poll = ts_poll,
0104 .mmap = NULL,
0105 };
0106
0107 struct dvb_device ngene_dvbdev_ci = {
0108 .priv = NULL,
0109 .readers = 1,
0110 .writers = 1,
0111 .users = 2,
0112 .fops = &ci_fops,
0113 };
0114
0115
0116
0117
0118
0119
0120 static void swap_buffer(u32 *p, u32 len)
0121 {
0122 while (len) {
0123 *p = swab32(*p);
0124 p++;
0125 len -= 4;
0126 }
0127 }
0128
0129
0130 static u8 fill_ts[] = { 0x47, 0x1f, 0xff, 0x10, TS_FILLER };
0131
0132 static int tsin_find_offset(void *buf, u32 len)
0133 {
0134 int i, l;
0135
0136 l = len - sizeof(fill_ts);
0137 if (l <= 0)
0138 return -1;
0139
0140 for (i = 0; i < l; i++) {
0141 if (((char *)buf)[i] == 0x47) {
0142 if (!memcmp(buf + i, fill_ts, sizeof(fill_ts)))
0143 return i % 188;
0144 }
0145 }
0146
0147 return -1;
0148 }
0149
0150 static inline void tsin_copy_stripped(struct ngene *dev, void *buf)
0151 {
0152 if (memcmp(buf, fill_ts, sizeof(fill_ts)) != 0) {
0153 if (dvb_ringbuffer_free(&dev->tsin_rbuf) >= 188) {
0154 dvb_ringbuffer_write(&dev->tsin_rbuf, buf, 188);
0155 wake_up(&dev->tsin_rbuf.queue);
0156 }
0157 }
0158 }
0159
0160 void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags)
0161 {
0162 struct ngene_channel *chan = priv;
0163 struct ngene *dev = chan->dev;
0164 int tsoff;
0165
0166 if (flags & DF_SWAP32)
0167 swap_buffer(buf, len);
0168
0169 if (dev->ci.en && chan->number == 2) {
0170
0171 if (!ci_tsfix) {
0172 while (len >= 188) {
0173 tsin_copy_stripped(dev, buf);
0174
0175 buf += 188;
0176 len -= 188;
0177 }
0178 return NULL;
0179 }
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189 if (chan->tsin_offset) {
0190 memcpy(&chan->tsin_buffer[(188 - chan->tsin_offset)],
0191 buf, chan->tsin_offset);
0192 tsin_copy_stripped(dev, &chan->tsin_buffer);
0193
0194 buf += chan->tsin_offset;
0195 len -= chan->tsin_offset;
0196 }
0197
0198
0199
0200
0201
0202 while (len >= 188) {
0203 if (*((char *)buf) != 0x47) {
0204
0205
0206
0207
0208 tsoff = tsin_find_offset(buf, len);
0209 if (tsoff > 0) {
0210 chan->tsin_offset += tsoff;
0211 chan->tsin_offset %= 188;
0212
0213 buf += tsoff;
0214 len -= tsoff;
0215
0216 dev_info(&dev->pci_dev->dev,
0217 "%s(): tsin_offset shift by %d on channel %d\n",
0218 __func__, tsoff,
0219 chan->number);
0220
0221
0222
0223
0224
0225
0226 if (len < 188)
0227 break;
0228 }
0229 }
0230
0231 tsin_copy_stripped(dev, buf);
0232
0233 buf += 188;
0234 len -= 188;
0235 }
0236
0237
0238
0239
0240
0241 if (len > 0 && len < 188)
0242 memcpy(&chan->tsin_buffer, buf, len);
0243
0244 return NULL;
0245 }
0246
0247 if (chan->users > 0)
0248 dvb_dmx_swfilter(&chan->demux, buf, len);
0249
0250 return NULL;
0251 }
0252
0253 void *tsout_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags)
0254 {
0255 struct ngene_channel *chan = priv;
0256 struct ngene *dev = chan->dev;
0257 u32 alen;
0258
0259 alen = dvb_ringbuffer_avail(&dev->tsout_rbuf);
0260 alen -= alen % 188;
0261
0262 if (alen < len)
0263 FillTSBuffer(buf + alen, len - alen, flags);
0264 else
0265 alen = len;
0266 dvb_ringbuffer_read(&dev->tsout_rbuf, buf, alen);
0267 if (flags & DF_SWAP32)
0268 swap_buffer((u32 *)buf, alen);
0269 wake_up_interruptible(&dev->tsout_rbuf.queue);
0270 return buf;
0271 }
0272
0273
0274
0275 int ngene_start_feed(struct dvb_demux_feed *dvbdmxfeed)
0276 {
0277 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
0278 struct ngene_channel *chan = dvbdmx->priv;
0279
0280 if (chan->users == 0) {
0281 if (!chan->dev->cmd_timeout_workaround || !chan->running)
0282 set_transfer(chan, 1);
0283 }
0284
0285 return ++chan->users;
0286 }
0287
0288 int ngene_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
0289 {
0290 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
0291 struct ngene_channel *chan = dvbdmx->priv;
0292
0293 if (--chan->users)
0294 return chan->users;
0295
0296 if (!chan->dev->cmd_timeout_workaround)
0297 set_transfer(chan, 0);
0298
0299 return 0;
0300 }
0301
0302 int my_dvb_dmx_ts_card_init(struct dvb_demux *dvbdemux, char *id,
0303 int (*start_feed)(struct dvb_demux_feed *),
0304 int (*stop_feed)(struct dvb_demux_feed *),
0305 void *priv)
0306 {
0307 dvbdemux->priv = priv;
0308
0309 dvbdemux->filternum = 256;
0310 dvbdemux->feednum = 256;
0311 dvbdemux->start_feed = start_feed;
0312 dvbdemux->stop_feed = stop_feed;
0313 dvbdemux->write_to_decoder = NULL;
0314 dvbdemux->dmx.capabilities = (DMX_TS_FILTERING |
0315 DMX_SECTION_FILTERING |
0316 DMX_MEMORY_BASED_FILTERING);
0317 return dvb_dmx_init(dvbdemux);
0318 }
0319
0320 int my_dvb_dmxdev_ts_card_init(struct dmxdev *dmxdev,
0321 struct dvb_demux *dvbdemux,
0322 struct dmx_frontend *hw_frontend,
0323 struct dmx_frontend *mem_frontend,
0324 struct dvb_adapter *dvb_adapter)
0325 {
0326 int ret;
0327
0328 dmxdev->filternum = 256;
0329 dmxdev->demux = &dvbdemux->dmx;
0330 dmxdev->capabilities = 0;
0331 ret = dvb_dmxdev_init(dmxdev, dvb_adapter);
0332 if (ret < 0)
0333 return ret;
0334
0335 hw_frontend->source = DMX_FRONTEND_0;
0336 dvbdemux->dmx.add_frontend(&dvbdemux->dmx, hw_frontend);
0337 mem_frontend->source = DMX_MEMORY_FE;
0338 dvbdemux->dmx.add_frontend(&dvbdemux->dmx, mem_frontend);
0339 return dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, hw_frontend);
0340 }