diff options
Diffstat (limited to 'drivers/media/dvb/ngene/ngene-dvb.c')
-rw-r--r-- | drivers/media/dvb/ngene/ngene-dvb.c | 72 |
1 files changed, 70 insertions, 2 deletions
diff --git a/drivers/media/dvb/ngene/ngene-dvb.c b/drivers/media/dvb/ngene/ngene-dvb.c index 48f980b21d66..0b4943233166 100644 --- a/drivers/media/dvb/ngene/ngene-dvb.c +++ b/drivers/media/dvb/ngene/ngene-dvb.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <linux/io.h> | 35 | #include <linux/io.h> |
36 | #include <asm/div64.h> | 36 | #include <asm/div64.h> |
37 | #include <linux/pci.h> | 37 | #include <linux/pci.h> |
38 | #include <linux/smp_lock.h> | ||
39 | #include <linux/timer.h> | 38 | #include <linux/timer.h> |
40 | #include <linux/byteorder/generic.h> | 39 | #include <linux/byteorder/generic.h> |
41 | #include <linux/firmware.h> | 40 | #include <linux/firmware.h> |
@@ -48,6 +47,64 @@ | |||
48 | /* COMMAND API interface ****************************************************/ | 47 | /* COMMAND API interface ****************************************************/ |
49 | /****************************************************************************/ | 48 | /****************************************************************************/ |
50 | 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 | |||
51 | /****************************************************************************/ | 108 | /****************************************************************************/ |
52 | /* DVB functions and API interface ******************************************/ | 109 | /* DVB functions and API interface ******************************************/ |
53 | /****************************************************************************/ | 110 | /****************************************************************************/ |
@@ -64,10 +121,21 @@ static void swap_buffer(u32 *p, u32 len) | |||
64 | 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) |
65 | { | 122 | { |
66 | struct ngene_channel *chan = priv; | 123 | struct ngene_channel *chan = priv; |
124 | struct ngene *dev = chan->dev; | ||
67 | 125 | ||
68 | 126 | ||
69 | 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) { | ||
70 | dvb_dmx_swfilter(&chan->demux, buf, len); | 137 | dvb_dmx_swfilter(&chan->demux, buf, len); |
138 | } | ||
71 | return NULL; | 139 | return NULL; |
72 | } | 140 | } |
73 | 141 | ||