aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/dvb-core
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/media/dvb/dvb-core
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'drivers/media/dvb/dvb-core')
-rw-r--r--drivers/media/dvb/dvb-core/Makefile11
-rw-r--r--drivers/media/dvb/dvb-core/demux.h280
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.c1278
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.h118
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ca_en50221.c1749
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ca_en50221.h136
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.c1299
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.h149
-rw-r--r--drivers/media/dvb/dvb-core/dvb_filter.c603
-rw-r--r--drivers/media/dvb/dvb-core/dvb_filter.h246
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c2173
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.h392
-rw-r--r--drivers/media/dvb/dvb-core/dvb_math.c145
-rw-r--r--drivers/media/dvb/dvb-core/dvb_math.h58
-rw-r--r--drivers/media/dvb/dvb-core/dvb_net.c1518
-rw-r--r--drivers/media/dvb/dvb-core/dvb_net.h66
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ringbuffer.c299
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ringbuffer.h186
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.c506
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.h172
20 files changed, 11384 insertions, 0 deletions
diff --git a/drivers/media/dvb/dvb-core/Makefile b/drivers/media/dvb/dvb-core/Makefile
new file mode 100644
index 00000000000..8f22bcd7c1f
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/Makefile
@@ -0,0 +1,11 @@
1#
2# Makefile for the kernel DVB device drivers.
3#
4
5dvb-net-$(CONFIG_DVB_NET) := dvb_net.o
6
7dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \
8 dvb_ca_en50221.o dvb_frontend.o \
9 $(dvb-net-y) dvb_ringbuffer.o dvb_math.o
10
11obj-$(CONFIG_DVB_CORE) += dvb-core.o
diff --git a/drivers/media/dvb/dvb-core/demux.h b/drivers/media/dvb/dvb-core/demux.h
new file mode 100644
index 00000000000..eb91fd808c1
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/demux.h
@@ -0,0 +1,280 @@
1/*
2 * demux.h
3 *
4 * Copyright (c) 2002 Convergence GmbH
5 *
6 * based on code:
7 * Copyright (c) 2000 Nokia Research Center
8 * Tampere, FINLAND
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public License
12 * as published by the Free Software Foundation; either version 2.1
13 * of the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 *
24 */
25
26#ifndef __DEMUX_H
27#define __DEMUX_H
28
29#include <linux/types.h>
30#include <linux/errno.h>
31#include <linux/list.h>
32#include <linux/time.h>
33#include <linux/dvb/dmx.h>
34
35/*--------------------------------------------------------------------------*/
36/* Common definitions */
37/*--------------------------------------------------------------------------*/
38
39/*
40 * DMX_MAX_FILTER_SIZE: Maximum length (in bytes) of a section/PES filter.
41 */
42
43#ifndef DMX_MAX_FILTER_SIZE
44#define DMX_MAX_FILTER_SIZE 18
45#endif
46
47/*
48 * DMX_MAX_SECFEED_SIZE: Maximum length (in bytes) of a private section feed filter.
49 */
50
51#ifndef DMX_MAX_SECTION_SIZE
52#define DMX_MAX_SECTION_SIZE 4096
53#endif
54#ifndef DMX_MAX_SECFEED_SIZE
55#define DMX_MAX_SECFEED_SIZE (DMX_MAX_SECTION_SIZE + 188)
56#endif
57
58
59/*
60 * enum dmx_success: Success codes for the Demux Callback API.
61 */
62
63enum dmx_success {
64 DMX_OK = 0, /* Received Ok */
65 DMX_LENGTH_ERROR, /* Incorrect length */
66 DMX_OVERRUN_ERROR, /* Receiver ring buffer overrun */
67 DMX_CRC_ERROR, /* Incorrect CRC */
68 DMX_FRAME_ERROR, /* Frame alignment error */
69 DMX_FIFO_ERROR, /* Receiver FIFO overrun */
70 DMX_MISSED_ERROR /* Receiver missed packet */
71} ;
72
73/*--------------------------------------------------------------------------*/
74/* TS packet reception */
75/*--------------------------------------------------------------------------*/
76
77/* TS filter type for set() */
78
79#define TS_PACKET 1 /* send TS packets (188 bytes) to callback (default) */
80#define TS_PAYLOAD_ONLY 2 /* in case TS_PACKET is set, only send the TS
81 payload (<=184 bytes per packet) to callback */
82#define TS_DECODER 4 /* send stream to built-in decoder (if present) */
83#define TS_DEMUX 8 /* in case TS_PACKET is set, send the TS to
84 the demux device, not to the dvr device */
85
86/* PES type for filters which write to built-in decoder */
87/* these should be kept identical to the types in dmx.h */
88
89enum dmx_ts_pes
90{ /* also send packets to decoder (if it exists) */
91 DMX_TS_PES_AUDIO0,
92 DMX_TS_PES_VIDEO0,
93 DMX_TS_PES_TELETEXT0,
94 DMX_TS_PES_SUBTITLE0,
95 DMX_TS_PES_PCR0,
96
97 DMX_TS_PES_AUDIO1,
98 DMX_TS_PES_VIDEO1,
99 DMX_TS_PES_TELETEXT1,
100 DMX_TS_PES_SUBTITLE1,
101 DMX_TS_PES_PCR1,
102
103 DMX_TS_PES_AUDIO2,
104 DMX_TS_PES_VIDEO2,
105 DMX_TS_PES_TELETEXT2,
106 DMX_TS_PES_SUBTITLE2,
107 DMX_TS_PES_PCR2,
108
109 DMX_TS_PES_AUDIO3,
110 DMX_TS_PES_VIDEO3,
111 DMX_TS_PES_TELETEXT3,
112 DMX_TS_PES_SUBTITLE3,
113 DMX_TS_PES_PCR3,
114
115 DMX_TS_PES_OTHER
116};
117
118#define DMX_TS_PES_AUDIO DMX_TS_PES_AUDIO0
119#define DMX_TS_PES_VIDEO DMX_TS_PES_VIDEO0
120#define DMX_TS_PES_TELETEXT DMX_TS_PES_TELETEXT0
121#define DMX_TS_PES_SUBTITLE DMX_TS_PES_SUBTITLE0
122#define DMX_TS_PES_PCR DMX_TS_PES_PCR0
123
124
125struct dmx_ts_feed {
126 int is_filtering; /* Set to non-zero when filtering in progress */
127 struct dmx_demux *parent; /* Back-pointer */
128 void *priv; /* Pointer to private data of the API client */
129 int (*set) (struct dmx_ts_feed *feed,
130 u16 pid,
131 int type,
132 enum dmx_ts_pes pes_type,
133 size_t circular_buffer_size,
134 struct timespec timeout);
135 int (*start_filtering) (struct dmx_ts_feed* feed);
136 int (*stop_filtering) (struct dmx_ts_feed* feed);
137};
138
139/*--------------------------------------------------------------------------*/
140/* Section reception */
141/*--------------------------------------------------------------------------*/
142
143struct dmx_section_filter {
144 u8 filter_value [DMX_MAX_FILTER_SIZE];
145 u8 filter_mask [DMX_MAX_FILTER_SIZE];
146 u8 filter_mode [DMX_MAX_FILTER_SIZE];
147 struct dmx_section_feed* parent; /* Back-pointer */
148 void* priv; /* Pointer to private data of the API client */
149};
150
151struct dmx_section_feed {
152 int is_filtering; /* Set to non-zero when filtering in progress */
153 struct dmx_demux* parent; /* Back-pointer */
154 void* priv; /* Pointer to private data of the API client */
155
156 int check_crc;
157 u32 crc_val;
158
159 u8 *secbuf;
160 u8 secbuf_base[DMX_MAX_SECFEED_SIZE];
161 u16 secbufp, seclen, tsfeedp;
162
163 int (*set) (struct dmx_section_feed* feed,
164 u16 pid,
165 size_t circular_buffer_size,
166 int check_crc);
167 int (*allocate_filter) (struct dmx_section_feed* feed,
168 struct dmx_section_filter** filter);
169 int (*release_filter) (struct dmx_section_feed* feed,
170 struct dmx_section_filter* filter);
171 int (*start_filtering) (struct dmx_section_feed* feed);
172 int (*stop_filtering) (struct dmx_section_feed* feed);
173};
174
175/*--------------------------------------------------------------------------*/
176/* Callback functions */
177/*--------------------------------------------------------------------------*/
178
179typedef int (*dmx_ts_cb) ( const u8 * buffer1,
180 size_t buffer1_length,
181 const u8 * buffer2,
182 size_t buffer2_length,
183 struct dmx_ts_feed* source,
184 enum dmx_success success);
185
186typedef int (*dmx_section_cb) ( const u8 * buffer1,
187 size_t buffer1_len,
188 const u8 * buffer2,
189 size_t buffer2_len,
190 struct dmx_section_filter * source,
191 enum dmx_success success);
192
193/*--------------------------------------------------------------------------*/
194/* DVB Front-End */
195/*--------------------------------------------------------------------------*/
196
197enum dmx_frontend_source {
198 DMX_MEMORY_FE,
199 DMX_FRONTEND_0,
200 DMX_FRONTEND_1,
201 DMX_FRONTEND_2,
202 DMX_FRONTEND_3,
203 DMX_STREAM_0, /* external stream input, e.g. LVDS */
204 DMX_STREAM_1,
205 DMX_STREAM_2,
206 DMX_STREAM_3
207};
208
209struct dmx_frontend {
210 struct list_head connectivity_list; /* List of front-ends that can
211 be connected to a particular
212 demux */
213 enum dmx_frontend_source source;
214};
215
216/*--------------------------------------------------------------------------*/
217/* MPEG-2 TS Demux */
218/*--------------------------------------------------------------------------*/
219
220/*
221 * Flags OR'ed in the capabilities field of struct dmx_demux.
222 */
223
224#define DMX_TS_FILTERING 1
225#define DMX_PES_FILTERING 2
226#define DMX_SECTION_FILTERING 4
227#define DMX_MEMORY_BASED_FILTERING 8 /* write() available */
228#define DMX_CRC_CHECKING 16
229#define DMX_TS_DESCRAMBLING 32
230
231/*
232 * Demux resource type identifier.
233*/
234
235/*
236 * DMX_FE_ENTRY(): Casts elements in the list of registered
237 * front-ends from the generic type struct list_head
238 * to the type * struct dmx_frontend
239 *.
240*/
241
242#define DMX_FE_ENTRY(list) list_entry(list, struct dmx_frontend, connectivity_list)
243
244struct dmx_demux {
245 u32 capabilities; /* Bitfield of capability flags */
246 struct dmx_frontend* frontend; /* Front-end connected to the demux */
247 void* priv; /* Pointer to private data of the API client */
248 int (*open) (struct dmx_demux* demux);
249 int (*close) (struct dmx_demux* demux);
250 int (*write) (struct dmx_demux* demux, const char __user *buf, size_t count);
251 int (*allocate_ts_feed) (struct dmx_demux* demux,
252 struct dmx_ts_feed** feed,
253 dmx_ts_cb callback);
254 int (*release_ts_feed) (struct dmx_demux* demux,
255 struct dmx_ts_feed* feed);
256 int (*allocate_section_feed) (struct dmx_demux* demux,
257 struct dmx_section_feed** feed,
258 dmx_section_cb callback);
259 int (*release_section_feed) (struct dmx_demux* demux,
260 struct dmx_section_feed* feed);
261 int (*add_frontend) (struct dmx_demux* demux,
262 struct dmx_frontend* frontend);
263 int (*remove_frontend) (struct dmx_demux* demux,
264 struct dmx_frontend* frontend);
265 struct list_head* (*get_frontends) (struct dmx_demux* demux);
266 int (*connect_frontend) (struct dmx_demux* demux,
267 struct dmx_frontend* frontend);
268 int (*disconnect_frontend) (struct dmx_demux* demux);
269
270 int (*get_pes_pids) (struct dmx_demux* demux, u16 *pids);
271
272 int (*get_caps) (struct dmx_demux* demux, struct dmx_caps *caps);
273
274 int (*set_source) (struct dmx_demux* demux, const dmx_source_t *src);
275
276 int (*get_stc) (struct dmx_demux* demux, unsigned int num,
277 u64 *stc, unsigned int *base);
278};
279
280#endif /* #ifndef __DEMUX_H */
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
new file mode 100644
index 00000000000..e4b5c03ae51
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -0,0 +1,1278 @@
1/*
2 * dmxdev.c - DVB demultiplexer device
3 *
4 * Copyright (C) 2000 Ralph Metzler & Marcus Metzler
5 * for convergence integrated media GmbH
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation; either version 2.1
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 *
21 */
22
23#include <linux/sched.h>
24#include <linux/spinlock.h>
25#include <linux/slab.h>
26#include <linux/vmalloc.h>
27#include <linux/module.h>
28#include <linux/poll.h>
29#include <linux/ioctl.h>
30#include <linux/wait.h>
31#include <asm/uaccess.h>
32#include <asm/system.h>
33#include "dmxdev.h"
34
35static int debug;
36
37module_param(debug, int, 0644);
38MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
39
40#define dprintk if (debug) printk
41
42static int dvb_dmxdev_buffer_write(struct dvb_ringbuffer *buf,
43 const u8 *src, size_t len)
44{
45 ssize_t free;
46
47 if (!len)
48 return 0;
49 if (!buf->data)
50 return 0;
51
52 free = dvb_ringbuffer_free(buf);
53 if (len > free) {
54 dprintk("dmxdev: buffer overflow\n");
55 return -EOVERFLOW;
56 }
57
58 return dvb_ringbuffer_write(buf, src, len);
59}
60
61static ssize_t dvb_dmxdev_buffer_read(struct dvb_ringbuffer *src,
62 int non_blocking, char __user *buf,
63 size_t count, loff_t *ppos)
64{
65 size_t todo;
66 ssize_t avail;
67 ssize_t ret = 0;
68
69 if (!src->data)
70 return 0;
71
72 if (src->error) {
73 ret = src->error;
74 dvb_ringbuffer_flush(src);
75 return ret;
76 }
77
78 for (todo = count; todo > 0; todo -= ret) {
79 if (non_blocking && dvb_ringbuffer_empty(src)) {
80 ret = -EWOULDBLOCK;
81 break;
82 }
83
84 ret = wait_event_interruptible(src->queue,
85 !dvb_ringbuffer_empty(src) ||
86 (src->error != 0));
87 if (ret < 0)
88 break;
89
90 if (src->error) {
91 ret = src->error;
92 dvb_ringbuffer_flush(src);
93 break;
94 }
95
96 avail = dvb_ringbuffer_avail(src);
97 if (avail > todo)
98 avail = todo;
99
100 ret = dvb_ringbuffer_read_user(src, buf, avail);
101 if (ret < 0)
102 break;
103
104 buf += ret;
105 }
106
107 return (count - todo) ? (count - todo) : ret;
108}
109
110static struct dmx_frontend *get_fe(struct dmx_demux *demux, int type)
111{
112 struct list_head *head, *pos;
113
114 head = demux->get_frontends(demux);
115 if (!head)
116 return NULL;
117 list_for_each(pos, head)
118 if (DMX_FE_ENTRY(pos)->source == type)
119 return DMX_FE_ENTRY(pos);
120
121 return NULL;
122}
123
124static int dvb_dvr_open(struct inode *inode, struct file *file)
125{
126 struct dvb_device *dvbdev = file->private_data;
127 struct dmxdev *dmxdev = dvbdev->priv;
128 struct dmx_frontend *front;
129
130 dprintk("function : %s\n", __func__);
131
132 if (mutex_lock_interruptible(&dmxdev->mutex))
133 return -ERESTARTSYS;
134
135 if (dmxdev->exit) {
136 mutex_unlock(&dmxdev->mutex);
137 return -ENODEV;
138 }
139
140 if ((file->f_flags & O_ACCMODE) == O_RDWR) {
141 if (!(dmxdev->capabilities & DMXDEV_CAP_DUPLEX)) {
142 mutex_unlock(&dmxdev->mutex);
143 return -EOPNOTSUPP;
144 }
145 }
146
147 if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
148 void *mem;
149 if (!dvbdev->readers) {
150 mutex_unlock(&dmxdev->mutex);
151 return -EBUSY;
152 }
153 mem = vmalloc(DVR_BUFFER_SIZE);
154 if (!mem) {
155 mutex_unlock(&dmxdev->mutex);
156 return -ENOMEM;
157 }
158 dvb_ringbuffer_init(&dmxdev->dvr_buffer, mem, DVR_BUFFER_SIZE);
159 dvbdev->readers--;
160 }
161
162 if ((file->f_flags & O_ACCMODE) == O_WRONLY) {
163 dmxdev->dvr_orig_fe = dmxdev->demux->frontend;
164
165 if (!dmxdev->demux->write) {
166 mutex_unlock(&dmxdev->mutex);
167 return -EOPNOTSUPP;
168 }
169
170 front = get_fe(dmxdev->demux, DMX_MEMORY_FE);
171
172 if (!front) {
173 mutex_unlock(&dmxdev->mutex);
174 return -EINVAL;
175 }
176 dmxdev->demux->disconnect_frontend(dmxdev->demux);
177 dmxdev->demux->connect_frontend(dmxdev->demux, front);
178 }
179 dvbdev->users++;
180 mutex_unlock(&dmxdev->mutex);
181 return 0;
182}
183
184static int dvb_dvr_release(struct inode *inode, struct file *file)
185{
186 struct dvb_device *dvbdev = file->private_data;
187 struct dmxdev *dmxdev = dvbdev->priv;
188
189 mutex_lock(&dmxdev->mutex);
190
191 if ((file->f_flags & O_ACCMODE) == O_WRONLY) {
192 dmxdev->demux->disconnect_frontend(dmxdev->demux);
193 dmxdev->demux->connect_frontend(dmxdev->demux,
194 dmxdev->dvr_orig_fe);
195 }
196 if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
197 dvbdev->readers++;
198 if (dmxdev->dvr_buffer.data) {
199 void *mem = dmxdev->dvr_buffer.data;
200 mb();
201 spin_lock_irq(&dmxdev->lock);
202 dmxdev->dvr_buffer.data = NULL;
203 spin_unlock_irq(&dmxdev->lock);
204 vfree(mem);
205 }
206 }
207 /* TODO */
208 dvbdev->users--;
209 if (dvbdev->users == 1 && dmxdev->exit == 1) {
210 fops_put(file->f_op);
211 file->f_op = NULL;
212 mutex_unlock(&dmxdev->mutex);
213 wake_up(&dvbdev->wait_queue);
214 } else
215 mutex_unlock(&dmxdev->mutex);
216
217 return 0;
218}
219
220static ssize_t dvb_dvr_write(struct file *file, const char __user *buf,
221 size_t count, loff_t *ppos)
222{
223 struct dvb_device *dvbdev = file->private_data;
224 struct dmxdev *dmxdev = dvbdev->priv;
225 int ret;
226
227 if (!dmxdev->demux->write)
228 return -EOPNOTSUPP;
229 if ((file->f_flags & O_ACCMODE) != O_WRONLY)
230 return -EINVAL;
231 if (mutex_lock_interruptible(&dmxdev->mutex))
232 return -ERESTARTSYS;
233
234 if (dmxdev->exit) {
235 mutex_unlock(&dmxdev->mutex);
236 return -ENODEV;
237 }
238 ret = dmxdev->demux->write(dmxdev->demux, buf, count);
239 mutex_unlock(&dmxdev->mutex);
240 return ret;
241}
242
243static ssize_t dvb_dvr_read(struct file *file, char __user *buf, size_t count,
244 loff_t *ppos)
245{
246 struct dvb_device *dvbdev = file->private_data;
247 struct dmxdev *dmxdev = dvbdev->priv;
248
249 if (dmxdev->exit)
250 return -ENODEV;
251
252 return dvb_dmxdev_buffer_read(&dmxdev->dvr_buffer,
253 file->f_flags & O_NONBLOCK,
254 buf, count, ppos);
255}
256
257static int dvb_dvr_set_buffer_size(struct dmxdev *dmxdev,
258 unsigned long size)
259{
260 struct dvb_ringbuffer *buf = &dmxdev->dvr_buffer;
261 void *newmem;
262 void *oldmem;
263
264 dprintk("function : %s\n", __func__);
265
266 if (buf->size == size)
267 return 0;
268 if (!size)
269 return -EINVAL;
270
271 newmem = vmalloc(size);
272 if (!newmem)
273 return -ENOMEM;
274
275 oldmem = buf->data;
276
277 spin_lock_irq(&dmxdev->lock);
278 buf->data = newmem;
279 buf->size = size;
280
281 /* reset and not flush in case the buffer shrinks */
282 dvb_ringbuffer_reset(buf);
283 spin_unlock_irq(&dmxdev->lock);
284
285 vfree(oldmem);
286
287 return 0;
288}
289
290static inline void dvb_dmxdev_filter_state_set(struct dmxdev_filter
291 *dmxdevfilter, int state)
292{
293 spin_lock_irq(&dmxdevfilter->dev->lock);
294 dmxdevfilter->state = state;
295 spin_unlock_irq(&dmxdevfilter->dev->lock);
296}
297
298static int dvb_dmxdev_set_buffer_size(struct dmxdev_filter *dmxdevfilter,
299 unsigned long size)
300{
301 struct dvb_ringbuffer *buf = &dmxdevfilter->buffer;
302 void *newmem;
303 void *oldmem;
304
305 if (buf->size == size)
306 return 0;
307 if (!size)
308 return -EINVAL;
309 if (dmxdevfilter->state >= DMXDEV_STATE_GO)
310 return -EBUSY;
311
312 newmem = vmalloc(size);
313 if (!newmem)
314 return -ENOMEM;
315
316 oldmem = buf->data;
317
318 spin_lock_irq(&dmxdevfilter->dev->lock);
319 buf->data = newmem;
320 buf->size = size;
321
322 /* reset and not flush in case the buffer shrinks */
323 dvb_ringbuffer_reset(buf);
324 spin_unlock_irq(&dmxdevfilter->dev->lock);
325
326 vfree(oldmem);
327
328 return 0;
329}
330
331static void dvb_dmxdev_filter_timeout(unsigned long data)
332{
333 struct dmxdev_filter *dmxdevfilter = (struct dmxdev_filter *)data;
334
335 dmxdevfilter->buffer.error = -ETIMEDOUT;
336 spin_lock_irq(&dmxdevfilter->dev->lock);
337 dmxdevfilter->state = DMXDEV_STATE_TIMEDOUT;
338 spin_unlock_irq(&dmxdevfilter->dev->lock);
339 wake_up(&dmxdevfilter->buffer.queue);
340}
341
342static void dvb_dmxdev_filter_timer(struct dmxdev_filter *dmxdevfilter)
343{
344 struct dmx_sct_filter_params *para = &dmxdevfilter->params.sec;
345
346 del_timer(&dmxdevfilter->timer);
347 if (para->timeout) {
348 dmxdevfilter->timer.function = dvb_dmxdev_filter_timeout;
349 dmxdevfilter->timer.data = (unsigned long)dmxdevfilter;
350 dmxdevfilter->timer.expires =
351 jiffies + 1 + (HZ / 2 + HZ * para->timeout) / 1000;
352 add_timer(&dmxdevfilter->timer);
353 }
354}
355
356static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
357 const u8 *buffer2, size_t buffer2_len,
358 struct dmx_section_filter *filter,
359 enum dmx_success success)
360{
361 struct dmxdev_filter *dmxdevfilter = filter->priv;
362 int ret;
363
364 if (dmxdevfilter->buffer.error) {
365 wake_up(&dmxdevfilter->buffer.queue);
366 return 0;
367 }
368 spin_lock(&dmxdevfilter->dev->lock);
369 if (dmxdevfilter->state != DMXDEV_STATE_GO) {
370 spin_unlock(&dmxdevfilter->dev->lock);
371 return 0;
372 }
373 del_timer(&dmxdevfilter->timer);
374 dprintk("dmxdev: section callback %02x %02x %02x %02x %02x %02x\n",
375 buffer1[0], buffer1[1],
376 buffer1[2], buffer1[3], buffer1[4], buffer1[5]);
377 ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer1,
378 buffer1_len);
379 if (ret == buffer1_len) {
380 ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer2,
381 buffer2_len);
382 }
383 if (ret < 0) {
384 dvb_ringbuffer_flush(&dmxdevfilter->buffer);
385 dmxdevfilter->buffer.error = ret;
386 }
387 if (dmxdevfilter->params.sec.flags & DMX_ONESHOT)
388 dmxdevfilter->state = DMXDEV_STATE_DONE;
389 spin_unlock(&dmxdevfilter->dev->lock);
390 wake_up(&dmxdevfilter->buffer.queue);
391 return 0;
392}
393
394static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
395 const u8 *buffer2, size_t buffer2_len,
396 struct dmx_ts_feed *feed,
397 enum dmx_success success)
398{
399 struct dmxdev_filter *dmxdevfilter = feed->priv;
400 struct dvb_ringbuffer *buffer;
401 int ret;
402
403 spin_lock(&dmxdevfilter->dev->lock);
404 if (dmxdevfilter->params.pes.output == DMX_OUT_DECODER) {
405 spin_unlock(&dmxdevfilter->dev->lock);
406 return 0;
407 }
408
409 if (dmxdevfilter->params.pes.output == DMX_OUT_TAP
410 || dmxdevfilter->params.pes.output == DMX_OUT_TSDEMUX_TAP)
411 buffer = &dmxdevfilter->buffer;
412 else
413 buffer = &dmxdevfilter->dev->dvr_buffer;
414 if (buffer->error) {
415 spin_unlock(&dmxdevfilter->dev->lock);
416 wake_up(&buffer->queue);
417 return 0;
418 }
419 ret = dvb_dmxdev_buffer_write(buffer, buffer1, buffer1_len);
420 if (ret == buffer1_len)
421 ret = dvb_dmxdev_buffer_write(buffer, buffer2, buffer2_len);
422 if (ret < 0) {
423 dvb_ringbuffer_flush(buffer);
424 buffer->error = ret;
425 }
426 spin_unlock(&dmxdevfilter->dev->lock);
427 wake_up(&buffer->queue);
428 return 0;
429}
430
431/* stop feed but only mark the specified filter as stopped (state set) */
432static int dvb_dmxdev_feed_stop(struct dmxdev_filter *dmxdevfilter)
433{
434 struct dmxdev_feed *feed;
435
436 dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET);
437
438 switch (dmxdevfilter->type) {
439 case DMXDEV_TYPE_SEC:
440 del_timer(&dmxdevfilter->timer);
441 dmxdevfilter->feed.sec->stop_filtering(dmxdevfilter->feed.sec);
442 break;
443 case DMXDEV_TYPE_PES:
444 list_for_each_entry(feed, &dmxdevfilter->feed.ts, next)
445 feed->ts->stop_filtering(feed->ts);
446 break;
447 default:
448 return -EINVAL;
449 }
450 return 0;
451}
452
453/* start feed associated with the specified filter */
454static int dvb_dmxdev_feed_start(struct dmxdev_filter *filter)
455{
456 struct dmxdev_feed *feed;
457 int ret;
458
459 dvb_dmxdev_filter_state_set(filter, DMXDEV_STATE_GO);
460
461 switch (filter->type) {
462 case DMXDEV_TYPE_SEC:
463 return filter->feed.sec->start_filtering(filter->feed.sec);
464 case DMXDEV_TYPE_PES:
465 list_for_each_entry(feed, &filter->feed.ts, next) {
466 ret = feed->ts->start_filtering(feed->ts);
467 if (ret < 0) {
468 dvb_dmxdev_feed_stop(filter);
469 return ret;
470 }
471 }
472 break;
473 default:
474 return -EINVAL;
475 }
476
477 return 0;
478}
479
480/* restart section feed if it has filters left associated with it,
481 otherwise release the feed */
482static int dvb_dmxdev_feed_restart(struct dmxdev_filter *filter)
483{
484 int i;
485 struct dmxdev *dmxdev = filter->dev;
486 u16 pid = filter->params.sec.pid;
487
488 for (i = 0; i < dmxdev->filternum; i++)
489 if (dmxdev->filter[i].state >= DMXDEV_STATE_GO &&
490 dmxdev->filter[i].type == DMXDEV_TYPE_SEC &&
491 dmxdev->filter[i].params.sec.pid == pid) {
492 dvb_dmxdev_feed_start(&dmxdev->filter[i]);
493 return 0;
494 }
495
496 filter->dev->demux->release_section_feed(dmxdev->demux,
497 filter->feed.sec);
498
499 return 0;
500}
501
502static int dvb_dmxdev_filter_stop(struct dmxdev_filter *dmxdevfilter)
503{
504 struct dmxdev_feed *feed;
505 struct dmx_demux *demux;
506
507 if (dmxdevfilter->state < DMXDEV_STATE_GO)
508 return 0;
509
510 switch (dmxdevfilter->type) {
511 case DMXDEV_TYPE_SEC:
512 if (!dmxdevfilter->feed.sec)
513 break;
514 dvb_dmxdev_feed_stop(dmxdevfilter);
515 if (dmxdevfilter->filter.sec)
516 dmxdevfilter->feed.sec->
517 release_filter(dmxdevfilter->feed.sec,
518 dmxdevfilter->filter.sec);
519 dvb_dmxdev_feed_restart(dmxdevfilter);
520 dmxdevfilter->feed.sec = NULL;
521 break;
522 case DMXDEV_TYPE_PES:
523 dvb_dmxdev_feed_stop(dmxdevfilter);
524 demux = dmxdevfilter->dev->demux;
525 list_for_each_entry(feed, &dmxdevfilter->feed.ts, next) {
526 demux->release_ts_feed(demux, feed->ts);
527 feed->ts = NULL;
528 }
529 break;
530 default:
531 if (dmxdevfilter->state == DMXDEV_STATE_ALLOCATED)
532 return 0;
533 return -EINVAL;
534 }
535
536 dvb_ringbuffer_flush(&dmxdevfilter->buffer);
537 return 0;
538}
539
540static void dvb_dmxdev_delete_pids(struct dmxdev_filter *dmxdevfilter)
541{
542 struct dmxdev_feed *feed, *tmp;
543
544 /* delete all PIDs */
545 list_for_each_entry_safe(feed, tmp, &dmxdevfilter->feed.ts, next) {
546 list_del(&feed->next);
547 kfree(feed);
548 }
549
550 BUG_ON(!list_empty(&dmxdevfilter->feed.ts));
551}
552
553static inline int dvb_dmxdev_filter_reset(struct dmxdev_filter *dmxdevfilter)
554{
555 if (dmxdevfilter->state < DMXDEV_STATE_SET)
556 return 0;
557
558 if (dmxdevfilter->type == DMXDEV_TYPE_PES)
559 dvb_dmxdev_delete_pids(dmxdevfilter);
560
561 dmxdevfilter->type = DMXDEV_TYPE_NONE;
562 dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED);
563 return 0;
564}
565
566static int dvb_dmxdev_start_feed(struct dmxdev *dmxdev,
567 struct dmxdev_filter *filter,
568 struct dmxdev_feed *feed)
569{
570 struct timespec timeout = { 0 };
571 struct dmx_pes_filter_params *para = &filter->params.pes;
572 dmx_output_t otype;
573 int ret;
574 int ts_type;
575 dmx_pes_type_t ts_pes;
576 struct dmx_ts_feed *tsfeed;
577
578 feed->ts = NULL;
579 otype = para->output;
580
581 ts_pes = para->pes_type;
582
583 if (ts_pes < DMX_PES_OTHER)
584 ts_type = TS_DECODER;
585 else
586 ts_type = 0;
587
588 if (otype == DMX_OUT_TS_TAP)
589 ts_type |= TS_PACKET;
590 else if (otype == DMX_OUT_TSDEMUX_TAP)
591 ts_type |= TS_PACKET | TS_DEMUX;
592 else if (otype == DMX_OUT_TAP)
593 ts_type |= TS_PACKET | TS_DEMUX | TS_PAYLOAD_ONLY;
594
595 ret = dmxdev->demux->allocate_ts_feed(dmxdev->demux, &feed->ts,
596 dvb_dmxdev_ts_callback);
597 if (ret < 0)
598 return ret;
599
600 tsfeed = feed->ts;
601 tsfeed->priv = filter;
602
603 ret = tsfeed->set(tsfeed, feed->pid, ts_type, ts_pes, 32768, timeout);
604 if (ret < 0) {
605 dmxdev->demux->release_ts_feed(dmxdev->demux, tsfeed);
606 return ret;
607 }
608
609 ret = tsfeed->start_filtering(tsfeed);
610 if (ret < 0) {
611 dmxdev->demux->release_ts_feed(dmxdev->demux, tsfeed);
612 return ret;
613 }
614
615 return 0;
616}
617
618static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
619{
620 struct dmxdev *dmxdev = filter->dev;
621 struct dmxdev_feed *feed;
622 void *mem;
623 int ret, i;
624
625 if (filter->state < DMXDEV_STATE_SET)
626 return -EINVAL;
627
628 if (filter->state >= DMXDEV_STATE_GO)
629 dvb_dmxdev_filter_stop(filter);
630
631 if (!filter->buffer.data) {
632 mem = vmalloc(filter->buffer.size);
633 if (!mem)
634 return -ENOMEM;
635 spin_lock_irq(&filter->dev->lock);
636 filter->buffer.data = mem;
637 spin_unlock_irq(&filter->dev->lock);
638 }
639
640 dvb_ringbuffer_flush(&filter->buffer);
641
642 switch (filter->type) {
643 case DMXDEV_TYPE_SEC:
644 {
645 struct dmx_sct_filter_params *para = &filter->params.sec;
646 struct dmx_section_filter **secfilter = &filter->filter.sec;
647 struct dmx_section_feed **secfeed = &filter->feed.sec;
648
649 *secfilter = NULL;
650 *secfeed = NULL;
651
652
653 /* find active filter/feed with same PID */
654 for (i = 0; i < dmxdev->filternum; i++) {
655 if (dmxdev->filter[i].state >= DMXDEV_STATE_GO &&
656 dmxdev->filter[i].type == DMXDEV_TYPE_SEC &&
657 dmxdev->filter[i].params.sec.pid == para->pid) {
658 *secfeed = dmxdev->filter[i].feed.sec;
659 break;
660 }
661 }
662
663 /* if no feed found, try to allocate new one */
664 if (!*secfeed) {
665 ret = dmxdev->demux->allocate_section_feed(dmxdev->demux,
666 secfeed,
667 dvb_dmxdev_section_callback);
668 if (ret < 0) {
669 printk("DVB (%s): could not alloc feed\n",
670 __func__);
671 return ret;
672 }
673
674 ret = (*secfeed)->set(*secfeed, para->pid, 32768,
675 (para->flags & DMX_CHECK_CRC) ? 1 : 0);
676 if (ret < 0) {
677 printk("DVB (%s): could not set feed\n",
678 __func__);
679 dvb_dmxdev_feed_restart(filter);
680 return ret;
681 }
682 } else {
683 dvb_dmxdev_feed_stop(filter);
684 }
685
686 ret = (*secfeed)->allocate_filter(*secfeed, secfilter);
687 if (ret < 0) {
688 dvb_dmxdev_feed_restart(filter);
689 filter->feed.sec->start_filtering(*secfeed);
690 dprintk("could not get filter\n");
691 return ret;
692 }
693
694 (*secfilter)->priv = filter;
695
696 memcpy(&((*secfilter)->filter_value[3]),
697 &(para->filter.filter[1]), DMX_FILTER_SIZE - 1);
698 memcpy(&(*secfilter)->filter_mask[3],
699 &para->filter.mask[1], DMX_FILTER_SIZE - 1);
700 memcpy(&(*secfilter)->filter_mode[3],
701 &para->filter.mode[1], DMX_FILTER_SIZE - 1);
702
703 (*secfilter)->filter_value[0] = para->filter.filter[0];
704 (*secfilter)->filter_mask[0] = para->filter.mask[0];
705 (*secfilter)->filter_mode[0] = para->filter.mode[0];
706 (*secfilter)->filter_mask[1] = 0;
707 (*secfilter)->filter_mask[2] = 0;
708
709 filter->todo = 0;
710
711 ret = filter->feed.sec->start_filtering(filter->feed.sec);
712 if (ret < 0)
713 return ret;
714
715 dvb_dmxdev_filter_timer(filter);
716 break;
717 }
718 case DMXDEV_TYPE_PES:
719 list_for_each_entry(feed, &filter->feed.ts, next) {
720 ret = dvb_dmxdev_start_feed(dmxdev, filter, feed);
721 if (ret < 0) {
722 dvb_dmxdev_filter_stop(filter);
723 return ret;
724 }
725 }
726 break;
727 default:
728 return -EINVAL;
729 }
730
731 dvb_dmxdev_filter_state_set(filter, DMXDEV_STATE_GO);
732 return 0;
733}
734
735static int dvb_demux_open(struct inode *inode, struct file *file)
736{
737 struct dvb_device *dvbdev = file->private_data;
738 struct dmxdev *dmxdev = dvbdev->priv;
739 int i;
740 struct dmxdev_filter *dmxdevfilter;
741
742 if (!dmxdev->filter)
743 return -EINVAL;
744
745 if (mutex_lock_interruptible(&dmxdev->mutex))
746 return -ERESTARTSYS;
747
748 for (i = 0; i < dmxdev->filternum; i++)
749 if (dmxdev->filter[i].state == DMXDEV_STATE_FREE)
750 break;
751
752 if (i == dmxdev->filternum) {
753 mutex_unlock(&dmxdev->mutex);
754 return -EMFILE;
755 }
756
757 dmxdevfilter = &dmxdev->filter[i];
758 mutex_init(&dmxdevfilter->mutex);
759 file->private_data = dmxdevfilter;
760
761 dvb_ringbuffer_init(&dmxdevfilter->buffer, NULL, 8192);
762 dmxdevfilter->type = DMXDEV_TYPE_NONE;
763 dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED);
764 init_timer(&dmxdevfilter->timer);
765
766 dvbdev->users++;
767
768 mutex_unlock(&dmxdev->mutex);
769 return 0;
770}
771
772static int dvb_dmxdev_filter_free(struct dmxdev *dmxdev,
773 struct dmxdev_filter *dmxdevfilter)
774{
775 mutex_lock(&dmxdev->mutex);
776 mutex_lock(&dmxdevfilter->mutex);
777
778 dvb_dmxdev_filter_stop(dmxdevfilter);
779 dvb_dmxdev_filter_reset(dmxdevfilter);
780
781 if (dmxdevfilter->buffer.data) {
782 void *mem = dmxdevfilter->buffer.data;
783
784 spin_lock_irq(&dmxdev->lock);
785 dmxdevfilter->buffer.data = NULL;
786 spin_unlock_irq(&dmxdev->lock);
787 vfree(mem);
788 }
789
790 dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_FREE);
791 wake_up(&dmxdevfilter->buffer.queue);
792 mutex_unlock(&dmxdevfilter->mutex);
793 mutex_unlock(&dmxdev->mutex);
794 return 0;
795}
796
797static inline void invert_mode(dmx_filter_t *filter)
798{
799 int i;
800
801 for (i = 0; i < DMX_FILTER_SIZE; i++)
802 filter->mode[i] ^= 0xff;
803}
804
805static int dvb_dmxdev_add_pid(struct dmxdev *dmxdev,
806 struct dmxdev_filter *filter, u16 pid)
807{
808 struct dmxdev_feed *feed;
809
810 if ((filter->type != DMXDEV_TYPE_PES) ||
811 (filter->state < DMXDEV_STATE_SET))
812 return -EINVAL;
813
814 /* only TS packet filters may have multiple PIDs */
815 if ((filter->params.pes.output != DMX_OUT_TSDEMUX_TAP) &&
816 (!list_empty(&filter->feed.ts)))
817 return -EINVAL;
818
819 feed = kzalloc(sizeof(struct dmxdev_feed), GFP_KERNEL);
820 if (feed == NULL)
821 return -ENOMEM;
822
823 feed->pid = pid;
824 list_add(&feed->next, &filter->feed.ts);
825
826 if (filter->state >= DMXDEV_STATE_GO)
827 return dvb_dmxdev_start_feed(dmxdev, filter, feed);
828
829 return 0;
830}
831
832static int dvb_dmxdev_remove_pid(struct dmxdev *dmxdev,
833 struct dmxdev_filter *filter, u16 pid)
834{
835 struct dmxdev_feed *feed, *tmp;
836
837 if ((filter->type != DMXDEV_TYPE_PES) ||
838 (filter->state < DMXDEV_STATE_SET))
839 return -EINVAL;
840
841 list_for_each_entry_safe(feed, tmp, &filter->feed.ts, next) {
842 if ((feed->pid == pid) && (feed->ts != NULL)) {
843 feed->ts->stop_filtering(feed->ts);
844 filter->dev->demux->release_ts_feed(filter->dev->demux,
845 feed->ts);
846 list_del(&feed->next);
847 kfree(feed);
848 }
849 }
850
851 return 0;
852}
853
854static int dvb_dmxdev_filter_set(struct dmxdev *dmxdev,
855 struct dmxdev_filter *dmxdevfilter,
856 struct dmx_sct_filter_params *params)
857{
858 dprintk("function : %s\n", __func__);
859
860 dvb_dmxdev_filter_stop(dmxdevfilter);
861
862 dmxdevfilter->type = DMXDEV_TYPE_SEC;
863 memcpy(&dmxdevfilter->params.sec,
864 params, sizeof(struct dmx_sct_filter_params));
865 invert_mode(&dmxdevfilter->params.sec.filter);
866 dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET);
867
868 if (params->flags & DMX_IMMEDIATE_START)
869 return dvb_dmxdev_filter_start(dmxdevfilter);
870
871 return 0;
872}
873
874static int dvb_dmxdev_pes_filter_set(struct dmxdev *dmxdev,
875 struct dmxdev_filter *dmxdevfilter,
876 struct dmx_pes_filter_params *params)
877{
878 int ret;
879
880 dvb_dmxdev_filter_stop(dmxdevfilter);
881 dvb_dmxdev_filter_reset(dmxdevfilter);
882
883 if (params->pes_type > DMX_PES_OTHER || params->pes_type < 0)
884 return -EINVAL;
885
886 dmxdevfilter->type = DMXDEV_TYPE_PES;
887 memcpy(&dmxdevfilter->params, params,
888 sizeof(struct dmx_pes_filter_params));
889 INIT_LIST_HEAD(&dmxdevfilter->feed.ts);
890
891 dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET);
892
893 ret = dvb_dmxdev_add_pid(dmxdev, dmxdevfilter,
894 dmxdevfilter->params.pes.pid);
895 if (ret < 0)
896 return ret;
897
898 if (params->flags & DMX_IMMEDIATE_START)
899 return dvb_dmxdev_filter_start(dmxdevfilter);
900
901 return 0;
902}
903
904static ssize_t dvb_dmxdev_read_sec(struct dmxdev_filter *dfil,
905 struct file *file, char __user *buf,
906 size_t count, loff_t *ppos)
907{
908 int result, hcount;
909 int done = 0;
910
911 if (dfil->todo <= 0) {
912 hcount = 3 + dfil->todo;
913 if (hcount > count)
914 hcount = count;
915 result = dvb_dmxdev_buffer_read(&dfil->buffer,
916 file->f_flags & O_NONBLOCK,
917 buf, hcount, ppos);
918 if (result < 0) {
919 dfil->todo = 0;
920 return result;
921 }
922 if (copy_from_user(dfil->secheader - dfil->todo, buf, result))
923 return -EFAULT;
924 buf += result;
925 done = result;
926 count -= result;
927 dfil->todo -= result;
928 if (dfil->todo > -3)
929 return done;
930 dfil->todo = ((dfil->secheader[1] << 8) | dfil->secheader[2]) & 0xfff;
931 if (!count)
932 return done;
933 }
934 if (count > dfil->todo)
935 count = dfil->todo;
936 result = dvb_dmxdev_buffer_read(&dfil->buffer,
937 file->f_flags & O_NONBLOCK,
938 buf, count, ppos);
939 if (result < 0)
940 return result;
941 dfil->todo -= result;
942 return (result + done);
943}
944
945static ssize_t
946dvb_demux_read(struct file *file, char __user *buf, size_t count,
947 loff_t *ppos)
948{
949 struct dmxdev_filter *dmxdevfilter = file->private_data;
950 int ret;
951
952 if (mutex_lock_interruptible(&dmxdevfilter->mutex))
953 return -ERESTARTSYS;
954
955 if (dmxdevfilter->type == DMXDEV_TYPE_SEC)
956 ret = dvb_dmxdev_read_sec(dmxdevfilter, file, buf, count, ppos);
957 else
958 ret = dvb_dmxdev_buffer_read(&dmxdevfilter->buffer,
959 file->f_flags & O_NONBLOCK,
960 buf, count, ppos);
961
962 mutex_unlock(&dmxdevfilter->mutex);
963 return ret;
964}
965
966static int dvb_demux_do_ioctl(struct file *file,
967 unsigned int cmd, void *parg)
968{
969 struct dmxdev_filter *dmxdevfilter = file->private_data;
970 struct dmxdev *dmxdev = dmxdevfilter->dev;
971 unsigned long arg = (unsigned long)parg;
972 int ret = 0;
973
974 if (mutex_lock_interruptible(&dmxdev->mutex))
975 return -ERESTARTSYS;
976
977 switch (cmd) {
978 case DMX_START:
979 if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
980 mutex_unlock(&dmxdev->mutex);
981 return -ERESTARTSYS;
982 }
983 if (dmxdevfilter->state < DMXDEV_STATE_SET)
984 ret = -EINVAL;
985 else
986 ret = dvb_dmxdev_filter_start(dmxdevfilter);
987 mutex_unlock(&dmxdevfilter->mutex);
988 break;
989
990 case DMX_STOP:
991 if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
992 mutex_unlock(&dmxdev->mutex);
993 return -ERESTARTSYS;
994 }
995 ret = dvb_dmxdev_filter_stop(dmxdevfilter);
996 mutex_unlock(&dmxdevfilter->mutex);
997 break;
998
999 case DMX_SET_FILTER:
1000 if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
1001 mutex_unlock(&dmxdev->mutex);
1002 return -ERESTARTSYS;
1003 }
1004 ret = dvb_dmxdev_filter_set(dmxdev, dmxdevfilter, parg);
1005 mutex_unlock(&dmxdevfilter->mutex);
1006 break;
1007
1008 case DMX_SET_PES_FILTER:
1009 if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
1010 mutex_unlock(&dmxdev->mutex);
1011 return -ERESTARTSYS;
1012 }
1013 ret = dvb_dmxdev_pes_filter_set(dmxdev, dmxdevfilter, parg);
1014 mutex_unlock(&dmxdevfilter->mutex);
1015 break;
1016
1017 case DMX_SET_BUFFER_SIZE:
1018 if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
1019 mutex_unlock(&dmxdev->mutex);
1020 return -ERESTARTSYS;
1021 }
1022 ret = dvb_dmxdev_set_buffer_size(dmxdevfilter, arg);
1023 mutex_unlock(&dmxdevfilter->mutex);
1024 break;
1025
1026 case DMX_GET_PES_PIDS:
1027 if (!dmxdev->demux->get_pes_pids) {
1028 ret = -EINVAL;
1029 break;
1030 }
1031 dmxdev->demux->get_pes_pids(dmxdev->demux, parg);
1032 break;
1033
1034 case DMX_GET_CAPS:
1035 if (!dmxdev->demux->get_caps) {
1036 ret = -EINVAL;
1037 break;
1038 }
1039 ret = dmxdev->demux->get_caps(dmxdev->demux, parg);
1040 break;
1041
1042 case DMX_SET_SOURCE:
1043 if (!dmxdev->demux->set_source) {
1044 ret = -EINVAL;
1045 break;
1046 }
1047 ret = dmxdev->demux->set_source(dmxdev->demux, parg);
1048 break;
1049
1050 case DMX_GET_STC:
1051 if (!dmxdev->demux->get_stc) {
1052 ret = -EINVAL;
1053 break;
1054 }
1055 ret = dmxdev->demux->get_stc(dmxdev->demux,
1056 ((struct dmx_stc *)parg)->num,
1057 &((struct dmx_stc *)parg)->stc,
1058 &((struct dmx_stc *)parg)->base);
1059 break;
1060
1061 case DMX_ADD_PID:
1062 if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
1063 ret = -ERESTARTSYS;
1064 break;
1065 }
1066 ret = dvb_dmxdev_add_pid(dmxdev, dmxdevfilter, *(u16 *)parg);
1067 mutex_unlock(&dmxdevfilter->mutex);
1068 break;
1069
1070 case DMX_REMOVE_PID:
1071 if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
1072 ret = -ERESTARTSYS;
1073 break;
1074 }
1075 ret = dvb_dmxdev_remove_pid(dmxdev, dmxdevfilter, *(u16 *)parg);
1076 mutex_unlock(&dmxdevfilter->mutex);
1077 break;
1078
1079 default:
1080 ret = -EINVAL;
1081 break;
1082 }
1083 mutex_unlock(&dmxdev->mutex);
1084 return ret;
1085}
1086
1087static long dvb_demux_ioctl(struct file *file, unsigned int cmd,
1088 unsigned long arg)
1089{
1090 return dvb_usercopy(file, cmd, arg, dvb_demux_do_ioctl);
1091}
1092
1093static unsigned int dvb_demux_poll(struct file *file, poll_table *wait)
1094{
1095 struct dmxdev_filter *dmxdevfilter = file->private_data;
1096 unsigned int mask = 0;
1097
1098 if (!dmxdevfilter)
1099 return -EINVAL;
1100
1101 poll_wait(file, &dmxdevfilter->buffer.queue, wait);
1102
1103 if (dmxdevfilter->state != DMXDEV_STATE_GO &&
1104 dmxdevfilter->state != DMXDEV_STATE_DONE &&
1105 dmxdevfilter->state != DMXDEV_STATE_TIMEDOUT)
1106 return 0;
1107
1108 if (dmxdevfilter->buffer.error)
1109 mask |= (POLLIN | POLLRDNORM | POLLPRI | POLLERR);
1110
1111 if (!dvb_ringbuffer_empty(&dmxdevfilter->buffer))
1112 mask |= (POLLIN | POLLRDNORM | POLLPRI);
1113
1114 return mask;
1115}
1116
1117static int dvb_demux_release(struct inode *inode, struct file *file)
1118{
1119 struct dmxdev_filter *dmxdevfilter = file->private_data;
1120 struct dmxdev *dmxdev = dmxdevfilter->dev;
1121
1122 int ret;
1123
1124 ret = dvb_dmxdev_filter_free(dmxdev, dmxdevfilter);
1125
1126 mutex_lock(&dmxdev->mutex);
1127 dmxdev->dvbdev->users--;
1128 if(dmxdev->dvbdev->users==1 && dmxdev->exit==1) {
1129 fops_put(file->f_op);
1130 file->f_op = NULL;
1131 mutex_unlock(&dmxdev->mutex);
1132 wake_up(&dmxdev->dvbdev->wait_queue);
1133 } else
1134 mutex_unlock(&dmxdev->mutex);
1135
1136 return ret;
1137}
1138
1139static const struct file_operations dvb_demux_fops = {
1140 .owner = THIS_MODULE,
1141 .read = dvb_demux_read,
1142 .unlocked_ioctl = dvb_demux_ioctl,
1143 .open = dvb_demux_open,
1144 .release = dvb_demux_release,
1145 .poll = dvb_demux_poll,
1146 .llseek = default_llseek,
1147};
1148
1149static struct dvb_device dvbdev_demux = {
1150 .priv = NULL,
1151 .users = 1,
1152 .writers = 1,
1153 .fops = &dvb_demux_fops
1154};
1155
1156static int dvb_dvr_do_ioctl(struct file *file,
1157 unsigned int cmd, void *parg)
1158{
1159 struct dvb_device *dvbdev = file->private_data;
1160 struct dmxdev *dmxdev = dvbdev->priv;
1161 unsigned long arg = (unsigned long)parg;
1162 int ret;
1163
1164 if (mutex_lock_interruptible(&dmxdev->mutex))
1165 return -ERESTARTSYS;
1166
1167 switch (cmd) {
1168 case DMX_SET_BUFFER_SIZE:
1169 ret = dvb_dvr_set_buffer_size(dmxdev, arg);
1170 break;
1171
1172 default:
1173 ret = -EINVAL;
1174 break;
1175 }
1176 mutex_unlock(&dmxdev->mutex);
1177 return ret;
1178}
1179
1180static long dvb_dvr_ioctl(struct file *file,
1181 unsigned int cmd, unsigned long arg)
1182{
1183 return dvb_usercopy(file, cmd, arg, dvb_dvr_do_ioctl);
1184}
1185
1186static unsigned int dvb_dvr_poll(struct file *file, poll_table *wait)
1187{
1188 struct dvb_device *dvbdev = file->private_data;
1189 struct dmxdev *dmxdev = dvbdev->priv;
1190 unsigned int mask = 0;
1191
1192 dprintk("function : %s\n", __func__);
1193
1194 poll_wait(file, &dmxdev->dvr_buffer.queue, wait);
1195
1196 if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
1197 if (dmxdev->dvr_buffer.error)
1198 mask |= (POLLIN | POLLRDNORM | POLLPRI | POLLERR);
1199
1200 if (!dvb_ringbuffer_empty(&dmxdev->dvr_buffer))
1201 mask |= (POLLIN | POLLRDNORM | POLLPRI);
1202 } else
1203 mask |= (POLLOUT | POLLWRNORM | POLLPRI);
1204
1205 return mask;
1206}
1207
1208static const struct file_operations dvb_dvr_fops = {
1209 .owner = THIS_MODULE,
1210 .read = dvb_dvr_read,
1211 .write = dvb_dvr_write,
1212 .unlocked_ioctl = dvb_dvr_ioctl,
1213 .open = dvb_dvr_open,
1214 .release = dvb_dvr_release,
1215 .poll = dvb_dvr_poll,
1216 .llseek = default_llseek,
1217};
1218
1219static struct dvb_device dvbdev_dvr = {
1220 .priv = NULL,
1221 .readers = 1,
1222 .users = 1,
1223 .fops = &dvb_dvr_fops
1224};
1225
1226int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter)
1227{
1228 int i;
1229
1230 if (dmxdev->demux->open(dmxdev->demux) < 0)
1231 return -EUSERS;
1232
1233 dmxdev->filter = vmalloc(dmxdev->filternum * sizeof(struct dmxdev_filter));
1234 if (!dmxdev->filter)
1235 return -ENOMEM;
1236
1237 mutex_init(&dmxdev->mutex);
1238 spin_lock_init(&dmxdev->lock);
1239 for (i = 0; i < dmxdev->filternum; i++) {
1240 dmxdev->filter[i].dev = dmxdev;
1241 dmxdev->filter[i].buffer.data = NULL;
1242 dvb_dmxdev_filter_state_set(&dmxdev->filter[i],
1243 DMXDEV_STATE_FREE);
1244 }
1245
1246 dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev,
1247 DVB_DEVICE_DEMUX);
1248 dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr,
1249 dmxdev, DVB_DEVICE_DVR);
1250
1251 dvb_ringbuffer_init(&dmxdev->dvr_buffer, NULL, 8192);
1252
1253 return 0;
1254}
1255
1256EXPORT_SYMBOL(dvb_dmxdev_init);
1257
1258void dvb_dmxdev_release(struct dmxdev *dmxdev)
1259{
1260 dmxdev->exit=1;
1261 if (dmxdev->dvbdev->users > 1) {
1262 wait_event(dmxdev->dvbdev->wait_queue,
1263 dmxdev->dvbdev->users==1);
1264 }
1265 if (dmxdev->dvr_dvbdev->users > 1) {
1266 wait_event(dmxdev->dvr_dvbdev->wait_queue,
1267 dmxdev->dvr_dvbdev->users==1);
1268 }
1269
1270 dvb_unregister_device(dmxdev->dvbdev);
1271 dvb_unregister_device(dmxdev->dvr_dvbdev);
1272
1273 vfree(dmxdev->filter);
1274 dmxdev->filter = NULL;
1275 dmxdev->demux->close(dmxdev->demux);
1276}
1277
1278EXPORT_SYMBOL(dvb_dmxdev_release);
diff --git a/drivers/media/dvb/dvb-core/dmxdev.h b/drivers/media/dvb/dvb-core/dmxdev.h
new file mode 100644
index 00000000000..02ebe28f830
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dmxdev.h
@@ -0,0 +1,118 @@
1/*
2 * dmxdev.h
3 *
4 * Copyright (C) 2000 Ralph Metzler & Marcus Metzler
5 * for convergence integrated media GmbH
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation; either version 2.1
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 *
21 */
22
23#ifndef _DMXDEV_H_
24#define _DMXDEV_H_
25
26#include <linux/types.h>
27#include <linux/spinlock.h>
28#include <linux/kernel.h>
29#include <linux/timer.h>
30#include <linux/wait.h>
31#include <linux/fs.h>
32#include <linux/string.h>
33#include <linux/mutex.h>
34#include <linux/slab.h>
35
36#include <linux/dvb/dmx.h>
37
38#include "dvbdev.h"
39#include "demux.h"
40#include "dvb_ringbuffer.h"
41
42enum dmxdev_type {
43 DMXDEV_TYPE_NONE,
44 DMXDEV_TYPE_SEC,
45 DMXDEV_TYPE_PES,
46};
47
48enum dmxdev_state {
49 DMXDEV_STATE_FREE,
50 DMXDEV_STATE_ALLOCATED,
51 DMXDEV_STATE_SET,
52 DMXDEV_STATE_GO,
53 DMXDEV_STATE_DONE,
54 DMXDEV_STATE_TIMEDOUT
55};
56
57struct dmxdev_feed {
58 u16 pid;
59 struct dmx_ts_feed *ts;
60 struct list_head next;
61};
62
63struct dmxdev_filter {
64 union {
65 struct dmx_section_filter *sec;
66 } filter;
67
68 union {
69 /* list of TS and PES feeds (struct dmxdev_feed) */
70 struct list_head ts;
71 struct dmx_section_feed *sec;
72 } feed;
73
74 union {
75 struct dmx_sct_filter_params sec;
76 struct dmx_pes_filter_params pes;
77 } params;
78
79 enum dmxdev_type type;
80 enum dmxdev_state state;
81 struct dmxdev *dev;
82 struct dvb_ringbuffer buffer;
83
84 struct mutex mutex;
85
86 /* only for sections */
87 struct timer_list timer;
88 int todo;
89 u8 secheader[3];
90};
91
92
93struct dmxdev {
94 struct dvb_device *dvbdev;
95 struct dvb_device *dvr_dvbdev;
96
97 struct dmxdev_filter *filter;
98 struct dmx_demux *demux;
99
100 int filternum;
101 int capabilities;
102
103 unsigned int exit:1;
104#define DMXDEV_CAP_DUPLEX 1
105 struct dmx_frontend *dvr_orig_fe;
106
107 struct dvb_ringbuffer dvr_buffer;
108#define DVR_BUFFER_SIZE (10*188*1024)
109
110 struct mutex mutex;
111 spinlock_t lock;
112};
113
114
115int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *);
116void dvb_dmxdev_release(struct dmxdev *dmxdev);
117
118#endif /* _DMXDEV_H_ */
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
new file mode 100644
index 00000000000..7ea517b7e18
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
@@ -0,0 +1,1749 @@
1/*
2 * dvb_ca.c: generic DVB functions for EN50221 CAM interfaces
3 *
4 * Copyright (C) 2004 Andrew de Quincey
5 *
6 * Parts of this file were based on sources as follows:
7 *
8 * Copyright (C) 2003 Ralph Metzler <rjkm@metzlerbros.de>
9 *
10 * based on code:
11 *
12 * Copyright (C) 1999-2002 Ralph Metzler
13 * & Marcus Metzler for convergence integrated media GmbH
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
29 */
30
31#include <linux/errno.h>
32#include <linux/slab.h>
33#include <linux/list.h>
34#include <linux/module.h>
35#include <linux/vmalloc.h>
36#include <linux/delay.h>
37#include <linux/spinlock.h>
38#include <linux/sched.h>
39#include <linux/kthread.h>
40
41#include "dvb_ca_en50221.h"
42#include "dvb_ringbuffer.h"
43
44static int dvb_ca_en50221_debug;
45
46module_param_named(cam_debug, dvb_ca_en50221_debug, int, 0644);
47MODULE_PARM_DESC(cam_debug, "enable verbose debug messages");
48
49#define dprintk if (dvb_ca_en50221_debug) printk
50
51#define INIT_TIMEOUT_SECS 10
52
53#define HOST_LINK_BUF_SIZE 0x200
54
55#define RX_BUFFER_SIZE 65535
56
57#define MAX_RX_PACKETS_PER_ITERATION 10
58
59#define CTRLIF_DATA 0
60#define CTRLIF_COMMAND 1
61#define CTRLIF_STATUS 1
62#define CTRLIF_SIZE_LOW 2
63#define CTRLIF_SIZE_HIGH 3
64
65#define CMDREG_HC 1 /* Host control */
66#define CMDREG_SW 2 /* Size write */
67#define CMDREG_SR 4 /* Size read */
68#define CMDREG_RS 8 /* Reset interface */
69#define CMDREG_FRIE 0x40 /* Enable FR interrupt */
70#define CMDREG_DAIE 0x80 /* Enable DA interrupt */
71#define IRQEN (CMDREG_DAIE)
72
73#define STATUSREG_RE 1 /* read error */
74#define STATUSREG_WE 2 /* write error */
75#define STATUSREG_FR 0x40 /* module free */
76#define STATUSREG_DA 0x80 /* data available */
77#define STATUSREG_TXERR (STATUSREG_RE|STATUSREG_WE) /* general transfer error */
78
79
80#define DVB_CA_SLOTSTATE_NONE 0
81#define DVB_CA_SLOTSTATE_UNINITIALISED 1
82#define DVB_CA_SLOTSTATE_RUNNING 2
83#define DVB_CA_SLOTSTATE_INVALID 3
84#define DVB_CA_SLOTSTATE_WAITREADY 4
85#define DVB_CA_SLOTSTATE_VALIDATE 5
86#define DVB_CA_SLOTSTATE_WAITFR 6
87#define DVB_CA_SLOTSTATE_LINKINIT 7
88
89
90/* Information on a CA slot */
91struct dvb_ca_slot {
92
93 /* current state of the CAM */
94 int slot_state;
95
96 /* mutex used for serializing access to one CI slot */
97 struct mutex slot_lock;
98
99 /* Number of CAMCHANGES that have occurred since last processing */
100 atomic_t camchange_count;
101
102 /* Type of last CAMCHANGE */
103 int camchange_type;
104
105 /* base address of CAM config */
106 u32 config_base;
107
108 /* value to write into Config Control register */
109 u8 config_option;
110
111 /* if 1, the CAM supports DA IRQs */
112 u8 da_irq_supported:1;
113
114 /* size of the buffer to use when talking to the CAM */
115 int link_buf_size;
116
117 /* buffer for incoming packets */
118 struct dvb_ringbuffer rx_buffer;
119
120 /* timer used during various states of the slot */
121 unsigned long timeout;
122};
123
124/* Private CA-interface information */
125struct dvb_ca_private {
126
127 /* pointer back to the public data structure */
128 struct dvb_ca_en50221 *pub;
129
130 /* the DVB device */
131 struct dvb_device *dvbdev;
132
133 /* Flags describing the interface (DVB_CA_FLAG_*) */
134 u32 flags;
135
136 /* number of slots supported by this CA interface */
137 unsigned int slot_count;
138
139 /* information on each slot */
140 struct dvb_ca_slot *slot_info;
141
142 /* wait queues for read() and write() operations */
143 wait_queue_head_t wait_queue;
144
145 /* PID of the monitoring thread */
146 struct task_struct *thread;
147
148 /* Flag indicating if the CA device is open */
149 unsigned int open:1;
150
151 /* Flag indicating the thread should wake up now */
152 unsigned int wakeup:1;
153
154 /* Delay the main thread should use */
155 unsigned long delay;
156
157 /* Slot to start looking for data to read from in the next user-space read operation */
158 int next_read_slot;
159};
160
161static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca);
162static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, u8 * ebuf, int ecount);
163static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 * ebuf, int ecount);
164
165
166/**
167 * Safely find needle in haystack.
168 *
169 * @param haystack Buffer to look in.
170 * @param hlen Number of bytes in haystack.
171 * @param needle Buffer to find.
172 * @param nlen Number of bytes in needle.
173 * @return Pointer into haystack needle was found at, or NULL if not found.
174 */
175static char *findstr(char * haystack, int hlen, char * needle, int nlen)
176{
177 int i;
178
179 if (hlen < nlen)
180 return NULL;
181
182 for (i = 0; i <= hlen - nlen; i++) {
183 if (!strncmp(haystack + i, needle, nlen))
184 return haystack + i;
185 }
186
187 return NULL;
188}
189
190
191
192/* ******************************************************************************** */
193/* EN50221 physical interface functions */
194
195
196/**
197 * Check CAM status.
198 */
199static int dvb_ca_en50221_check_camstatus(struct dvb_ca_private *ca, int slot)
200{
201 int slot_status;
202 int cam_present_now;
203 int cam_changed;
204
205 /* IRQ mode */
206 if (ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE) {
207 return (atomic_read(&ca->slot_info[slot].camchange_count) != 0);
208 }
209
210 /* poll mode */
211 slot_status = ca->pub->poll_slot_status(ca->pub, slot, ca->open);
212
213 cam_present_now = (slot_status & DVB_CA_EN50221_POLL_CAM_PRESENT) ? 1 : 0;
214 cam_changed = (slot_status & DVB_CA_EN50221_POLL_CAM_CHANGED) ? 1 : 0;
215 if (!cam_changed) {
216 int cam_present_old = (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_NONE);
217 cam_changed = (cam_present_now != cam_present_old);
218 }
219
220 if (cam_changed) {
221 if (!cam_present_now) {
222 ca->slot_info[slot].camchange_type = DVB_CA_EN50221_CAMCHANGE_REMOVED;
223 } else {
224 ca->slot_info[slot].camchange_type = DVB_CA_EN50221_CAMCHANGE_INSERTED;
225 }
226 atomic_set(&ca->slot_info[slot].camchange_count, 1);
227 } else {
228 if ((ca->slot_info[slot].slot_state == DVB_CA_SLOTSTATE_WAITREADY) &&
229 (slot_status & DVB_CA_EN50221_POLL_CAM_READY)) {
230 // move to validate state if reset is completed
231 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_VALIDATE;
232 }
233 }
234
235 return cam_changed;
236}
237
238
239/**
240 * Wait for flags to become set on the STATUS register on a CAM interface,
241 * checking for errors and timeout.
242 *
243 * @param ca CA instance.
244 * @param slot Slot on interface.
245 * @param waitfor Flags to wait for.
246 * @param timeout_ms Timeout in milliseconds.
247 *
248 * @return 0 on success, nonzero on error.
249 */
250static int dvb_ca_en50221_wait_if_status(struct dvb_ca_private *ca, int slot,
251 u8 waitfor, int timeout_hz)
252{
253 unsigned long timeout;
254 unsigned long start;
255
256 dprintk("%s\n", __func__);
257
258 /* loop until timeout elapsed */
259 start = jiffies;
260 timeout = jiffies + timeout_hz;
261 while (1) {
262 /* read the status and check for error */
263 int res = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS);
264 if (res < 0)
265 return -EIO;
266
267 /* if we got the flags, it was successful! */
268 if (res & waitfor) {
269 dprintk("%s succeeded timeout:%lu\n", __func__, jiffies - start);
270 return 0;
271 }
272
273 /* check for timeout */
274 if (time_after(jiffies, timeout)) {
275 break;
276 }
277
278 /* wait for a bit */
279 msleep(1);
280 }
281
282 dprintk("%s failed timeout:%lu\n", __func__, jiffies - start);
283
284 /* if we get here, we've timed out */
285 return -ETIMEDOUT;
286}
287
288
289/**
290 * Initialise the link layer connection to a CAM.
291 *
292 * @param ca CA instance.
293 * @param slot Slot id.
294 *
295 * @return 0 on success, nonzero on failure.
296 */
297static int dvb_ca_en50221_link_init(struct dvb_ca_private *ca, int slot)
298{
299 int ret;
300 int buf_size;
301 u8 buf[2];
302
303 dprintk("%s\n", __func__);
304
305 /* we'll be determining these during this function */
306 ca->slot_info[slot].da_irq_supported = 0;
307
308 /* set the host link buffer size temporarily. it will be overwritten with the
309 * real negotiated size later. */
310 ca->slot_info[slot].link_buf_size = 2;
311
312 /* read the buffer size from the CAM */
313 if ((ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN | CMDREG_SR)) != 0)
314 return ret;
315 if ((ret = dvb_ca_en50221_wait_if_status(ca, slot, STATUSREG_DA, HZ / 10)) != 0)
316 return ret;
317 if ((ret = dvb_ca_en50221_read_data(ca, slot, buf, 2)) != 2)
318 return -EIO;
319 if ((ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN)) != 0)
320 return ret;
321
322 /* store it, and choose the minimum of our buffer and the CAM's buffer size */
323 buf_size = (buf[0] << 8) | buf[1];
324 if (buf_size > HOST_LINK_BUF_SIZE)
325 buf_size = HOST_LINK_BUF_SIZE;
326 ca->slot_info[slot].link_buf_size = buf_size;
327 buf[0] = buf_size >> 8;
328 buf[1] = buf_size & 0xff;
329 dprintk("Chosen link buffer size of %i\n", buf_size);
330
331 /* write the buffer size to the CAM */
332 if ((ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN | CMDREG_SW)) != 0)
333 return ret;
334 if ((ret = dvb_ca_en50221_wait_if_status(ca, slot, STATUSREG_FR, HZ / 10)) != 0)
335 return ret;
336 if ((ret = dvb_ca_en50221_write_data(ca, slot, buf, 2)) != 2)
337 return -EIO;
338 if ((ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN)) != 0)
339 return ret;
340
341 /* success */
342 return 0;
343}
344
345/**
346 * Read a tuple from attribute memory.
347 *
348 * @param ca CA instance.
349 * @param slot Slot id.
350 * @param address Address to read from. Updated.
351 * @param tupleType Tuple id byte. Updated.
352 * @param tupleLength Tuple length. Updated.
353 * @param tuple Dest buffer for tuple (must be 256 bytes). Updated.
354 *
355 * @return 0 on success, nonzero on error.
356 */
357static int dvb_ca_en50221_read_tuple(struct dvb_ca_private *ca, int slot,
358 int *address, int *tupleType, int *tupleLength, u8 * tuple)
359{
360 int i;
361 int _tupleType;
362 int _tupleLength;
363 int _address = *address;
364
365 /* grab the next tuple length and type */
366 if ((_tupleType = ca->pub->read_attribute_mem(ca->pub, slot, _address)) < 0)
367 return _tupleType;
368 if (_tupleType == 0xff) {
369 dprintk("END OF CHAIN TUPLE type:0x%x\n", _tupleType);
370 *address += 2;
371 *tupleType = _tupleType;
372 *tupleLength = 0;
373 return 0;
374 }
375 if ((_tupleLength = ca->pub->read_attribute_mem(ca->pub, slot, _address + 2)) < 0)
376 return _tupleLength;
377 _address += 4;
378
379 dprintk("TUPLE type:0x%x length:%i\n", _tupleType, _tupleLength);
380
381 /* read in the whole tuple */
382 for (i = 0; i < _tupleLength; i++) {
383 tuple[i] = ca->pub->read_attribute_mem(ca->pub, slot, _address + (i * 2));
384 dprintk(" 0x%02x: 0x%02x %c\n",
385 i, tuple[i] & 0xff,
386 ((tuple[i] > 31) && (tuple[i] < 127)) ? tuple[i] : '.');
387 }
388 _address += (_tupleLength * 2);
389
390 // success
391 *tupleType = _tupleType;
392 *tupleLength = _tupleLength;
393 *address = _address;
394 return 0;
395}
396
397
398/**
399 * Parse attribute memory of a CAM module, extracting Config register, and checking
400 * it is a DVB CAM module.
401 *
402 * @param ca CA instance.
403 * @param slot Slot id.
404 *
405 * @return 0 on success, <0 on failure.
406 */
407static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot)
408{
409 int address = 0;
410 int tupleLength;
411 int tupleType;
412 u8 tuple[257];
413 char *dvb_str;
414 int rasz;
415 int status;
416 int got_cftableentry = 0;
417 int end_chain = 0;
418 int i;
419 u16 manfid = 0;
420 u16 devid = 0;
421
422
423 // CISTPL_DEVICE_0A
424 if ((status =
425 dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType, &tupleLength, tuple)) < 0)
426 return status;
427 if (tupleType != 0x1D)
428 return -EINVAL;
429
430
431
432 // CISTPL_DEVICE_0C
433 if ((status =
434 dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType, &tupleLength, tuple)) < 0)
435 return status;
436 if (tupleType != 0x1C)
437 return -EINVAL;
438
439
440
441 // CISTPL_VERS_1
442 if ((status =
443 dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType, &tupleLength, tuple)) < 0)
444 return status;
445 if (tupleType != 0x15)
446 return -EINVAL;
447
448
449
450 // CISTPL_MANFID
451 if ((status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType,
452 &tupleLength, tuple)) < 0)
453 return status;
454 if (tupleType != 0x20)
455 return -EINVAL;
456 if (tupleLength != 4)
457 return -EINVAL;
458 manfid = (tuple[1] << 8) | tuple[0];
459 devid = (tuple[3] << 8) | tuple[2];
460
461
462
463 // CISTPL_CONFIG
464 if ((status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType,
465 &tupleLength, tuple)) < 0)
466 return status;
467 if (tupleType != 0x1A)
468 return -EINVAL;
469 if (tupleLength < 3)
470 return -EINVAL;
471
472 /* extract the configbase */
473 rasz = tuple[0] & 3;
474 if (tupleLength < (3 + rasz + 14))
475 return -EINVAL;
476 ca->slot_info[slot].config_base = 0;
477 for (i = 0; i < rasz + 1; i++) {
478 ca->slot_info[slot].config_base |= (tuple[2 + i] << (8 * i));
479 }
480
481 /* check it contains the correct DVB string */
482 dvb_str = findstr((char *)tuple, tupleLength, "DVB_CI_V", 8);
483 if (dvb_str == NULL)
484 return -EINVAL;
485 if (tupleLength < ((dvb_str - (char *) tuple) + 12))
486 return -EINVAL;
487
488 /* is it a version we support? */
489 if (strncmp(dvb_str + 8, "1.00", 4)) {
490 printk("dvb_ca adapter %d: Unsupported DVB CAM module version %c%c%c%c\n",
491 ca->dvbdev->adapter->num, dvb_str[8], dvb_str[9], dvb_str[10], dvb_str[11]);
492 return -EINVAL;
493 }
494
495 /* process the CFTABLE_ENTRY tuples, and any after those */
496 while ((!end_chain) && (address < 0x1000)) {
497 if ((status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType,
498 &tupleLength, tuple)) < 0)
499 return status;
500 switch (tupleType) {
501 case 0x1B: // CISTPL_CFTABLE_ENTRY
502 if (tupleLength < (2 + 11 + 17))
503 break;
504
505 /* if we've already parsed one, just use it */
506 if (got_cftableentry)
507 break;
508
509 /* get the config option */
510 ca->slot_info[slot].config_option = tuple[0] & 0x3f;
511
512 /* OK, check it contains the correct strings */
513 if ((findstr((char *)tuple, tupleLength, "DVB_HOST", 8) == NULL) ||
514 (findstr((char *)tuple, tupleLength, "DVB_CI_MODULE", 13) == NULL))
515 break;
516
517 got_cftableentry = 1;
518 break;
519
520 case 0x14: // CISTPL_NO_LINK
521 break;
522
523 case 0xFF: // CISTPL_END
524 end_chain = 1;
525 break;
526
527 default: /* Unknown tuple type - just skip this tuple and move to the next one */
528 dprintk("dvb_ca: Skipping unknown tuple type:0x%x length:0x%x\n", tupleType,
529 tupleLength);
530 break;
531 }
532 }
533
534 if ((address > 0x1000) || (!got_cftableentry))
535 return -EINVAL;
536
537 dprintk("Valid DVB CAM detected MANID:%x DEVID:%x CONFIGBASE:0x%x CONFIGOPTION:0x%x\n",
538 manfid, devid, ca->slot_info[slot].config_base, ca->slot_info[slot].config_option);
539
540 // success!
541 return 0;
542}
543
544
545/**
546 * Set CAM's configoption correctly.
547 *
548 * @param ca CA instance.
549 * @param slot Slot containing the CAM.
550 */
551static int dvb_ca_en50221_set_configoption(struct dvb_ca_private *ca, int slot)
552{
553 int configoption;
554
555 dprintk("%s\n", __func__);
556
557 /* set the config option */
558 ca->pub->write_attribute_mem(ca->pub, slot,
559 ca->slot_info[slot].config_base,
560 ca->slot_info[slot].config_option);
561
562 /* check it */
563 configoption = ca->pub->read_attribute_mem(ca->pub, slot, ca->slot_info[slot].config_base);
564 dprintk("Set configoption 0x%x, read configoption 0x%x\n",
565 ca->slot_info[slot].config_option, configoption & 0x3f);
566
567 /* fine! */
568 return 0;
569
570}
571
572
573/**
574 * This function talks to an EN50221 CAM control interface. It reads a buffer of
575 * data from the CAM. The data can either be stored in a supplied buffer, or
576 * automatically be added to the slot's rx_buffer.
577 *
578 * @param ca CA instance.
579 * @param slot Slot to read from.
580 * @param ebuf If non-NULL, the data will be written to this buffer. If NULL,
581 * the data will be added into the buffering system as a normal fragment.
582 * @param ecount Size of ebuf. Ignored if ebuf is NULL.
583 *
584 * @return Number of bytes read, or < 0 on error
585 */
586static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, u8 * ebuf, int ecount)
587{
588 int bytes_read;
589 int status;
590 u8 buf[HOST_LINK_BUF_SIZE];
591 int i;
592
593 dprintk("%s\n", __func__);
594
595 /* check if we have space for a link buf in the rx_buffer */
596 if (ebuf == NULL) {
597 int buf_free;
598
599 if (ca->slot_info[slot].rx_buffer.data == NULL) {
600 status = -EIO;
601 goto exit;
602 }
603 buf_free = dvb_ringbuffer_free(&ca->slot_info[slot].rx_buffer);
604
605 if (buf_free < (ca->slot_info[slot].link_buf_size + DVB_RINGBUFFER_PKTHDRSIZE)) {
606 status = -EAGAIN;
607 goto exit;
608 }
609 }
610
611 /* check if there is data available */
612 if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
613 goto exit;
614 if (!(status & STATUSREG_DA)) {
615 /* no data */
616 status = 0;
617 goto exit;
618 }
619
620 /* read the amount of data */
621 if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_SIZE_HIGH)) < 0)
622 goto exit;
623 bytes_read = status << 8;
624 if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_SIZE_LOW)) < 0)
625 goto exit;
626 bytes_read |= status;
627
628 /* check it will fit */
629 if (ebuf == NULL) {
630 if (bytes_read > ca->slot_info[slot].link_buf_size) {
631 printk("dvb_ca adapter %d: CAM tried to send a buffer larger than the link buffer size (%i > %i)!\n",
632 ca->dvbdev->adapter->num, bytes_read, ca->slot_info[slot].link_buf_size);
633 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
634 status = -EIO;
635 goto exit;
636 }
637 if (bytes_read < 2) {
638 printk("dvb_ca adapter %d: CAM sent a buffer that was less than 2 bytes!\n",
639 ca->dvbdev->adapter->num);
640 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
641 status = -EIO;
642 goto exit;
643 }
644 } else {
645 if (bytes_read > ecount) {
646 printk("dvb_ca adapter %d: CAM tried to send a buffer larger than the ecount size!\n",
647 ca->dvbdev->adapter->num);
648 status = -EIO;
649 goto exit;
650 }
651 }
652
653 /* fill the buffer */
654 for (i = 0; i < bytes_read; i++) {
655 /* read byte and check */
656 if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_DATA)) < 0)
657 goto exit;
658
659 /* OK, store it in the buffer */
660 buf[i] = status;
661 }
662
663 /* check for read error (RE should now be 0) */
664 if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
665 goto exit;
666 if (status & STATUSREG_RE) {
667 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
668 status = -EIO;
669 goto exit;
670 }
671
672 /* OK, add it to the receive buffer, or copy into external buffer if supplied */
673 if (ebuf == NULL) {
674 if (ca->slot_info[slot].rx_buffer.data == NULL) {
675 status = -EIO;
676 goto exit;
677 }
678 dvb_ringbuffer_pkt_write(&ca->slot_info[slot].rx_buffer, buf, bytes_read);
679 } else {
680 memcpy(ebuf, buf, bytes_read);
681 }
682
683 dprintk("Received CA packet for slot %i connection id 0x%x last_frag:%i size:0x%x\n", slot,
684 buf[0], (buf[1] & 0x80) == 0, bytes_read);
685
686 /* wake up readers when a last_fragment is received */
687 if ((buf[1] & 0x80) == 0x00) {
688 wake_up_interruptible(&ca->wait_queue);
689 }
690 status = bytes_read;
691
692exit:
693 return status;
694}
695
696
697/**
698 * This function talks to an EN50221 CAM control interface. It writes a buffer of data
699 * to a CAM.
700 *
701 * @param ca CA instance.
702 * @param slot Slot to write to.
703 * @param ebuf The data in this buffer is treated as a complete link-level packet to
704 * be written.
705 * @param count Size of ebuf.
706 *
707 * @return Number of bytes written, or < 0 on error.
708 */
709static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 * buf, int bytes_write)
710{
711 int status;
712 int i;
713
714 dprintk("%s\n", __func__);
715
716
717 /* sanity check */
718 if (bytes_write > ca->slot_info[slot].link_buf_size)
719 return -EINVAL;
720
721 /* it is possible we are dealing with a single buffer implementation,
722 thus if there is data available for read or if there is even a read
723 already in progress, we do nothing but awake the kernel thread to
724 process the data if necessary. */
725 if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
726 goto exitnowrite;
727 if (status & (STATUSREG_DA | STATUSREG_RE)) {
728 if (status & STATUSREG_DA)
729 dvb_ca_en50221_thread_wakeup(ca);
730
731 status = -EAGAIN;
732 goto exitnowrite;
733 }
734
735 /* OK, set HC bit */
736 if ((status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND,
737 IRQEN | CMDREG_HC)) != 0)
738 goto exit;
739
740 /* check if interface is still free */
741 if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
742 goto exit;
743 if (!(status & STATUSREG_FR)) {
744 /* it wasn't free => try again later */
745 status = -EAGAIN;
746 goto exit;
747 }
748
749 /* send the amount of data */
750 if ((status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_SIZE_HIGH, bytes_write >> 8)) != 0)
751 goto exit;
752 if ((status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_SIZE_LOW,
753 bytes_write & 0xff)) != 0)
754 goto exit;
755
756 /* send the buffer */
757 for (i = 0; i < bytes_write; i++) {
758 if ((status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_DATA, buf[i])) != 0)
759 goto exit;
760 }
761
762 /* check for write error (WE should now be 0) */
763 if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
764 goto exit;
765 if (status & STATUSREG_WE) {
766 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
767 status = -EIO;
768 goto exit;
769 }
770 status = bytes_write;
771
772 dprintk("Wrote CA packet for slot %i, connection id 0x%x last_frag:%i size:0x%x\n", slot,
773 buf[0], (buf[1] & 0x80) == 0, bytes_write);
774
775exit:
776 ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN);
777
778exitnowrite:
779 return status;
780}
781EXPORT_SYMBOL(dvb_ca_en50221_camchange_irq);
782
783
784
785/* ******************************************************************************** */
786/* EN50221 higher level functions */
787
788
789/**
790 * A CAM has been removed => shut it down.
791 *
792 * @param ca CA instance.
793 * @param slot Slot to shut down.
794 */
795static int dvb_ca_en50221_slot_shutdown(struct dvb_ca_private *ca, int slot)
796{
797 dprintk("%s\n", __func__);
798
799 ca->pub->slot_shutdown(ca->pub, slot);
800 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE;
801
802 /* need to wake up all processes to check if they're now
803 trying to write to a defunct CAM */
804 wake_up_interruptible(&ca->wait_queue);
805
806 dprintk("Slot %i shutdown\n", slot);
807
808 /* success */
809 return 0;
810}
811EXPORT_SYMBOL(dvb_ca_en50221_camready_irq);
812
813
814/**
815 * A CAMCHANGE IRQ has occurred.
816 *
817 * @param ca CA instance.
818 * @param slot Slot concerned.
819 * @param change_type One of the DVB_CA_CAMCHANGE_* values.
820 */
821void dvb_ca_en50221_camchange_irq(struct dvb_ca_en50221 *pubca, int slot, int change_type)
822{
823 struct dvb_ca_private *ca = pubca->private;
824
825 dprintk("CAMCHANGE IRQ slot:%i change_type:%i\n", slot, change_type);
826
827 switch (change_type) {
828 case DVB_CA_EN50221_CAMCHANGE_REMOVED:
829 case DVB_CA_EN50221_CAMCHANGE_INSERTED:
830 break;
831
832 default:
833 return;
834 }
835
836 ca->slot_info[slot].camchange_type = change_type;
837 atomic_inc(&ca->slot_info[slot].camchange_count);
838 dvb_ca_en50221_thread_wakeup(ca);
839}
840EXPORT_SYMBOL(dvb_ca_en50221_frda_irq);
841
842
843/**
844 * A CAMREADY IRQ has occurred.
845 *
846 * @param ca CA instance.
847 * @param slot Slot concerned.
848 */
849void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221 *pubca, int slot)
850{
851 struct dvb_ca_private *ca = pubca->private;
852
853 dprintk("CAMREADY IRQ slot:%i\n", slot);
854
855 if (ca->slot_info[slot].slot_state == DVB_CA_SLOTSTATE_WAITREADY) {
856 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_VALIDATE;
857 dvb_ca_en50221_thread_wakeup(ca);
858 }
859}
860
861
862/**
863 * An FR or DA IRQ has occurred.
864 *
865 * @param ca CA instance.
866 * @param slot Slot concerned.
867 */
868void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221 *pubca, int slot)
869{
870 struct dvb_ca_private *ca = pubca->private;
871 int flags;
872
873 dprintk("FR/DA IRQ slot:%i\n", slot);
874
875 switch (ca->slot_info[slot].slot_state) {
876 case DVB_CA_SLOTSTATE_LINKINIT:
877 flags = ca->pub->read_cam_control(pubca, slot, CTRLIF_STATUS);
878 if (flags & STATUSREG_DA) {
879 dprintk("CAM supports DA IRQ\n");
880 ca->slot_info[slot].da_irq_supported = 1;
881 }
882 break;
883
884 case DVB_CA_SLOTSTATE_RUNNING:
885 if (ca->open)
886 dvb_ca_en50221_thread_wakeup(ca);
887 break;
888 }
889}
890
891
892
893/* ******************************************************************************** */
894/* EN50221 thread functions */
895
896/**
897 * Wake up the DVB CA thread
898 *
899 * @param ca CA instance.
900 */
901static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca)
902{
903
904 dprintk("%s\n", __func__);
905
906 ca->wakeup = 1;
907 mb();
908 wake_up_process(ca->thread);
909}
910
911/**
912 * Update the delay used by the thread.
913 *
914 * @param ca CA instance.
915 */
916static void dvb_ca_en50221_thread_update_delay(struct dvb_ca_private *ca)
917{
918 int delay;
919 int curdelay = 100000000;
920 int slot;
921
922 /* Beware of too high polling frequency, because one polling
923 * call might take several hundred milliseconds until timeout!
924 */
925 for (slot = 0; slot < ca->slot_count; slot++) {
926 switch (ca->slot_info[slot].slot_state) {
927 default:
928 case DVB_CA_SLOTSTATE_NONE:
929 delay = HZ * 60; /* 60s */
930 if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE))
931 delay = HZ * 5; /* 5s */
932 break;
933 case DVB_CA_SLOTSTATE_INVALID:
934 delay = HZ * 60; /* 60s */
935 if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE))
936 delay = HZ / 10; /* 100ms */
937 break;
938
939 case DVB_CA_SLOTSTATE_UNINITIALISED:
940 case DVB_CA_SLOTSTATE_WAITREADY:
941 case DVB_CA_SLOTSTATE_VALIDATE:
942 case DVB_CA_SLOTSTATE_WAITFR:
943 case DVB_CA_SLOTSTATE_LINKINIT:
944 delay = HZ / 10; /* 100ms */
945 break;
946
947 case DVB_CA_SLOTSTATE_RUNNING:
948 delay = HZ * 60; /* 60s */
949 if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE))
950 delay = HZ / 10; /* 100ms */
951 if (ca->open) {
952 if ((!ca->slot_info[slot].da_irq_supported) ||
953 (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_DA)))
954 delay = HZ / 10; /* 100ms */
955 }
956 break;
957 }
958
959 if (delay < curdelay)
960 curdelay = delay;
961 }
962
963 ca->delay = curdelay;
964}
965
966
967
968/**
969 * Kernel thread which monitors CA slots for CAM changes, and performs data transfers.
970 */
971static int dvb_ca_en50221_thread(void *data)
972{
973 struct dvb_ca_private *ca = data;
974 int slot;
975 int flags;
976 int status;
977 int pktcount;
978 void *rxbuf;
979
980 dprintk("%s\n", __func__);
981
982 /* choose the correct initial delay */
983 dvb_ca_en50221_thread_update_delay(ca);
984
985 /* main loop */
986 while (!kthread_should_stop()) {
987 /* sleep for a bit */
988 if (!ca->wakeup) {
989 set_current_state(TASK_INTERRUPTIBLE);
990 schedule_timeout(ca->delay);
991 if (kthread_should_stop())
992 return 0;
993 }
994 ca->wakeup = 0;
995
996 /* go through all the slots processing them */
997 for (slot = 0; slot < ca->slot_count; slot++) {
998
999 mutex_lock(&ca->slot_info[slot].slot_lock);
1000
1001 // check the cam status + deal with CAMCHANGEs
1002 while (dvb_ca_en50221_check_camstatus(ca, slot)) {
1003 /* clear down an old CI slot if necessary */
1004 if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_NONE)
1005 dvb_ca_en50221_slot_shutdown(ca, slot);
1006
1007 /* if a CAM is NOW present, initialise it */
1008 if (ca->slot_info[slot].camchange_type == DVB_CA_EN50221_CAMCHANGE_INSERTED) {
1009 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_UNINITIALISED;
1010 }
1011
1012 /* we've handled one CAMCHANGE */
1013 dvb_ca_en50221_thread_update_delay(ca);
1014 atomic_dec(&ca->slot_info[slot].camchange_count);
1015 }
1016
1017 // CAM state machine
1018 switch (ca->slot_info[slot].slot_state) {
1019 case DVB_CA_SLOTSTATE_NONE:
1020 case DVB_CA_SLOTSTATE_INVALID:
1021 // no action needed
1022 break;
1023
1024 case DVB_CA_SLOTSTATE_UNINITIALISED:
1025 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_WAITREADY;
1026 ca->pub->slot_reset(ca->pub, slot);
1027 ca->slot_info[slot].timeout = jiffies + (INIT_TIMEOUT_SECS * HZ);
1028 break;
1029
1030 case DVB_CA_SLOTSTATE_WAITREADY:
1031 if (time_after(jiffies, ca->slot_info[slot].timeout)) {
1032 printk("dvb_ca adaptor %d: PC card did not respond :(\n",
1033 ca->dvbdev->adapter->num);
1034 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
1035 dvb_ca_en50221_thread_update_delay(ca);
1036 break;
1037 }
1038 // no other action needed; will automatically change state when ready
1039 break;
1040
1041 case DVB_CA_SLOTSTATE_VALIDATE:
1042 if (dvb_ca_en50221_parse_attributes(ca, slot) != 0) {
1043 /* we need this extra check for annoying interfaces like the budget-av */
1044 if ((!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) &&
1045 (ca->pub->poll_slot_status)) {
1046 status = ca->pub->poll_slot_status(ca->pub, slot, 0);
1047 if (!(status & DVB_CA_EN50221_POLL_CAM_PRESENT)) {
1048 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE;
1049 dvb_ca_en50221_thread_update_delay(ca);
1050 break;
1051 }
1052 }
1053
1054 printk("dvb_ca adapter %d: Invalid PC card inserted :(\n",
1055 ca->dvbdev->adapter->num);
1056 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
1057 dvb_ca_en50221_thread_update_delay(ca);
1058 break;
1059 }
1060 if (dvb_ca_en50221_set_configoption(ca, slot) != 0) {
1061 printk("dvb_ca adapter %d: Unable to initialise CAM :(\n",
1062 ca->dvbdev->adapter->num);
1063 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
1064 dvb_ca_en50221_thread_update_delay(ca);
1065 break;
1066 }
1067 if (ca->pub->write_cam_control(ca->pub, slot,
1068 CTRLIF_COMMAND, CMDREG_RS) != 0) {
1069 printk("dvb_ca adapter %d: Unable to reset CAM IF\n",
1070 ca->dvbdev->adapter->num);
1071 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
1072 dvb_ca_en50221_thread_update_delay(ca);
1073 break;
1074 }
1075 dprintk("DVB CAM validated successfully\n");
1076
1077 ca->slot_info[slot].timeout = jiffies + (INIT_TIMEOUT_SECS * HZ);
1078 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_WAITFR;
1079 ca->wakeup = 1;
1080 break;
1081
1082 case DVB_CA_SLOTSTATE_WAITFR:
1083 if (time_after(jiffies, ca->slot_info[slot].timeout)) {
1084 printk("dvb_ca adapter %d: DVB CAM did not respond :(\n",
1085 ca->dvbdev->adapter->num);
1086 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
1087 dvb_ca_en50221_thread_update_delay(ca);
1088 break;
1089 }
1090
1091 flags = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS);
1092 if (flags & STATUSREG_FR) {
1093 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
1094 ca->wakeup = 1;
1095 }
1096 break;
1097
1098 case DVB_CA_SLOTSTATE_LINKINIT:
1099 if (dvb_ca_en50221_link_init(ca, slot) != 0) {
1100 /* we need this extra check for annoying interfaces like the budget-av */
1101 if ((!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) &&
1102 (ca->pub->poll_slot_status)) {
1103 status = ca->pub->poll_slot_status(ca->pub, slot, 0);
1104 if (!(status & DVB_CA_EN50221_POLL_CAM_PRESENT)) {
1105 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE;
1106 dvb_ca_en50221_thread_update_delay(ca);
1107 break;
1108 }
1109 }
1110
1111 printk("dvb_ca adapter %d: DVB CAM link initialisation failed :(\n", ca->dvbdev->adapter->num);
1112 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
1113 dvb_ca_en50221_thread_update_delay(ca);
1114 break;
1115 }
1116
1117 if (ca->slot_info[slot].rx_buffer.data == NULL) {
1118 rxbuf = vmalloc(RX_BUFFER_SIZE);
1119 if (rxbuf == NULL) {
1120 printk("dvb_ca adapter %d: Unable to allocate CAM rx buffer :(\n", ca->dvbdev->adapter->num);
1121 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
1122 dvb_ca_en50221_thread_update_delay(ca);
1123 break;
1124 }
1125 dvb_ringbuffer_init(&ca->slot_info[slot].rx_buffer, rxbuf, RX_BUFFER_SIZE);
1126 }
1127
1128 ca->pub->slot_ts_enable(ca->pub, slot);
1129 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_RUNNING;
1130 dvb_ca_en50221_thread_update_delay(ca);
1131 printk("dvb_ca adapter %d: DVB CAM detected and initialised successfully\n", ca->dvbdev->adapter->num);
1132 break;
1133
1134 case DVB_CA_SLOTSTATE_RUNNING:
1135 if (!ca->open)
1136 break;
1137
1138 // poll slots for data
1139 pktcount = 0;
1140 while ((status = dvb_ca_en50221_read_data(ca, slot, NULL, 0)) > 0) {
1141 if (!ca->open)
1142 break;
1143
1144 /* if a CAMCHANGE occurred at some point, do not do any more processing of this slot */
1145 if (dvb_ca_en50221_check_camstatus(ca, slot)) {
1146 // we dont want to sleep on the next iteration so we can handle the cam change
1147 ca->wakeup = 1;
1148 break;
1149 }
1150
1151 /* check if we've hit our limit this time */
1152 if (++pktcount >= MAX_RX_PACKETS_PER_ITERATION) {
1153 // dont sleep; there is likely to be more data to read
1154 ca->wakeup = 1;
1155 break;
1156 }
1157 }
1158 break;
1159 }
1160
1161 mutex_unlock(&ca->slot_info[slot].slot_lock);
1162 }
1163 }
1164
1165 return 0;
1166}
1167
1168
1169
1170/* ******************************************************************************** */
1171/* EN50221 IO interface functions */
1172
1173/**
1174 * Real ioctl implementation.
1175 * NOTE: CA_SEND_MSG/CA_GET_MSG ioctls have userspace buffers passed to them.
1176 *
1177 * @param inode Inode concerned.
1178 * @param file File concerned.
1179 * @param cmd IOCTL command.
1180 * @param arg Associated argument.
1181 *
1182 * @return 0 on success, <0 on error.
1183 */
1184static int dvb_ca_en50221_io_do_ioctl(struct file *file,
1185 unsigned int cmd, void *parg)
1186{
1187 struct dvb_device *dvbdev = file->private_data;
1188 struct dvb_ca_private *ca = dvbdev->priv;
1189 int err = 0;
1190 int slot;
1191
1192 dprintk("%s\n", __func__);
1193
1194 switch (cmd) {
1195 case CA_RESET:
1196 for (slot = 0; slot < ca->slot_count; slot++) {
1197 mutex_lock(&ca->slot_info[slot].slot_lock);
1198 if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_NONE) {
1199 dvb_ca_en50221_slot_shutdown(ca, slot);
1200 if (ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)
1201 dvb_ca_en50221_camchange_irq(ca->pub,
1202 slot,
1203 DVB_CA_EN50221_CAMCHANGE_INSERTED);
1204 }
1205 mutex_unlock(&ca->slot_info[slot].slot_lock);
1206 }
1207 ca->next_read_slot = 0;
1208 dvb_ca_en50221_thread_wakeup(ca);
1209 break;
1210
1211 case CA_GET_CAP: {
1212 struct ca_caps *caps = parg;
1213
1214 caps->slot_num = ca->slot_count;
1215 caps->slot_type = CA_CI_LINK;
1216 caps->descr_num = 0;
1217 caps->descr_type = 0;
1218 break;
1219 }
1220
1221 case CA_GET_SLOT_INFO: {
1222 struct ca_slot_info *info = parg;
1223
1224 if ((info->num > ca->slot_count) || (info->num < 0))
1225 return -EINVAL;
1226
1227 info->type = CA_CI_LINK;
1228 info->flags = 0;
1229 if ((ca->slot_info[info->num].slot_state != DVB_CA_SLOTSTATE_NONE)
1230 && (ca->slot_info[info->num].slot_state != DVB_CA_SLOTSTATE_INVALID)) {
1231 info->flags = CA_CI_MODULE_PRESENT;
1232 }
1233 if (ca->slot_info[info->num].slot_state == DVB_CA_SLOTSTATE_RUNNING) {
1234 info->flags |= CA_CI_MODULE_READY;
1235 }
1236 break;
1237 }
1238
1239 default:
1240 err = -EINVAL;
1241 break;
1242 }
1243
1244 return err;
1245}
1246
1247
1248/**
1249 * Wrapper for ioctl implementation.
1250 *
1251 * @param inode Inode concerned.
1252 * @param file File concerned.
1253 * @param cmd IOCTL command.
1254 * @param arg Associated argument.
1255 *
1256 * @return 0 on success, <0 on error.
1257 */
1258static long dvb_ca_en50221_io_ioctl(struct file *file,
1259 unsigned int cmd, unsigned long arg)
1260{
1261 return dvb_usercopy(file, cmd, arg, dvb_ca_en50221_io_do_ioctl);
1262}
1263
1264
1265/**
1266 * Implementation of write() syscall.
1267 *
1268 * @param file File structure.
1269 * @param buf Source buffer.
1270 * @param count Size of source buffer.
1271 * @param ppos Position in file (ignored).
1272 *
1273 * @return Number of bytes read, or <0 on error.
1274 */
1275static ssize_t dvb_ca_en50221_io_write(struct file *file,
1276 const char __user * buf, size_t count, loff_t * ppos)
1277{
1278 struct dvb_device *dvbdev = file->private_data;
1279 struct dvb_ca_private *ca = dvbdev->priv;
1280 u8 slot, connection_id;
1281 int status;
1282 u8 fragbuf[HOST_LINK_BUF_SIZE];
1283 int fragpos = 0;
1284 int fraglen;
1285 unsigned long timeout;
1286 int written;
1287
1288 dprintk("%s\n", __func__);
1289
1290 /* Incoming packet has a 2 byte header. hdr[0] = slot_id, hdr[1] = connection_id */
1291 if (count < 2)
1292 return -EINVAL;
1293
1294 /* extract slot & connection id */
1295 if (copy_from_user(&slot, buf, 1))
1296 return -EFAULT;
1297 if (copy_from_user(&connection_id, buf + 1, 1))
1298 return -EFAULT;
1299 buf += 2;
1300 count -= 2;
1301
1302 /* check if the slot is actually running */
1303 if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_RUNNING)
1304 return -EINVAL;
1305
1306 /* fragment the packets & store in the buffer */
1307 while (fragpos < count) {
1308 fraglen = ca->slot_info[slot].link_buf_size - 2;
1309 if ((count - fragpos) < fraglen)
1310 fraglen = count - fragpos;
1311
1312 fragbuf[0] = connection_id;
1313 fragbuf[1] = ((fragpos + fraglen) < count) ? 0x80 : 0x00;
1314 status = copy_from_user(fragbuf + 2, buf + fragpos, fraglen);
1315 if (status) {
1316 status = -EFAULT;
1317 goto exit;
1318 }
1319
1320 timeout = jiffies + HZ / 2;
1321 written = 0;
1322 while (!time_after(jiffies, timeout)) {
1323 /* check the CAM hasn't been removed/reset in the meantime */
1324 if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_RUNNING) {
1325 status = -EIO;
1326 goto exit;
1327 }
1328
1329 mutex_lock(&ca->slot_info[slot].slot_lock);
1330 status = dvb_ca_en50221_write_data(ca, slot, fragbuf, fraglen + 2);
1331 mutex_unlock(&ca->slot_info[slot].slot_lock);
1332 if (status == (fraglen + 2)) {
1333 written = 1;
1334 break;
1335 }
1336 if (status != -EAGAIN)
1337 goto exit;
1338
1339 msleep(1);
1340 }
1341 if (!written) {
1342 status = -EIO;
1343 goto exit;
1344 }
1345
1346 fragpos += fraglen;
1347 }
1348 status = count + 2;
1349
1350exit:
1351 return status;
1352}
1353
1354
1355/**
1356 * Condition for waking up in dvb_ca_en50221_io_read_condition
1357 */
1358static int dvb_ca_en50221_io_read_condition(struct dvb_ca_private *ca,
1359 int *result, int *_slot)
1360{
1361 int slot;
1362 int slot_count = 0;
1363 int idx;
1364 size_t fraglen;
1365 int connection_id = -1;
1366 int found = 0;
1367 u8 hdr[2];
1368
1369 slot = ca->next_read_slot;
1370 while ((slot_count < ca->slot_count) && (!found)) {
1371 if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_RUNNING)
1372 goto nextslot;
1373
1374 if (ca->slot_info[slot].rx_buffer.data == NULL) {
1375 return 0;
1376 }
1377
1378 idx = dvb_ringbuffer_pkt_next(&ca->slot_info[slot].rx_buffer, -1, &fraglen);
1379 while (idx != -1) {
1380 dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 0, hdr, 2);
1381 if (connection_id == -1)
1382 connection_id = hdr[0];
1383 if ((hdr[0] == connection_id) && ((hdr[1] & 0x80) == 0)) {
1384 *_slot = slot;
1385 found = 1;
1386 break;
1387 }
1388
1389 idx = dvb_ringbuffer_pkt_next(&ca->slot_info[slot].rx_buffer, idx, &fraglen);
1390 }
1391
1392nextslot:
1393 slot = (slot + 1) % ca->slot_count;
1394 slot_count++;
1395 }
1396
1397 ca->next_read_slot = slot;
1398 return found;
1399}
1400
1401
1402/**
1403 * Implementation of read() syscall.
1404 *
1405 * @param file File structure.
1406 * @param buf Destination buffer.
1407 * @param count Size of destination buffer.
1408 * @param ppos Position in file (ignored).
1409 *
1410 * @return Number of bytes read, or <0 on error.
1411 */
1412static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user * buf,
1413 size_t count, loff_t * ppos)
1414{
1415 struct dvb_device *dvbdev = file->private_data;
1416 struct dvb_ca_private *ca = dvbdev->priv;
1417 int status;
1418 int result = 0;
1419 u8 hdr[2];
1420 int slot;
1421 int connection_id = -1;
1422 size_t idx, idx2;
1423 int last_fragment = 0;
1424 size_t fraglen;
1425 int pktlen;
1426 int dispose = 0;
1427
1428 dprintk("%s\n", __func__);
1429
1430 /* Outgoing packet has a 2 byte header. hdr[0] = slot_id, hdr[1] = connection_id */
1431 if (count < 2)
1432 return -EINVAL;
1433
1434 /* wait for some data */
1435 if ((status = dvb_ca_en50221_io_read_condition(ca, &result, &slot)) == 0) {
1436
1437 /* if we're in nonblocking mode, exit immediately */
1438 if (file->f_flags & O_NONBLOCK)
1439 return -EWOULDBLOCK;
1440
1441 /* wait for some data */
1442 status = wait_event_interruptible(ca->wait_queue,
1443 dvb_ca_en50221_io_read_condition
1444 (ca, &result, &slot));
1445 }
1446 if ((status < 0) || (result < 0)) {
1447 if (result)
1448 return result;
1449 return status;
1450 }
1451
1452 idx = dvb_ringbuffer_pkt_next(&ca->slot_info[slot].rx_buffer, -1, &fraglen);
1453 pktlen = 2;
1454 do {
1455 if (idx == -1) {
1456 printk("dvb_ca adapter %d: BUG: read packet ended before last_fragment encountered\n", ca->dvbdev->adapter->num);
1457 status = -EIO;
1458 goto exit;
1459 }
1460
1461 dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 0, hdr, 2);
1462 if (connection_id == -1)
1463 connection_id = hdr[0];
1464 if (hdr[0] == connection_id) {
1465 if (pktlen < count) {
1466 if ((pktlen + fraglen - 2) > count) {
1467 fraglen = count - pktlen;
1468 } else {
1469 fraglen -= 2;
1470 }
1471
1472 if ((status = dvb_ringbuffer_pkt_read_user(&ca->slot_info[slot].rx_buffer, idx, 2,
1473 buf + pktlen, fraglen)) < 0) {
1474 goto exit;
1475 }
1476 pktlen += fraglen;
1477 }
1478
1479 if ((hdr[1] & 0x80) == 0)
1480 last_fragment = 1;
1481 dispose = 1;
1482 }
1483
1484 idx2 = dvb_ringbuffer_pkt_next(&ca->slot_info[slot].rx_buffer, idx, &fraglen);
1485 if (dispose)
1486 dvb_ringbuffer_pkt_dispose(&ca->slot_info[slot].rx_buffer, idx);
1487 idx = idx2;
1488 dispose = 0;
1489 } while (!last_fragment);
1490
1491 hdr[0] = slot;
1492 hdr[1] = connection_id;
1493 status = copy_to_user(buf, hdr, 2);
1494 if (status) {
1495 status = -EFAULT;
1496 goto exit;
1497 }
1498 status = pktlen;
1499
1500exit:
1501 return status;
1502}
1503
1504
1505/**
1506 * Implementation of file open syscall.
1507 *
1508 * @param inode Inode concerned.
1509 * @param file File concerned.
1510 *
1511 * @return 0 on success, <0 on failure.
1512 */
1513static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file)
1514{
1515 struct dvb_device *dvbdev = file->private_data;
1516 struct dvb_ca_private *ca = dvbdev->priv;
1517 int err;
1518 int i;
1519
1520 dprintk("%s\n", __func__);
1521
1522 if (!try_module_get(ca->pub->owner))
1523 return -EIO;
1524
1525 err = dvb_generic_open(inode, file);
1526 if (err < 0) {
1527 module_put(ca->pub->owner);
1528 return err;
1529 }
1530
1531 for (i = 0; i < ca->slot_count; i++) {
1532
1533 if (ca->slot_info[i].slot_state == DVB_CA_SLOTSTATE_RUNNING) {
1534 if (ca->slot_info[i].rx_buffer.data != NULL) {
1535 /* it is safe to call this here without locks because
1536 * ca->open == 0. Data is not read in this case */
1537 dvb_ringbuffer_flush(&ca->slot_info[i].rx_buffer);
1538 }
1539 }
1540 }
1541
1542 ca->open = 1;
1543 dvb_ca_en50221_thread_update_delay(ca);
1544 dvb_ca_en50221_thread_wakeup(ca);
1545
1546 return 0;
1547}
1548
1549
1550/**
1551 * Implementation of file close syscall.
1552 *
1553 * @param inode Inode concerned.
1554 * @param file File concerned.
1555 *
1556 * @return 0 on success, <0 on failure.
1557 */
1558static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file)
1559{
1560 struct dvb_device *dvbdev = file->private_data;
1561 struct dvb_ca_private *ca = dvbdev->priv;
1562 int err;
1563
1564 dprintk("%s\n", __func__);
1565
1566 /* mark the CA device as closed */
1567 ca->open = 0;
1568 dvb_ca_en50221_thread_update_delay(ca);
1569
1570 err = dvb_generic_release(inode, file);
1571
1572 module_put(ca->pub->owner);
1573
1574 return err;
1575}
1576
1577
1578/**
1579 * Implementation of poll() syscall.
1580 *
1581 * @param file File concerned.
1582 * @param wait poll wait table.
1583 *
1584 * @return Standard poll mask.
1585 */
1586static unsigned int dvb_ca_en50221_io_poll(struct file *file, poll_table * wait)
1587{
1588 struct dvb_device *dvbdev = file->private_data;
1589 struct dvb_ca_private *ca = dvbdev->priv;
1590 unsigned int mask = 0;
1591 int slot;
1592 int result = 0;
1593
1594 dprintk("%s\n", __func__);
1595
1596 if (dvb_ca_en50221_io_read_condition(ca, &result, &slot) == 1) {
1597 mask |= POLLIN;
1598 }
1599
1600 /* if there is something, return now */
1601 if (mask)
1602 return mask;
1603
1604 /* wait for something to happen */
1605 poll_wait(file, &ca->wait_queue, wait);
1606
1607 if (dvb_ca_en50221_io_read_condition(ca, &result, &slot) == 1) {
1608 mask |= POLLIN;
1609 }
1610
1611 return mask;
1612}
1613EXPORT_SYMBOL(dvb_ca_en50221_init);
1614
1615
1616static const struct file_operations dvb_ca_fops = {
1617 .owner = THIS_MODULE,
1618 .read = dvb_ca_en50221_io_read,
1619 .write = dvb_ca_en50221_io_write,
1620 .unlocked_ioctl = dvb_ca_en50221_io_ioctl,
1621 .open = dvb_ca_en50221_io_open,
1622 .release = dvb_ca_en50221_io_release,
1623 .poll = dvb_ca_en50221_io_poll,
1624 .llseek = noop_llseek,
1625};
1626
1627static struct dvb_device dvbdev_ca = {
1628 .priv = NULL,
1629 .users = 1,
1630 .readers = 1,
1631 .writers = 1,
1632 .fops = &dvb_ca_fops,
1633};
1634
1635
1636/* ******************************************************************************** */
1637/* Initialisation/shutdown functions */
1638
1639
1640/**
1641 * Initialise a new DVB CA EN50221 interface device.
1642 *
1643 * @param dvb_adapter DVB adapter to attach the new CA device to.
1644 * @param ca The dvb_ca instance.
1645 * @param flags Flags describing the CA device (DVB_CA_FLAG_*).
1646 * @param slot_count Number of slots supported.
1647 *
1648 * @return 0 on success, nonzero on failure
1649 */
1650int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
1651 struct dvb_ca_en50221 *pubca, int flags, int slot_count)
1652{
1653 int ret;
1654 struct dvb_ca_private *ca = NULL;
1655 int i;
1656
1657 dprintk("%s\n", __func__);
1658
1659 if (slot_count < 1)
1660 return -EINVAL;
1661
1662 /* initialise the system data */
1663 if ((ca = kzalloc(sizeof(struct dvb_ca_private), GFP_KERNEL)) == NULL) {
1664 ret = -ENOMEM;
1665 goto error;
1666 }
1667 ca->pub = pubca;
1668 ca->flags = flags;
1669 ca->slot_count = slot_count;
1670 if ((ca->slot_info = kcalloc(slot_count, sizeof(struct dvb_ca_slot), GFP_KERNEL)) == NULL) {
1671 ret = -ENOMEM;
1672 goto error;
1673 }
1674 init_waitqueue_head(&ca->wait_queue);
1675 ca->open = 0;
1676 ca->wakeup = 0;
1677 ca->next_read_slot = 0;
1678 pubca->private = ca;
1679
1680 /* register the DVB device */
1681 ret = dvb_register_device(dvb_adapter, &ca->dvbdev, &dvbdev_ca, ca, DVB_DEVICE_CA);
1682 if (ret)
1683 goto error;
1684
1685 /* now initialise each slot */
1686 for (i = 0; i < slot_count; i++) {
1687 memset(&ca->slot_info[i], 0, sizeof(struct dvb_ca_slot));
1688 ca->slot_info[i].slot_state = DVB_CA_SLOTSTATE_NONE;
1689 atomic_set(&ca->slot_info[i].camchange_count, 0);
1690 ca->slot_info[i].camchange_type = DVB_CA_EN50221_CAMCHANGE_REMOVED;
1691 mutex_init(&ca->slot_info[i].slot_lock);
1692 }
1693
1694 if (signal_pending(current)) {
1695 ret = -EINTR;
1696 goto error;
1697 }
1698 mb();
1699
1700 /* create a kthread for monitoring this CA device */
1701 ca->thread = kthread_run(dvb_ca_en50221_thread, ca, "kdvb-ca-%i:%i",
1702 ca->dvbdev->adapter->num, ca->dvbdev->id);
1703 if (IS_ERR(ca->thread)) {
1704 ret = PTR_ERR(ca->thread);
1705 printk("dvb_ca_init: failed to start kernel_thread (%d)\n",
1706 ret);
1707 goto error;
1708 }
1709 return 0;
1710
1711error:
1712 if (ca != NULL) {
1713 if (ca->dvbdev != NULL)
1714 dvb_unregister_device(ca->dvbdev);
1715 kfree(ca->slot_info);
1716 kfree(ca);
1717 }
1718 pubca->private = NULL;
1719 return ret;
1720}
1721EXPORT_SYMBOL(dvb_ca_en50221_release);
1722
1723
1724
1725/**
1726 * Release a DVB CA EN50221 interface device.
1727 *
1728 * @param ca_dev The dvb_device_t instance for the CA device.
1729 * @param ca The associated dvb_ca instance.
1730 */
1731void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca)
1732{
1733 struct dvb_ca_private *ca = pubca->private;
1734 int i;
1735
1736 dprintk("%s\n", __func__);
1737
1738 /* shutdown the thread if there was one */
1739 kthread_stop(ca->thread);
1740
1741 for (i = 0; i < ca->slot_count; i++) {
1742 dvb_ca_en50221_slot_shutdown(ca, i);
1743 vfree(ca->slot_info[i].rx_buffer.data);
1744 }
1745 kfree(ca->slot_info);
1746 dvb_unregister_device(ca->dvbdev);
1747 kfree(ca);
1748 pubca->private = NULL;
1749}
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.h b/drivers/media/dvb/dvb-core/dvb_ca_en50221.h
new file mode 100644
index 00000000000..7df2e141187
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.h
@@ -0,0 +1,136 @@
1/*
2 * dvb_ca.h: generic DVB functions for EN50221 CA interfaces
3 *
4 * Copyright (C) 2004 Andrew de Quincey
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either version 2.1
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#ifndef _DVB_CA_EN50221_H_
22#define _DVB_CA_EN50221_H_
23
24#include <linux/list.h>
25#include <linux/dvb/ca.h>
26
27#include "dvbdev.h"
28
29#define DVB_CA_EN50221_POLL_CAM_PRESENT 1
30#define DVB_CA_EN50221_POLL_CAM_CHANGED 2
31#define DVB_CA_EN50221_POLL_CAM_READY 4
32
33#define DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE 1
34#define DVB_CA_EN50221_FLAG_IRQ_FR 2
35#define DVB_CA_EN50221_FLAG_IRQ_DA 4
36
37#define DVB_CA_EN50221_CAMCHANGE_REMOVED 0
38#define DVB_CA_EN50221_CAMCHANGE_INSERTED 1
39
40
41
42/* Structure describing a CA interface */
43struct dvb_ca_en50221 {
44
45 /* the module owning this structure */
46 struct module* owner;
47
48 /* NOTE: the read_*, write_* and poll_slot_status functions will be
49 * called for different slots concurrently and need to use locks where
50 * and if appropriate. There will be no concurrent access to one slot.
51 */
52
53 /* functions for accessing attribute memory on the CAM */
54 int (*read_attribute_mem)(struct dvb_ca_en50221* ca, int slot, int address);
55 int (*write_attribute_mem)(struct dvb_ca_en50221* ca, int slot, int address, u8 value);
56
57 /* functions for accessing the control interface on the CAM */
58 int (*read_cam_control)(struct dvb_ca_en50221* ca, int slot, u8 address);
59 int (*write_cam_control)(struct dvb_ca_en50221* ca, int slot, u8 address, u8 value);
60
61 /* Functions for controlling slots */
62 int (*slot_reset)(struct dvb_ca_en50221* ca, int slot);
63 int (*slot_shutdown)(struct dvb_ca_en50221* ca, int slot);
64 int (*slot_ts_enable)(struct dvb_ca_en50221* ca, int slot);
65
66 /*
67 * Poll slot status.
68 * Only necessary if DVB_CA_FLAG_EN50221_IRQ_CAMCHANGE is not set
69 */
70 int (*poll_slot_status)(struct dvb_ca_en50221* ca, int slot, int open);
71
72 /* private data, used by caller */
73 void* data;
74
75 /* Opaque data used by the dvb_ca core. Do not modify! */
76 void* private;
77};
78
79
80
81
82/* ******************************************************************************** */
83/* Functions for reporting IRQ events */
84
85/**
86 * A CAMCHANGE IRQ has occurred.
87 *
88 * @param ca CA instance.
89 * @param slot Slot concerned.
90 * @param change_type One of the DVB_CA_CAMCHANGE_* values
91 */
92void dvb_ca_en50221_camchange_irq(struct dvb_ca_en50221* pubca, int slot, int change_type);
93
94/**
95 * A CAMREADY IRQ has occurred.
96 *
97 * @param ca CA instance.
98 * @param slot Slot concerned.
99 */
100void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221* pubca, int slot);
101
102/**
103 * An FR or a DA IRQ has occurred.
104 *
105 * @param ca CA instance.
106 * @param slot Slot concerned.
107 */
108void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221* ca, int slot);
109
110
111
112/* ******************************************************************************** */
113/* Initialisation/shutdown functions */
114
115/**
116 * Initialise a new DVB CA device.
117 *
118 * @param dvb_adapter DVB adapter to attach the new CA device to.
119 * @param ca The dvb_ca instance.
120 * @param flags Flags describing the CA device (DVB_CA_EN50221_FLAG_*).
121 * @param slot_count Number of slots supported.
122 *
123 * @return 0 on success, nonzero on failure
124 */
125extern int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, struct dvb_ca_en50221* ca, int flags, int slot_count);
126
127/**
128 * Release a DVB CA device.
129 *
130 * @param ca The associated dvb_ca instance.
131 */
132extern void dvb_ca_en50221_release(struct dvb_ca_en50221* ca);
133
134
135
136#endif
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
new file mode 100644
index 00000000000..faa3671b649
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -0,0 +1,1299 @@
1/*
2 * dvb_demux.c - DVB kernel demux API
3 *
4 * Copyright (C) 2000-2001 Ralph Metzler <ralph@convergence.de>
5 * & Marcus Metzler <marcus@convergence.de>
6 * for convergence integrated media GmbH
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 *
22 */
23
24#include <linux/sched.h>
25#include <linux/spinlock.h>
26#include <linux/slab.h>
27#include <linux/vmalloc.h>
28#include <linux/module.h>
29#include <linux/poll.h>
30#include <linux/string.h>
31#include <linux/crc32.h>
32#include <asm/uaccess.h>
33#include <asm/div64.h>
34
35#include "dvb_demux.h"
36
37#define NOBUFS
38/*
39** #define DVB_DEMUX_SECTION_LOSS_LOG to monitor payload loss in the syslog
40*/
41// #define DVB_DEMUX_SECTION_LOSS_LOG
42
43static int dvb_demux_tscheck;
44module_param(dvb_demux_tscheck, int, 0644);
45MODULE_PARM_DESC(dvb_demux_tscheck,
46 "enable transport stream continuity and TEI check");
47
48static int dvb_demux_speedcheck;
49module_param(dvb_demux_speedcheck, int, 0644);
50MODULE_PARM_DESC(dvb_demux_speedcheck,
51 "enable transport stream speed check");
52
53#define dprintk_tscheck(x...) do { \
54 if (dvb_demux_tscheck && printk_ratelimit()) \
55 printk(x); \
56 } while (0)
57
58/******************************************************************************
59 * static inlined helper functions
60 ******************************************************************************/
61
62static inline u16 section_length(const u8 *buf)
63{
64 return 3 + ((buf[1] & 0x0f) << 8) + buf[2];
65}
66
67static inline u16 ts_pid(const u8 *buf)
68{
69 return ((buf[1] & 0x1f) << 8) + buf[2];
70}
71
72static inline u8 payload(const u8 *tsp)
73{
74 if (!(tsp[3] & 0x10)) // no payload?
75 return 0;
76
77 if (tsp[3] & 0x20) { // adaptation field?
78 if (tsp[4] > 183) // corrupted data?
79 return 0;
80 else
81 return 184 - 1 - tsp[4];
82 }
83
84 return 184;
85}
86
87static u32 dvb_dmx_crc32(struct dvb_demux_feed *f, const u8 *src, size_t len)
88{
89 return (f->feed.sec.crc_val = crc32_be(f->feed.sec.crc_val, src, len));
90}
91
92static void dvb_dmx_memcopy(struct dvb_demux_feed *f, u8 *d, const u8 *s,
93 size_t len)
94{
95 memcpy(d, s, len);
96}
97
98/******************************************************************************
99 * Software filter functions
100 ******************************************************************************/
101
102static inline int dvb_dmx_swfilter_payload(struct dvb_demux_feed *feed,
103 const u8 *buf)
104{
105 int count = payload(buf);
106 int p;
107 //int ccok;
108 //u8 cc;
109
110 if (count == 0)
111 return -1;
112
113 p = 188 - count;
114
115 /*
116 cc = buf[3] & 0x0f;
117 ccok = ((feed->cc + 1) & 0x0f) == cc;
118 feed->cc = cc;
119 if (!ccok)
120 printk("missed packet!\n");
121 */
122
123 if (buf[1] & 0x40) // PUSI ?
124 feed->peslen = 0xfffa;
125
126 feed->peslen += count;
127
128 return feed->cb.ts(&buf[p], count, NULL, 0, &feed->feed.ts, DMX_OK);
129}
130
131static int dvb_dmx_swfilter_sectionfilter(struct dvb_demux_feed *feed,
132 struct dvb_demux_filter *f)
133{
134 u8 neq = 0;
135 int i;
136
137 for (i = 0; i < DVB_DEMUX_MASK_MAX; i++) {
138 u8 xor = f->filter.filter_value[i] ^ feed->feed.sec.secbuf[i];
139
140 if (f->maskandmode[i] & xor)
141 return 0;
142
143 neq |= f->maskandnotmode[i] & xor;
144 }
145
146 if (f->doneq && !neq)
147 return 0;
148
149 return feed->cb.sec(feed->feed.sec.secbuf, feed->feed.sec.seclen,
150 NULL, 0, &f->filter, DMX_OK);
151}
152
153static inline int dvb_dmx_swfilter_section_feed(struct dvb_demux_feed *feed)
154{
155 struct dvb_demux *demux = feed->demux;
156 struct dvb_demux_filter *f = feed->filter;
157 struct dmx_section_feed *sec = &feed->feed.sec;
158 int section_syntax_indicator;
159
160 if (!sec->is_filtering)
161 return 0;
162
163 if (!f)
164 return 0;
165
166 if (sec->check_crc) {
167 section_syntax_indicator = ((sec->secbuf[1] & 0x80) != 0);
168 if (section_syntax_indicator &&
169 demux->check_crc32(feed, sec->secbuf, sec->seclen))
170 return -1;
171 }
172
173 do {
174 if (dvb_dmx_swfilter_sectionfilter(feed, f) < 0)
175 return -1;
176 } while ((f = f->next) && sec->is_filtering);
177
178 sec->seclen = 0;
179
180 return 0;
181}
182
183static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed)
184{
185 struct dmx_section_feed *sec = &feed->feed.sec;
186
187#ifdef DVB_DEMUX_SECTION_LOSS_LOG
188 if (sec->secbufp < sec->tsfeedp) {
189 int i, n = sec->tsfeedp - sec->secbufp;
190
191 /*
192 * Section padding is done with 0xff bytes entirely.
193 * Due to speed reasons, we won't check all of them
194 * but just first and last.
195 */
196 if (sec->secbuf[0] != 0xff || sec->secbuf[n - 1] != 0xff) {
197 printk("dvb_demux.c section ts padding loss: %d/%d\n",
198 n, sec->tsfeedp);
199 printk("dvb_demux.c pad data:");
200 for (i = 0; i < n; i++)
201 printk(" %02x", sec->secbuf[i]);
202 printk("\n");
203 }
204 }
205#endif
206
207 sec->tsfeedp = sec->secbufp = sec->seclen = 0;
208 sec->secbuf = sec->secbuf_base;
209}
210
211/*
212 * Losless Section Demux 1.4.1 by Emard
213 * Valsecchi Patrick:
214 * - middle of section A (no PUSI)
215 * - end of section A and start of section B
216 * (with PUSI pointing to the start of the second section)
217 *
218 * In this case, without feed->pusi_seen you'll receive a garbage section
219 * consisting of the end of section A. Basically because tsfeedp
220 * is incemented and the use=0 condition is not raised
221 * when the second packet arrives.
222 *
223 * Fix:
224 * when demux is started, let feed->pusi_seen = 0 to
225 * prevent initial feeding of garbage from the end of
226 * previous section. When you for the first time see PUSI=1
227 * then set feed->pusi_seen = 1
228 */
229static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
230 const u8 *buf, u8 len)
231{
232 struct dvb_demux *demux = feed->demux;
233 struct dmx_section_feed *sec = &feed->feed.sec;
234 u16 limit, seclen, n;
235
236 if (sec->tsfeedp >= DMX_MAX_SECFEED_SIZE)
237 return 0;
238
239 if (sec->tsfeedp + len > DMX_MAX_SECFEED_SIZE) {
240#ifdef DVB_DEMUX_SECTION_LOSS_LOG
241 printk("dvb_demux.c section buffer full loss: %d/%d\n",
242 sec->tsfeedp + len - DMX_MAX_SECFEED_SIZE,
243 DMX_MAX_SECFEED_SIZE);
244#endif
245 len = DMX_MAX_SECFEED_SIZE - sec->tsfeedp;
246 }
247
248 if (len <= 0)
249 return 0;
250
251 demux->memcopy(feed, sec->secbuf_base + sec->tsfeedp, buf, len);
252 sec->tsfeedp += len;
253
254 /*
255 * Dump all the sections we can find in the data (Emard)
256 */
257 limit = sec->tsfeedp;
258 if (limit > DMX_MAX_SECFEED_SIZE)
259 return -1; /* internal error should never happen */
260
261 /* to be sure always set secbuf */
262 sec->secbuf = sec->secbuf_base + sec->secbufp;
263
264 for (n = 0; sec->secbufp + 2 < limit; n++) {
265 seclen = section_length(sec->secbuf);
266 if (seclen <= 0 || seclen > DMX_MAX_SECTION_SIZE
267 || seclen + sec->secbufp > limit)
268 return 0;
269 sec->seclen = seclen;
270 sec->crc_val = ~0;
271 /* dump [secbuf .. secbuf+seclen) */
272 if (feed->pusi_seen)
273 dvb_dmx_swfilter_section_feed(feed);
274#ifdef DVB_DEMUX_SECTION_LOSS_LOG
275 else
276 printk("dvb_demux.c pusi not seen, discarding section data\n");
277#endif
278 sec->secbufp += seclen; /* secbufp and secbuf moving together is */
279 sec->secbuf += seclen; /* redundant but saves pointer arithmetic */
280 }
281
282 return 0;
283}
284
285static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed,
286 const u8 *buf)
287{
288 u8 p, count;
289 int ccok, dc_i = 0;
290 u8 cc;
291
292 count = payload(buf);
293
294 if (count == 0) /* count == 0 if no payload or out of range */
295 return -1;
296
297 p = 188 - count; /* payload start */
298
299 cc = buf[3] & 0x0f;
300 ccok = ((feed->cc + 1) & 0x0f) == cc;
301 feed->cc = cc;
302
303 if (buf[3] & 0x20) {
304 /* adaption field present, check for discontinuity_indicator */
305 if ((buf[4] > 0) && (buf[5] & 0x80))
306 dc_i = 1;
307 }
308
309 if (!ccok || dc_i) {
310#ifdef DVB_DEMUX_SECTION_LOSS_LOG
311 printk("dvb_demux.c discontinuity detected %d bytes lost\n",
312 count);
313 /*
314 * those bytes under sume circumstances will again be reported
315 * in the following dvb_dmx_swfilter_section_new
316 */
317#endif
318 /*
319 * Discontinuity detected. Reset pusi_seen = 0 to
320 * stop feeding of suspicious data until next PUSI=1 arrives
321 */
322 feed->pusi_seen = 0;
323 dvb_dmx_swfilter_section_new(feed);
324 }
325
326 if (buf[1] & 0x40) {
327 /* PUSI=1 (is set), section boundary is here */
328 if (count > 1 && buf[p] < count) {
329 const u8 *before = &buf[p + 1];
330 u8 before_len = buf[p];
331 const u8 *after = &before[before_len];
332 u8 after_len = count - 1 - before_len;
333
334 dvb_dmx_swfilter_section_copy_dump(feed, before,
335 before_len);
336 /* before start of new section, set pusi_seen = 1 */
337 feed->pusi_seen = 1;
338 dvb_dmx_swfilter_section_new(feed);
339 dvb_dmx_swfilter_section_copy_dump(feed, after,
340 after_len);
341 }
342#ifdef DVB_DEMUX_SECTION_LOSS_LOG
343 else if (count > 0)
344 printk("dvb_demux.c PUSI=1 but %d bytes lost\n", count);
345#endif
346 } else {
347 /* PUSI=0 (is not set), no section boundary */
348 dvb_dmx_swfilter_section_copy_dump(feed, &buf[p], count);
349 }
350
351 return 0;
352}
353
354static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed,
355 const u8 *buf)
356{
357 switch (feed->type) {
358 case DMX_TYPE_TS:
359 if (!feed->feed.ts.is_filtering)
360 break;
361 if (feed->ts_type & TS_PACKET) {
362 if (feed->ts_type & TS_PAYLOAD_ONLY)
363 dvb_dmx_swfilter_payload(feed, buf);
364 else
365 feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts,
366 DMX_OK);
367 }
368 if (feed->ts_type & TS_DECODER)
369 if (feed->demux->write_to_decoder)
370 feed->demux->write_to_decoder(feed, buf, 188);
371 break;
372
373 case DMX_TYPE_SEC:
374 if (!feed->feed.sec.is_filtering)
375 break;
376 if (dvb_dmx_swfilter_section_packet(feed, buf) < 0)
377 feed->feed.sec.seclen = feed->feed.sec.secbufp = 0;
378 break;
379
380 default:
381 break;
382 }
383}
384
385#define DVR_FEED(f) \
386 (((f)->type == DMX_TYPE_TS) && \
387 ((f)->feed.ts.is_filtering) && \
388 (((f)->ts_type & (TS_PACKET | TS_DEMUX)) == TS_PACKET))
389
390static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
391{
392 struct dvb_demux_feed *feed;
393 u16 pid = ts_pid(buf);
394 int dvr_done = 0;
395
396 if (dvb_demux_speedcheck) {
397 struct timespec cur_time, delta_time;
398 u64 speed_bytes, speed_timedelta;
399
400 demux->speed_pkts_cnt++;
401
402 /* show speed every SPEED_PKTS_INTERVAL packets */
403 if (!(demux->speed_pkts_cnt % SPEED_PKTS_INTERVAL)) {
404 cur_time = current_kernel_time();
405
406 if (demux->speed_last_time.tv_sec != 0 &&
407 demux->speed_last_time.tv_nsec != 0) {
408 delta_time = timespec_sub(cur_time,
409 demux->speed_last_time);
410 speed_bytes = (u64)demux->speed_pkts_cnt
411 * 188 * 8;
412 /* convert to 1024 basis */
413 speed_bytes = 1000 * div64_u64(speed_bytes,
414 1024);
415 speed_timedelta =
416 (u64)timespec_to_ns(&delta_time);
417 speed_timedelta = div64_u64(speed_timedelta,
418 1000000); /* nsec -> usec */
419 printk(KERN_INFO "TS speed %llu Kbits/sec \n",
420 div64_u64(speed_bytes,
421 speed_timedelta));
422 };
423
424 demux->speed_last_time = cur_time;
425 demux->speed_pkts_cnt = 0;
426 };
427 };
428
429 if (demux->cnt_storage && dvb_demux_tscheck) {
430 /* check pkt counter */
431 if (pid < MAX_PID) {
432 if (buf[1] & 0x80)
433 dprintk_tscheck("TEI detected. "
434 "PID=0x%x data1=0x%x\n",
435 pid, buf[1]);
436
437 if ((buf[3] & 0xf) != demux->cnt_storage[pid])
438 dprintk_tscheck("TS packet counter mismatch. "
439 "PID=0x%x expected 0x%x "
440 "got 0x%x\n",
441 pid, demux->cnt_storage[pid],
442 buf[3] & 0xf);
443
444 demux->cnt_storage[pid] = ((buf[3] & 0xf) + 1)&0xf;
445 };
446 /* end check */
447 };
448
449 list_for_each_entry(feed, &demux->feed_list, list_head) {
450 if ((feed->pid != pid) && (feed->pid != 0x2000))
451 continue;
452
453 /* copy each packet only once to the dvr device, even
454 * if a PID is in multiple filters (e.g. video + PCR) */
455 if ((DVR_FEED(feed)) && (dvr_done++))
456 continue;
457
458 if (feed->pid == pid)
459 dvb_dmx_swfilter_packet_type(feed, buf);
460 else if (feed->pid == 0x2000)
461 feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts, DMX_OK);
462 }
463}
464
465void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf,
466 size_t count)
467{
468 spin_lock(&demux->lock);
469
470 while (count--) {
471 if (buf[0] == 0x47)
472 dvb_dmx_swfilter_packet(demux, buf);
473 buf += 188;
474 }
475
476 spin_unlock(&demux->lock);
477}
478
479EXPORT_SYMBOL(dvb_dmx_swfilter_packets);
480
481static inline int find_next_packet(const u8 *buf, int pos, size_t count,
482 const int pktsize)
483{
484 int start = pos, lost;
485
486 while (pos < count) {
487 if (buf[pos] == 0x47 ||
488 (pktsize == 204 && buf[pos] == 0xB8))
489 break;
490 pos++;
491 }
492
493 lost = pos - start;
494 if (lost) {
495 /* This garbage is part of a valid packet? */
496 int backtrack = pos - pktsize;
497 if (backtrack >= 0 && (buf[backtrack] == 0x47 ||
498 (pktsize == 204 && buf[backtrack] == 0xB8)))
499 return backtrack;
500 }
501
502 return pos;
503}
504
505/* Filter all pktsize= 188 or 204 sized packets and skip garbage. */
506static inline void _dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf,
507 size_t count, const int pktsize)
508{
509 int p = 0, i, j;
510 const u8 *q;
511
512 spin_lock(&demux->lock);
513
514 if (demux->tsbufp) { /* tsbuf[0] is now 0x47. */
515 i = demux->tsbufp;
516 j = pktsize - i;
517 if (count < j) {
518 memcpy(&demux->tsbuf[i], buf, count);
519 demux->tsbufp += count;
520 goto bailout;
521 }
522 memcpy(&demux->tsbuf[i], buf, j);
523 if (demux->tsbuf[0] == 0x47) /* double check */
524 dvb_dmx_swfilter_packet(demux, demux->tsbuf);
525 demux->tsbufp = 0;
526 p += j;
527 }
528
529 while (1) {
530 p = find_next_packet(buf, p, count, pktsize);
531 if (p >= count)
532 break;
533 if (count - p < pktsize)
534 break;
535
536 q = &buf[p];
537
538 if (pktsize == 204 && (*q == 0xB8)) {
539 memcpy(demux->tsbuf, q, 188);
540 demux->tsbuf[0] = 0x47;
541 q = demux->tsbuf;
542 }
543 dvb_dmx_swfilter_packet(demux, q);
544 p += pktsize;
545 }
546
547 i = count - p;
548 if (i) {
549 memcpy(demux->tsbuf, &buf[p], i);
550 demux->tsbufp = i;
551 if (pktsize == 204 && demux->tsbuf[0] == 0xB8)
552 demux->tsbuf[0] = 0x47;
553 }
554
555bailout:
556 spin_unlock(&demux->lock);
557}
558
559void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
560{
561 _dvb_dmx_swfilter(demux, buf, count, 188);
562}
563EXPORT_SYMBOL(dvb_dmx_swfilter);
564
565void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
566{
567 _dvb_dmx_swfilter(demux, buf, count, 204);
568}
569EXPORT_SYMBOL(dvb_dmx_swfilter_204);
570
571static struct dvb_demux_filter *dvb_dmx_filter_alloc(struct dvb_demux *demux)
572{
573 int i;
574
575 for (i = 0; i < demux->filternum; i++)
576 if (demux->filter[i].state == DMX_STATE_FREE)
577 break;
578
579 if (i == demux->filternum)
580 return NULL;
581
582 demux->filter[i].state = DMX_STATE_ALLOCATED;
583
584 return &demux->filter[i];
585}
586
587static struct dvb_demux_feed *dvb_dmx_feed_alloc(struct dvb_demux *demux)
588{
589 int i;
590
591 for (i = 0; i < demux->feednum; i++)
592 if (demux->feed[i].state == DMX_STATE_FREE)
593 break;
594
595 if (i == demux->feednum)
596 return NULL;
597
598 demux->feed[i].state = DMX_STATE_ALLOCATED;
599
600 return &demux->feed[i];
601}
602
603static int dvb_demux_feed_find(struct dvb_demux_feed *feed)
604{
605 struct dvb_demux_feed *entry;
606
607 list_for_each_entry(entry, &feed->demux->feed_list, list_head)
608 if (entry == feed)
609 return 1;
610
611 return 0;
612}
613
614static void dvb_demux_feed_add(struct dvb_demux_feed *feed)
615{
616 spin_lock_irq(&feed->demux->lock);
617 if (dvb_demux_feed_find(feed)) {
618 printk(KERN_ERR "%s: feed already in list (type=%x state=%x pid=%x)\n",
619 __func__, feed->type, feed->state, feed->pid);
620 goto out;
621 }
622
623 list_add(&feed->list_head, &feed->demux->feed_list);
624out:
625 spin_unlock_irq(&feed->demux->lock);
626}
627
628static void dvb_demux_feed_del(struct dvb_demux_feed *feed)
629{
630 spin_lock_irq(&feed->demux->lock);
631 if (!(dvb_demux_feed_find(feed))) {
632 printk(KERN_ERR "%s: feed not in list (type=%x state=%x pid=%x)\n",
633 __func__, feed->type, feed->state, feed->pid);
634 goto out;
635 }
636
637 list_del(&feed->list_head);
638out:
639 spin_unlock_irq(&feed->demux->lock);
640}
641
642static int dmx_ts_feed_set(struct dmx_ts_feed *ts_feed, u16 pid, int ts_type,
643 enum dmx_ts_pes pes_type,
644 size_t circular_buffer_size, struct timespec timeout)
645{
646 struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed;
647 struct dvb_demux *demux = feed->demux;
648
649 if (pid > DMX_MAX_PID)
650 return -EINVAL;
651
652 if (mutex_lock_interruptible(&demux->mutex))
653 return -ERESTARTSYS;
654
655 if (ts_type & TS_DECODER) {
656 if (pes_type >= DMX_TS_PES_OTHER) {
657 mutex_unlock(&demux->mutex);
658 return -EINVAL;
659 }
660
661 if (demux->pesfilter[pes_type] &&
662 demux->pesfilter[pes_type] != feed) {
663 mutex_unlock(&demux->mutex);
664 return -EINVAL;
665 }
666
667 demux->pesfilter[pes_type] = feed;
668 demux->pids[pes_type] = pid;
669 }
670
671 dvb_demux_feed_add(feed);
672
673 feed->pid = pid;
674 feed->buffer_size = circular_buffer_size;
675 feed->timeout = timeout;
676 feed->ts_type = ts_type;
677 feed->pes_type = pes_type;
678
679 if (feed->buffer_size) {
680#ifdef NOBUFS
681 feed->buffer = NULL;
682#else
683 feed->buffer = vmalloc(feed->buffer_size);
684 if (!feed->buffer) {
685 mutex_unlock(&demux->mutex);
686 return -ENOMEM;
687 }
688#endif
689 }
690
691 feed->state = DMX_STATE_READY;
692 mutex_unlock(&demux->mutex);
693
694 return 0;
695}
696
697static int dmx_ts_feed_start_filtering(struct dmx_ts_feed *ts_feed)
698{
699 struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed;
700 struct dvb_demux *demux = feed->demux;
701 int ret;
702
703 if (mutex_lock_interruptible(&demux->mutex))
704 return -ERESTARTSYS;
705
706 if (feed->state != DMX_STATE_READY || feed->type != DMX_TYPE_TS) {
707 mutex_unlock(&demux->mutex);
708 return -EINVAL;
709 }
710
711 if (!demux->start_feed) {
712 mutex_unlock(&demux->mutex);
713 return -ENODEV;
714 }
715
716 if ((ret = demux->start_feed(feed)) < 0) {
717 mutex_unlock(&demux->mutex);
718 return ret;
719 }
720
721 spin_lock_irq(&demux->lock);
722 ts_feed->is_filtering = 1;
723 feed->state = DMX_STATE_GO;
724 spin_unlock_irq(&demux->lock);
725 mutex_unlock(&demux->mutex);
726
727 return 0;
728}
729
730static int dmx_ts_feed_stop_filtering(struct dmx_ts_feed *ts_feed)
731{
732 struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed;
733 struct dvb_demux *demux = feed->demux;
734 int ret;
735
736 mutex_lock(&demux->mutex);
737
738 if (feed->state < DMX_STATE_GO) {
739 mutex_unlock(&demux->mutex);
740 return -EINVAL;
741 }
742
743 if (!demux->stop_feed) {
744 mutex_unlock(&demux->mutex);
745 return -ENODEV;
746 }
747
748 ret = demux->stop_feed(feed);
749
750 spin_lock_irq(&demux->lock);
751 ts_feed->is_filtering = 0;
752 feed->state = DMX_STATE_ALLOCATED;
753 spin_unlock_irq(&demux->lock);
754 mutex_unlock(&demux->mutex);
755
756 return ret;
757}
758
759static int dvbdmx_allocate_ts_feed(struct dmx_demux *dmx,
760 struct dmx_ts_feed **ts_feed,
761 dmx_ts_cb callback)
762{
763 struct dvb_demux *demux = (struct dvb_demux *)dmx;
764 struct dvb_demux_feed *feed;
765
766 if (mutex_lock_interruptible(&demux->mutex))
767 return -ERESTARTSYS;
768
769 if (!(feed = dvb_dmx_feed_alloc(demux))) {
770 mutex_unlock(&demux->mutex);
771 return -EBUSY;
772 }
773
774 feed->type = DMX_TYPE_TS;
775 feed->cb.ts = callback;
776 feed->demux = demux;
777 feed->pid = 0xffff;
778 feed->peslen = 0xfffa;
779 feed->buffer = NULL;
780
781 (*ts_feed) = &feed->feed.ts;
782 (*ts_feed)->parent = dmx;
783 (*ts_feed)->priv = NULL;
784 (*ts_feed)->is_filtering = 0;
785 (*ts_feed)->start_filtering = dmx_ts_feed_start_filtering;
786 (*ts_feed)->stop_filtering = dmx_ts_feed_stop_filtering;
787 (*ts_feed)->set = dmx_ts_feed_set;
788
789 if (!(feed->filter = dvb_dmx_filter_alloc(demux))) {
790 feed->state = DMX_STATE_FREE;
791 mutex_unlock(&demux->mutex);
792 return -EBUSY;
793 }
794
795 feed->filter->type = DMX_TYPE_TS;
796 feed->filter->feed = feed;
797 feed->filter->state = DMX_STATE_READY;
798
799 mutex_unlock(&demux->mutex);
800
801 return 0;
802}
803
804static int dvbdmx_release_ts_feed(struct dmx_demux *dmx,
805 struct dmx_ts_feed *ts_feed)
806{
807 struct dvb_demux *demux = (struct dvb_demux *)dmx;
808 struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed;
809
810 mutex_lock(&demux->mutex);
811
812 if (feed->state == DMX_STATE_FREE) {
813 mutex_unlock(&demux->mutex);
814 return -EINVAL;
815 }
816#ifndef NOBUFS
817 vfree(feed->buffer);
818 feed->buffer = NULL;
819#endif
820
821 feed->state = DMX_STATE_FREE;
822 feed->filter->state = DMX_STATE_FREE;
823
824 dvb_demux_feed_del(feed);
825
826 feed->pid = 0xffff;
827
828 if (feed->ts_type & TS_DECODER && feed->pes_type < DMX_TS_PES_OTHER)
829 demux->pesfilter[feed->pes_type] = NULL;
830
831 mutex_unlock(&demux->mutex);
832 return 0;
833}
834
835/******************************************************************************
836 * dmx_section_feed API calls
837 ******************************************************************************/
838
839static int dmx_section_feed_allocate_filter(struct dmx_section_feed *feed,
840 struct dmx_section_filter **filter)
841{
842 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
843 struct dvb_demux *dvbdemux = dvbdmxfeed->demux;
844 struct dvb_demux_filter *dvbdmxfilter;
845
846 if (mutex_lock_interruptible(&dvbdemux->mutex))
847 return -ERESTARTSYS;
848
849 dvbdmxfilter = dvb_dmx_filter_alloc(dvbdemux);
850 if (!dvbdmxfilter) {
851 mutex_unlock(&dvbdemux->mutex);
852 return -EBUSY;
853 }
854
855 spin_lock_irq(&dvbdemux->lock);
856 *filter = &dvbdmxfilter->filter;
857 (*filter)->parent = feed;
858 (*filter)->priv = NULL;
859 dvbdmxfilter->feed = dvbdmxfeed;
860 dvbdmxfilter->type = DMX_TYPE_SEC;
861 dvbdmxfilter->state = DMX_STATE_READY;
862 dvbdmxfilter->next = dvbdmxfeed->filter;
863 dvbdmxfeed->filter = dvbdmxfilter;
864 spin_unlock_irq(&dvbdemux->lock);
865
866 mutex_unlock(&dvbdemux->mutex);
867 return 0;
868}
869
870static int dmx_section_feed_set(struct dmx_section_feed *feed,
871 u16 pid, size_t circular_buffer_size,
872 int check_crc)
873{
874 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
875 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
876
877 if (pid > 0x1fff)
878 return -EINVAL;
879
880 if (mutex_lock_interruptible(&dvbdmx->mutex))
881 return -ERESTARTSYS;
882
883 dvb_demux_feed_add(dvbdmxfeed);
884
885 dvbdmxfeed->pid = pid;
886 dvbdmxfeed->buffer_size = circular_buffer_size;
887 dvbdmxfeed->feed.sec.check_crc = check_crc;
888
889#ifdef NOBUFS
890 dvbdmxfeed->buffer = NULL;
891#else
892 dvbdmxfeed->buffer = vmalloc(dvbdmxfeed->buffer_size);
893 if (!dvbdmxfeed->buffer) {
894 mutex_unlock(&dvbdmx->mutex);
895 return -ENOMEM;
896 }
897#endif
898
899 dvbdmxfeed->state = DMX_STATE_READY;
900 mutex_unlock(&dvbdmx->mutex);
901 return 0;
902}
903
904static void prepare_secfilters(struct dvb_demux_feed *dvbdmxfeed)
905{
906 int i;
907 struct dvb_demux_filter *f;
908 struct dmx_section_filter *sf;
909 u8 mask, mode, doneq;
910
911 if (!(f = dvbdmxfeed->filter))
912 return;
913 do {
914 sf = &f->filter;
915 doneq = 0;
916 for (i = 0; i < DVB_DEMUX_MASK_MAX; i++) {
917 mode = sf->filter_mode[i];
918 mask = sf->filter_mask[i];
919 f->maskandmode[i] = mask & mode;
920 doneq |= f->maskandnotmode[i] = mask & ~mode;
921 }
922 f->doneq = doneq ? 1 : 0;
923 } while ((f = f->next));
924}
925
926static int dmx_section_feed_start_filtering(struct dmx_section_feed *feed)
927{
928 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
929 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
930 int ret;
931
932 if (mutex_lock_interruptible(&dvbdmx->mutex))
933 return -ERESTARTSYS;
934
935 if (feed->is_filtering) {
936 mutex_unlock(&dvbdmx->mutex);
937 return -EBUSY;
938 }
939
940 if (!dvbdmxfeed->filter) {
941 mutex_unlock(&dvbdmx->mutex);
942 return -EINVAL;
943 }
944
945 dvbdmxfeed->feed.sec.tsfeedp = 0;
946 dvbdmxfeed->feed.sec.secbuf = dvbdmxfeed->feed.sec.secbuf_base;
947 dvbdmxfeed->feed.sec.secbufp = 0;
948 dvbdmxfeed->feed.sec.seclen = 0;
949
950 if (!dvbdmx->start_feed) {
951 mutex_unlock(&dvbdmx->mutex);
952 return -ENODEV;
953 }
954
955 prepare_secfilters(dvbdmxfeed);
956
957 if ((ret = dvbdmx->start_feed(dvbdmxfeed)) < 0) {
958 mutex_unlock(&dvbdmx->mutex);
959 return ret;
960 }
961
962 spin_lock_irq(&dvbdmx->lock);
963 feed->is_filtering = 1;
964 dvbdmxfeed->state = DMX_STATE_GO;
965 spin_unlock_irq(&dvbdmx->lock);
966
967 mutex_unlock(&dvbdmx->mutex);
968 return 0;
969}
970
971static int dmx_section_feed_stop_filtering(struct dmx_section_feed *feed)
972{
973 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
974 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
975 int ret;
976
977 mutex_lock(&dvbdmx->mutex);
978
979 if (!dvbdmx->stop_feed) {
980 mutex_unlock(&dvbdmx->mutex);
981 return -ENODEV;
982 }
983
984 ret = dvbdmx->stop_feed(dvbdmxfeed);
985
986 spin_lock_irq(&dvbdmx->lock);
987 dvbdmxfeed->state = DMX_STATE_READY;
988 feed->is_filtering = 0;
989 spin_unlock_irq(&dvbdmx->lock);
990
991 mutex_unlock(&dvbdmx->mutex);
992 return ret;
993}
994
995static int dmx_section_feed_release_filter(struct dmx_section_feed *feed,
996 struct dmx_section_filter *filter)
997{
998 struct dvb_demux_filter *dvbdmxfilter = (struct dvb_demux_filter *)filter, *f;
999 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
1000 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
1001
1002 mutex_lock(&dvbdmx->mutex);
1003
1004 if (dvbdmxfilter->feed != dvbdmxfeed) {
1005 mutex_unlock(&dvbdmx->mutex);
1006 return -EINVAL;
1007 }
1008
1009 if (feed->is_filtering)
1010 feed->stop_filtering(feed);
1011
1012 spin_lock_irq(&dvbdmx->lock);
1013 f = dvbdmxfeed->filter;
1014
1015 if (f == dvbdmxfilter) {
1016 dvbdmxfeed->filter = dvbdmxfilter->next;
1017 } else {
1018 while (f->next != dvbdmxfilter)
1019 f = f->next;
1020 f->next = f->next->next;
1021 }
1022
1023 dvbdmxfilter->state = DMX_STATE_FREE;
1024 spin_unlock_irq(&dvbdmx->lock);
1025 mutex_unlock(&dvbdmx->mutex);
1026 return 0;
1027}
1028
1029static int dvbdmx_allocate_section_feed(struct dmx_demux *demux,
1030 struct dmx_section_feed **feed,
1031 dmx_section_cb callback)
1032{
1033 struct dvb_demux *dvbdmx = (struct dvb_demux *)demux;
1034 struct dvb_demux_feed *dvbdmxfeed;
1035
1036 if (mutex_lock_interruptible(&dvbdmx->mutex))
1037 return -ERESTARTSYS;
1038
1039 if (!(dvbdmxfeed = dvb_dmx_feed_alloc(dvbdmx))) {
1040 mutex_unlock(&dvbdmx->mutex);
1041 return -EBUSY;
1042 }
1043
1044 dvbdmxfeed->type = DMX_TYPE_SEC;
1045 dvbdmxfeed->cb.sec = callback;
1046 dvbdmxfeed->demux = dvbdmx;
1047 dvbdmxfeed->pid = 0xffff;
1048 dvbdmxfeed->feed.sec.secbuf = dvbdmxfeed->feed.sec.secbuf_base;
1049 dvbdmxfeed->feed.sec.secbufp = dvbdmxfeed->feed.sec.seclen = 0;
1050 dvbdmxfeed->feed.sec.tsfeedp = 0;
1051 dvbdmxfeed->filter = NULL;
1052 dvbdmxfeed->buffer = NULL;
1053
1054 (*feed) = &dvbdmxfeed->feed.sec;
1055 (*feed)->is_filtering = 0;
1056 (*feed)->parent = demux;
1057 (*feed)->priv = NULL;
1058
1059 (*feed)->set = dmx_section_feed_set;
1060 (*feed)->allocate_filter = dmx_section_feed_allocate_filter;
1061 (*feed)->start_filtering = dmx_section_feed_start_filtering;
1062 (*feed)->stop_filtering = dmx_section_feed_stop_filtering;
1063 (*feed)->release_filter = dmx_section_feed_release_filter;
1064
1065 mutex_unlock(&dvbdmx->mutex);
1066 return 0;
1067}
1068
1069static int dvbdmx_release_section_feed(struct dmx_demux *demux,
1070 struct dmx_section_feed *feed)
1071{
1072 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
1073 struct dvb_demux *dvbdmx = (struct dvb_demux *)demux;
1074
1075 mutex_lock(&dvbdmx->mutex);
1076
1077 if (dvbdmxfeed->state == DMX_STATE_FREE) {
1078 mutex_unlock(&dvbdmx->mutex);
1079 return -EINVAL;
1080 }
1081#ifndef NOBUFS
1082 vfree(dvbdmxfeed->buffer);
1083 dvbdmxfeed->buffer = NULL;
1084#endif
1085 dvbdmxfeed->state = DMX_STATE_FREE;
1086
1087 dvb_demux_feed_del(dvbdmxfeed);
1088
1089 dvbdmxfeed->pid = 0xffff;
1090
1091 mutex_unlock(&dvbdmx->mutex);
1092 return 0;
1093}
1094
1095/******************************************************************************
1096 * dvb_demux kernel data API calls
1097 ******************************************************************************/
1098
1099static int dvbdmx_open(struct dmx_demux *demux)
1100{
1101 struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
1102
1103 if (dvbdemux->users >= MAX_DVB_DEMUX_USERS)
1104 return -EUSERS;
1105
1106 dvbdemux->users++;
1107 return 0;
1108}
1109
1110static int dvbdmx_close(struct dmx_demux *demux)
1111{
1112 struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
1113
1114 if (dvbdemux->users == 0)
1115 return -ENODEV;
1116
1117 dvbdemux->users--;
1118 //FIXME: release any unneeded resources if users==0
1119 return 0;
1120}
1121
1122static int dvbdmx_write(struct dmx_demux *demux, const char __user *buf, size_t count)
1123{
1124 struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
1125 void *p;
1126
1127 if ((!demux->frontend) || (demux->frontend->source != DMX_MEMORY_FE))
1128 return -EINVAL;
1129
1130 p = memdup_user(buf, count);
1131 if (IS_ERR(p))
1132 return PTR_ERR(p);
1133 if (mutex_lock_interruptible(&dvbdemux->mutex)) {
1134 kfree(p);
1135 return -ERESTARTSYS;
1136 }
1137 dvb_dmx_swfilter(dvbdemux, p, count);
1138 kfree(p);
1139 mutex_unlock(&dvbdemux->mutex);
1140
1141 if (signal_pending(current))
1142 return -EINTR;
1143 return count;
1144}
1145
1146static int dvbdmx_add_frontend(struct dmx_demux *demux,
1147 struct dmx_frontend *frontend)
1148{
1149 struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
1150 struct list_head *head = &dvbdemux->frontend_list;
1151
1152 list_add(&(frontend->connectivity_list), head);
1153
1154 return 0;
1155}
1156
1157static int dvbdmx_remove_frontend(struct dmx_demux *demux,
1158 struct dmx_frontend *frontend)
1159{
1160 struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
1161 struct list_head *pos, *n, *head = &dvbdemux->frontend_list;
1162
1163 list_for_each_safe(pos, n, head) {
1164 if (DMX_FE_ENTRY(pos) == frontend) {
1165 list_del(pos);
1166 return 0;
1167 }
1168 }
1169
1170 return -ENODEV;
1171}
1172
1173static struct list_head *dvbdmx_get_frontends(struct dmx_demux *demux)
1174{
1175 struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
1176
1177 if (list_empty(&dvbdemux->frontend_list))
1178 return NULL;
1179
1180 return &dvbdemux->frontend_list;
1181}
1182
1183static int dvbdmx_connect_frontend(struct dmx_demux *demux,
1184 struct dmx_frontend *frontend)
1185{
1186 struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
1187
1188 if (demux->frontend)
1189 return -EINVAL;
1190
1191 mutex_lock(&dvbdemux->mutex);
1192
1193 demux->frontend = frontend;
1194 mutex_unlock(&dvbdemux->mutex);
1195 return 0;
1196}
1197
1198static int dvbdmx_disconnect_frontend(struct dmx_demux *demux)
1199{
1200 struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
1201
1202 mutex_lock(&dvbdemux->mutex);
1203
1204 demux->frontend = NULL;
1205 mutex_unlock(&dvbdemux->mutex);
1206 return 0;
1207}
1208
1209static int dvbdmx_get_pes_pids(struct dmx_demux *demux, u16 * pids)
1210{
1211 struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
1212
1213 memcpy(pids, dvbdemux->pids, 5 * sizeof(u16));
1214 return 0;
1215}
1216
1217int dvb_dmx_init(struct dvb_demux *dvbdemux)
1218{
1219 int i;
1220 struct dmx_demux *dmx = &dvbdemux->dmx;
1221
1222 dvbdemux->cnt_storage = NULL;
1223 dvbdemux->users = 0;
1224 dvbdemux->filter = vmalloc(dvbdemux->filternum * sizeof(struct dvb_demux_filter));
1225
1226 if (!dvbdemux->filter)
1227 return -ENOMEM;
1228
1229 dvbdemux->feed = vmalloc(dvbdemux->feednum * sizeof(struct dvb_demux_feed));
1230 if (!dvbdemux->feed) {
1231 vfree(dvbdemux->filter);
1232 dvbdemux->filter = NULL;
1233 return -ENOMEM;
1234 }
1235 for (i = 0; i < dvbdemux->filternum; i++) {
1236 dvbdemux->filter[i].state = DMX_STATE_FREE;
1237 dvbdemux->filter[i].index = i;
1238 }
1239 for (i = 0; i < dvbdemux->feednum; i++) {
1240 dvbdemux->feed[i].state = DMX_STATE_FREE;
1241 dvbdemux->feed[i].index = i;
1242 }
1243
1244 dvbdemux->cnt_storage = vmalloc(MAX_PID + 1);
1245 if (!dvbdemux->cnt_storage)
1246 printk(KERN_WARNING "Couldn't allocate memory for TS/TEI check. Disabling it\n");
1247
1248 INIT_LIST_HEAD(&dvbdemux->frontend_list);
1249
1250 for (i = 0; i < DMX_TS_PES_OTHER; i++) {
1251 dvbdemux->pesfilter[i] = NULL;
1252 dvbdemux->pids[i] = 0xffff;
1253 }
1254
1255 INIT_LIST_HEAD(&dvbdemux->feed_list);
1256
1257 dvbdemux->playing = 0;
1258 dvbdemux->recording = 0;
1259 dvbdemux->tsbufp = 0;
1260
1261 if (!dvbdemux->check_crc32)
1262 dvbdemux->check_crc32 = dvb_dmx_crc32;
1263
1264 if (!dvbdemux->memcopy)
1265 dvbdemux->memcopy = dvb_dmx_memcopy;
1266
1267 dmx->frontend = NULL;
1268 dmx->priv = dvbdemux;
1269 dmx->open = dvbdmx_open;
1270 dmx->close = dvbdmx_close;
1271 dmx->write = dvbdmx_write;
1272 dmx->allocate_ts_feed = dvbdmx_allocate_ts_feed;
1273 dmx->release_ts_feed = dvbdmx_release_ts_feed;
1274 dmx->allocate_section_feed = dvbdmx_allocate_section_feed;
1275 dmx->release_section_feed = dvbdmx_release_section_feed;
1276
1277 dmx->add_frontend = dvbdmx_add_frontend;
1278 dmx->remove_frontend = dvbdmx_remove_frontend;
1279 dmx->get_frontends = dvbdmx_get_frontends;
1280 dmx->connect_frontend = dvbdmx_connect_frontend;
1281 dmx->disconnect_frontend = dvbdmx_disconnect_frontend;
1282 dmx->get_pes_pids = dvbdmx_get_pes_pids;
1283
1284 mutex_init(&dvbdemux->mutex);
1285 spin_lock_init(&dvbdemux->lock);
1286
1287 return 0;
1288}
1289
1290EXPORT_SYMBOL(dvb_dmx_init);
1291
1292void dvb_dmx_release(struct dvb_demux *dvbdemux)
1293{
1294 vfree(dvbdemux->cnt_storage);
1295 vfree(dvbdemux->filter);
1296 vfree(dvbdemux->feed);
1297}
1298
1299EXPORT_SYMBOL(dvb_dmx_release);
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.h b/drivers/media/dvb/dvb-core/dvb_demux.h
new file mode 100644
index 00000000000..a7d876fd02d
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_demux.h
@@ -0,0 +1,149 @@
1/*
2 * dvb_demux.h: DVB kernel demux API
3 *
4 * Copyright (C) 2000-2001 Marcus Metzler & Ralph Metzler
5 * for convergence integrated media GmbH
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation; either version 2.1
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 *
21 */
22
23#ifndef _DVB_DEMUX_H_
24#define _DVB_DEMUX_H_
25
26#include <linux/time.h>
27#include <linux/timer.h>
28#include <linux/spinlock.h>
29#include <linux/mutex.h>
30
31#include "demux.h"
32
33#define DMX_TYPE_TS 0
34#define DMX_TYPE_SEC 1
35#define DMX_TYPE_PES 2
36
37#define DMX_STATE_FREE 0
38#define DMX_STATE_ALLOCATED 1
39#define DMX_STATE_SET 2
40#define DMX_STATE_READY 3
41#define DMX_STATE_GO 4
42
43#define DVB_DEMUX_MASK_MAX 18
44
45#define MAX_PID 0x1fff
46
47#define SPEED_PKTS_INTERVAL 50000
48
49struct dvb_demux_filter {
50 struct dmx_section_filter filter;
51 u8 maskandmode[DMX_MAX_FILTER_SIZE];
52 u8 maskandnotmode[DMX_MAX_FILTER_SIZE];
53 int doneq;
54
55 struct dvb_demux_filter *next;
56 struct dvb_demux_feed *feed;
57 int index;
58 int state;
59 int type;
60
61 u16 hw_handle;
62 struct timer_list timer;
63};
64
65#define DMX_FEED_ENTRY(pos) list_entry(pos, struct dvb_demux_feed, list_head)
66
67struct dvb_demux_feed {
68 union {
69 struct dmx_ts_feed ts;
70 struct dmx_section_feed sec;
71 } feed;
72
73 union {
74 dmx_ts_cb ts;
75 dmx_section_cb sec;
76 } cb;
77
78 struct dvb_demux *demux;
79 void *priv;
80 int type;
81 int state;
82 u16 pid;
83 u8 *buffer;
84 int buffer_size;
85
86 struct timespec timeout;
87 struct dvb_demux_filter *filter;
88
89 int ts_type;
90 enum dmx_ts_pes pes_type;
91
92 int cc;
93 int pusi_seen; /* prevents feeding of garbage from previous section */
94
95 u16 peslen;
96
97 struct list_head list_head;
98 unsigned int index; /* a unique index for each feed (can be used as hardware pid filter index) */
99};
100
101struct dvb_demux {
102 struct dmx_demux dmx;
103 void *priv;
104 int filternum;
105 int feednum;
106 int (*start_feed)(struct dvb_demux_feed *feed);
107 int (*stop_feed)(struct dvb_demux_feed *feed);
108 int (*write_to_decoder)(struct dvb_demux_feed *feed,
109 const u8 *buf, size_t len);
110 u32 (*check_crc32)(struct dvb_demux_feed *feed,
111 const u8 *buf, size_t len);
112 void (*memcopy)(struct dvb_demux_feed *feed, u8 *dst,
113 const u8 *src, size_t len);
114
115 int users;
116#define MAX_DVB_DEMUX_USERS 10
117 struct dvb_demux_filter *filter;
118 struct dvb_demux_feed *feed;
119
120 struct list_head frontend_list;
121
122 struct dvb_demux_feed *pesfilter[DMX_TS_PES_OTHER];
123 u16 pids[DMX_TS_PES_OTHER];
124 int playing;
125 int recording;
126
127#define DMX_MAX_PID 0x2000
128 struct list_head feed_list;
129 u8 tsbuf[204];
130 int tsbufp;
131
132 struct mutex mutex;
133 spinlock_t lock;
134
135 uint8_t *cnt_storage; /* for TS continuity check */
136
137 struct timespec speed_last_time; /* for TS speed check */
138 uint32_t speed_pkts_cnt; /* for TS speed check */
139};
140
141int dvb_dmx_init(struct dvb_demux *dvbdemux);
142void dvb_dmx_release(struct dvb_demux *dvbdemux);
143void dvb_dmx_swfilter_packets(struct dvb_demux *dvbdmx, const u8 *buf,
144 size_t count);
145void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count);
146void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf,
147 size_t count);
148
149#endif /* _DVB_DEMUX_H_ */
diff --git a/drivers/media/dvb/dvb-core/dvb_filter.c b/drivers/media/dvb/dvb-core/dvb_filter.c
new file mode 100644
index 00000000000..772003fb182
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_filter.c
@@ -0,0 +1,603 @@
1#include <linux/kernel.h>
2#include <linux/module.h>
3#include <linux/string.h>
4#include "dvb_filter.h"
5
6#if 0
7static unsigned int bitrates[3][16] =
8{{0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0},
9 {0,32,48,56,64,80,96,112,128,160,192,224,256,320,384,0},
10 {0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0}};
11#endif
12
13static u32 freq[4] = {480, 441, 320, 0};
14
15static unsigned int ac3_bitrates[32] =
16 {32,40,48,56,64,80,96,112,128,160,192,224,256,320,384,448,512,576,640,
17 0,0,0,0,0,0,0,0,0,0,0,0,0};
18
19static u32 ac3_frames[3][32] =
20 {{64,80,96,112,128,160,192,224,256,320,384,448,512,640,768,896,1024,
21 1152,1280,0,0,0,0,0,0,0,0,0,0,0,0,0},
22 {69,87,104,121,139,174,208,243,278,348,417,487,557,696,835,975,1114,
23 1253,1393,0,0,0,0,0,0,0,0,0,0,0,0,0},
24 {96,120,144,168,192,240,288,336,384,480,576,672,768,960,1152,1344,
25 1536,1728,1920,0,0,0,0,0,0,0,0,0,0,0,0,0}};
26
27
28
29#if 0
30static void setup_ts2pes(ipack *pa, ipack *pv, u16 *pida, u16 *pidv,
31 void (*pes_write)(u8 *buf, int count, void *data),
32 void *priv)
33{
34 dvb_filter_ipack_init(pa, IPACKS, pes_write);
35 dvb_filter_ipack_init(pv, IPACKS, pes_write);
36 pa->pid = pida;
37 pv->pid = pidv;
38 pa->data = priv;
39 pv->data = priv;
40}
41#endif
42
43#if 0
44static void ts_to_pes(ipack *p, u8 *buf) // don't need count (=188)
45{
46 u8 off = 0;
47
48 if (!buf || !p ){
49 printk("NULL POINTER IDIOT\n");
50 return;
51 }
52 if (buf[1]&PAY_START) {
53 if (p->plength == MMAX_PLENGTH-6 && p->found>6){
54 p->plength = p->found-6;
55 p->found = 0;
56 send_ipack(p);
57 dvb_filter_ipack_reset(p);
58 }
59 }
60 if (buf[3] & ADAPT_FIELD) { // adaptation field?
61 off = buf[4] + 1;
62 if (off+4 > 187) return;
63 }
64 dvb_filter_instant_repack(buf+4+off, TS_SIZE-4-off, p);
65}
66#endif
67
68#if 0
69/* needs 5 byte input, returns picture coding type*/
70static int read_picture_header(u8 *headr, struct mpg_picture *pic, int field, int pr)
71{
72 u8 pct;
73
74 if (pr) printk( "Pic header: ");
75 pic->temporal_reference[field] = (( headr[0] << 2 ) |
76 (headr[1] & 0x03) )& 0x03ff;
77 if (pr) printk( " temp ref: 0x%04x", pic->temporal_reference[field]);
78
79 pct = ( headr[1] >> 2 ) & 0x07;
80 pic->picture_coding_type[field] = pct;
81 if (pr) {
82 switch(pct){
83 case I_FRAME:
84 printk( " I-FRAME");
85 break;
86 case B_FRAME:
87 printk( " B-FRAME");
88 break;
89 case P_FRAME:
90 printk( " P-FRAME");
91 break;
92 }
93 }
94
95
96 pic->vinfo.vbv_delay = (( headr[1] >> 5 ) | ( headr[2] << 3) |
97 ( (headr[3] & 0x1F) << 11) ) & 0xffff;
98
99 if (pr) printk( " vbv delay: 0x%04x", pic->vinfo.vbv_delay);
100
101 pic->picture_header_parameter = ( headr[3] & 0xe0 ) |
102 ((headr[4] & 0x80) >> 3);
103
104 if ( pct == B_FRAME ){
105 pic->picture_header_parameter |= ( headr[4] >> 3 ) & 0x0f;
106 }
107 if (pr) printk( " pic head param: 0x%x",
108 pic->picture_header_parameter);
109
110 return pct;
111}
112#endif
113
114#if 0
115/* needs 4 byte input */
116static int read_gop_header(u8 *headr, struct mpg_picture *pic, int pr)
117{
118 if (pr) printk("GOP header: ");
119
120 pic->time_code = (( headr[0] << 17 ) | ( headr[1] << 9) |
121 ( headr[2] << 1 ) | (headr[3] &0x01)) & 0x1ffffff;
122
123 if (pr) printk(" time: %d:%d.%d ", (headr[0]>>2)& 0x1F,
124 ((headr[0]<<4)& 0x30)| ((headr[1]>>4)& 0x0F),
125 ((headr[1]<<3)& 0x38)| ((headr[2]>>5)& 0x0F));
126
127 if ( ( headr[3] & 0x40 ) != 0 ){
128 pic->closed_gop = 1;
129 } else {
130 pic->closed_gop = 0;
131 }
132 if (pr) printk("closed: %d", pic->closed_gop);
133
134 if ( ( headr[3] & 0x20 ) != 0 ){
135 pic->broken_link = 1;
136 } else {
137 pic->broken_link = 0;
138 }
139 if (pr) printk(" broken: %d\n", pic->broken_link);
140
141 return 0;
142}
143#endif
144
145#if 0
146/* needs 8 byte input */
147static int read_sequence_header(u8 *headr, struct dvb_video_info *vi, int pr)
148{
149 int sw;
150 int form = -1;
151
152 if (pr) printk("Reading sequence header\n");
153
154 vi->horizontal_size = ((headr[1] &0xF0) >> 4) | (headr[0] << 4);
155 vi->vertical_size = ((headr[1] &0x0F) << 8) | (headr[2]);
156
157 sw = (int)((headr[3]&0xF0) >> 4) ;
158
159 switch( sw ){
160 case 1:
161 if (pr)
162 printk("Videostream: ASPECT: 1:1");
163 vi->aspect_ratio = 100;
164 break;
165 case 2:
166 if (pr)
167 printk("Videostream: ASPECT: 4:3");
168 vi->aspect_ratio = 133;
169 break;
170 case 3:
171 if (pr)
172 printk("Videostream: ASPECT: 16:9");
173 vi->aspect_ratio = 177;
174 break;
175 case 4:
176 if (pr)
177 printk("Videostream: ASPECT: 2.21:1");
178 vi->aspect_ratio = 221;
179 break;
180
181 case 5 ... 15:
182 if (pr)
183 printk("Videostream: ASPECT: reserved");
184 vi->aspect_ratio = 0;
185 break;
186
187 default:
188 vi->aspect_ratio = 0;
189 return -1;
190 }
191
192 if (pr)
193 printk(" Size = %dx%d",vi->horizontal_size,vi->vertical_size);
194
195 sw = (int)(headr[3]&0x0F);
196
197 switch ( sw ) {
198 case 1:
199 if (pr)
200 printk(" FRate: 23.976 fps");
201 vi->framerate = 23976;
202 form = -1;
203 break;
204 case 2:
205 if (pr)
206 printk(" FRate: 24 fps");
207 vi->framerate = 24000;
208 form = -1;
209 break;
210 case 3:
211 if (pr)
212 printk(" FRate: 25 fps");
213 vi->framerate = 25000;
214 form = VIDEO_MODE_PAL;
215 break;
216 case 4:
217 if (pr)
218 printk(" FRate: 29.97 fps");
219 vi->framerate = 29970;
220 form = VIDEO_MODE_NTSC;
221 break;
222 case 5:
223 if (pr)
224 printk(" FRate: 30 fps");
225 vi->framerate = 30000;
226 form = VIDEO_MODE_NTSC;
227 break;
228 case 6:
229 if (pr)
230 printk(" FRate: 50 fps");
231 vi->framerate = 50000;
232 form = VIDEO_MODE_PAL;
233 break;
234 case 7:
235 if (pr)
236 printk(" FRate: 60 fps");
237 vi->framerate = 60000;
238 form = VIDEO_MODE_NTSC;
239 break;
240 }
241
242 vi->bit_rate = (headr[4] << 10) | (headr[5] << 2) | (headr[6] & 0x03);
243
244 vi->vbv_buffer_size
245 = (( headr[6] & 0xF8) >> 3 ) | (( headr[7] & 0x1F )<< 5);
246
247 if (pr){
248 printk(" BRate: %d Mbit/s",4*(vi->bit_rate)/10000);
249 printk(" vbvbuffer %d",16*1024*(vi->vbv_buffer_size));
250 printk("\n");
251 }
252
253 vi->video_format = form;
254
255 return 0;
256}
257#endif
258
259
260#if 0
261static int get_vinfo(u8 *mbuf, int count, struct dvb_video_info *vi, int pr)
262{
263 u8 *headr;
264 int found = 0;
265 int c = 0;
266
267 while (found < 4 && c+4 < count){
268 u8 *b;
269
270 b = mbuf+c;
271 if ( b[0] == 0x00 && b[1] == 0x00 && b[2] == 0x01
272 && b[3] == 0xb3) found = 4;
273 else {
274 c++;
275 }
276 }
277
278 if (! found) return -1;
279 c += 4;
280 if (c+12 >= count) return -1;
281 headr = mbuf+c;
282 if (read_sequence_header(headr, vi, pr) < 0) return -1;
283 vi->off = c-4;
284 return 0;
285}
286#endif
287
288
289#if 0
290static int get_ainfo(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr)
291{
292 u8 *headr;
293 int found = 0;
294 int c = 0;
295 int fr = 0;
296
297 while (found < 2 && c < count){
298 u8 b[2];
299 memcpy( b, mbuf+c, 2);
300
301 if ( b[0] == 0xff && (b[1] & 0xf8) == 0xf8)
302 found = 2;
303 else {
304 c++;
305 }
306 }
307
308 if (!found) return -1;
309
310 if (c+3 >= count) return -1;
311 headr = mbuf+c;
312
313 ai->layer = (headr[1] & 0x06) >> 1;
314
315 if (pr)
316 printk("Audiostream: Layer: %d", 4-ai->layer);
317
318
319 ai->bit_rate = bitrates[(3-ai->layer)][(headr[2] >> 4 )]*1000;
320
321 if (pr){
322 if (ai->bit_rate == 0)
323 printk(" Bit rate: free");
324 else if (ai->bit_rate == 0xf)
325 printk(" BRate: reserved");
326 else
327 printk(" BRate: %d kb/s", ai->bit_rate/1000);
328 }
329
330 fr = (headr[2] & 0x0c ) >> 2;
331 ai->frequency = freq[fr]*100;
332 if (pr){
333 if (ai->frequency == 3)
334 printk(" Freq: reserved\n");
335 else
336 printk(" Freq: %d kHz\n",ai->frequency);
337
338 }
339 ai->off = c;
340 return 0;
341}
342#endif
343
344
345int dvb_filter_get_ac3info(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr)
346{
347 u8 *headr;
348 int found = 0;
349 int c = 0;
350 u8 frame = 0;
351 int fr = 0;
352
353 while ( !found && c < count){
354 u8 *b = mbuf+c;
355
356 if ( b[0] == 0x0b && b[1] == 0x77 )
357 found = 1;
358 else {
359 c++;
360 }
361 }
362
363 if (!found) return -1;
364 if (pr)
365 printk("Audiostream: AC3");
366
367 ai->off = c;
368 if (c+5 >= count) return -1;
369
370 ai->layer = 0; // 0 for AC3
371 headr = mbuf+c+2;
372
373 frame = (headr[2]&0x3f);
374 ai->bit_rate = ac3_bitrates[frame >> 1]*1000;
375
376 if (pr)
377 printk(" BRate: %d kb/s", (int) ai->bit_rate/1000);
378
379 ai->frequency = (headr[2] & 0xc0 ) >> 6;
380 fr = (headr[2] & 0xc0 ) >> 6;
381 ai->frequency = freq[fr]*100;
382 if (pr) printk (" Freq: %d Hz\n", (int) ai->frequency);
383
384
385 ai->framesize = ac3_frames[fr][frame >> 1];
386 if ((frame & 1) && (fr == 1)) ai->framesize++;
387 ai->framesize = ai->framesize << 1;
388 if (pr) printk (" Framesize %d\n",(int) ai->framesize);
389
390
391 return 0;
392}
393EXPORT_SYMBOL(dvb_filter_get_ac3info);
394
395
396#if 0
397static u8 *skip_pes_header(u8 **bufp)
398{
399 u8 *inbuf = *bufp;
400 u8 *buf = inbuf;
401 u8 *pts = NULL;
402 int skip = 0;
403
404 static const int mpeg1_skip_table[16] = {
405 1, 0xffff, 5, 10, 0xffff, 0xffff, 0xffff, 0xffff,
406 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
407 };
408
409
410 if ((inbuf[6] & 0xc0) == 0x80){ /* mpeg2 */
411 if (buf[7] & PTS_ONLY)
412 pts = buf+9;
413 else pts = NULL;
414 buf = inbuf + 9 + inbuf[8];
415 } else { /* mpeg1 */
416 for (buf = inbuf + 6; *buf == 0xff; buf++)
417 if (buf == inbuf + 6 + 16) {
418 break;
419 }
420 if ((*buf & 0xc0) == 0x40)
421 buf += 2;
422 skip = mpeg1_skip_table [*buf >> 4];
423 if (skip == 5 || skip == 10) pts = buf;
424 else pts = NULL;
425
426 buf += mpeg1_skip_table [*buf >> 4];
427 }
428
429 *bufp = buf;
430 return pts;
431}
432#endif
433
434#if 0
435static void initialize_quant_matrix( u32 *matrix )
436{
437 int i;
438
439 matrix[0] = 0x08101013;
440 matrix[1] = 0x10131616;
441 matrix[2] = 0x16161616;
442 matrix[3] = 0x1a181a1b;
443 matrix[4] = 0x1b1b1a1a;
444 matrix[5] = 0x1a1a1b1b;
445 matrix[6] = 0x1b1d1d1d;
446 matrix[7] = 0x2222221d;
447 matrix[8] = 0x1d1d1b1b;
448 matrix[9] = 0x1d1d2020;
449 matrix[10] = 0x22222526;
450 matrix[11] = 0x25232322;
451 matrix[12] = 0x23262628;
452 matrix[13] = 0x28283030;
453 matrix[14] = 0x2e2e3838;
454 matrix[15] = 0x3a454553;
455
456 for ( i = 16 ; i < 32 ; i++ )
457 matrix[i] = 0x10101010;
458}
459#endif
460
461#if 0
462static void initialize_mpg_picture(struct mpg_picture *pic)
463{
464 int i;
465
466 /* set MPEG1 */
467 pic->mpeg1_flag = 1;
468 pic->profile_and_level = 0x4A ; /* MP@LL */
469 pic->progressive_sequence = 1;
470 pic->low_delay = 0;
471
472 pic->sequence_display_extension_flag = 0;
473 for ( i = 0 ; i < 4 ; i++ ){
474 pic->frame_centre_horizontal_offset[i] = 0;
475 pic->frame_centre_vertical_offset[i] = 0;
476 }
477 pic->last_frame_centre_horizontal_offset = 0;
478 pic->last_frame_centre_vertical_offset = 0;
479
480 pic->picture_display_extension_flag[0] = 0;
481 pic->picture_display_extension_flag[1] = 0;
482 pic->sequence_header_flag = 0;
483 pic->gop_flag = 0;
484 pic->sequence_end_flag = 0;
485}
486#endif
487
488#if 0
489static void mpg_set_picture_parameter( int32_t field_type, struct mpg_picture *pic )
490{
491 int16_t last_h_offset;
492 int16_t last_v_offset;
493
494 int16_t *p_h_offset;
495 int16_t *p_v_offset;
496
497 if ( pic->mpeg1_flag ){
498 pic->picture_structure[field_type] = VIDEO_FRAME_PICTURE;
499 pic->top_field_first = 0;
500 pic->repeat_first_field = 0;
501 pic->progressive_frame = 1;
502 pic->picture_coding_parameter = 0x000010;
503 }
504
505 /* Reset flag */
506 pic->picture_display_extension_flag[field_type] = 0;
507
508 last_h_offset = pic->last_frame_centre_horizontal_offset;
509 last_v_offset = pic->last_frame_centre_vertical_offset;
510 if ( field_type == FIRST_FIELD ){
511 p_h_offset = pic->frame_centre_horizontal_offset;
512 p_v_offset = pic->frame_centre_vertical_offset;
513 *p_h_offset = last_h_offset;
514 *(p_h_offset + 1) = last_h_offset;
515 *(p_h_offset + 2) = last_h_offset;
516 *p_v_offset = last_v_offset;
517 *(p_v_offset + 1) = last_v_offset;
518 *(p_v_offset + 2) = last_v_offset;
519 } else {
520 pic->frame_centre_horizontal_offset[3] = last_h_offset;
521 pic->frame_centre_vertical_offset[3] = last_v_offset;
522 }
523}
524#endif
525
526#if 0
527static void init_mpg_picture( struct mpg_picture *pic, int chan, int32_t field_type)
528{
529 pic->picture_header = 0;
530 pic->sequence_header_data
531 = ( INIT_HORIZONTAL_SIZE << 20 )
532 | ( INIT_VERTICAL_SIZE << 8 )
533 | ( INIT_ASPECT_RATIO << 4 )
534 | ( INIT_FRAME_RATE );
535 pic->mpeg1_flag = 0;
536 pic->vinfo.horizontal_size
537 = INIT_DISP_HORIZONTAL_SIZE;
538 pic->vinfo.vertical_size
539 = INIT_DISP_VERTICAL_SIZE;
540 pic->picture_display_extension_flag[field_type]
541 = 0;
542 pic->pts_flag[field_type] = 0;
543
544 pic->sequence_gop_header = 0;
545 pic->picture_header = 0;
546 pic->sequence_header_flag = 0;
547 pic->gop_flag = 0;
548 pic->sequence_end_flag = 0;
549 pic->sequence_display_extension_flag = 0;
550 pic->last_frame_centre_horizontal_offset = 0;
551 pic->last_frame_centre_vertical_offset = 0;
552 pic->channel = chan;
553}
554#endif
555
556void dvb_filter_pes2ts_init(struct dvb_filter_pes2ts *p2ts, unsigned short pid,
557 dvb_filter_pes2ts_cb_t *cb, void *priv)
558{
559 unsigned char *buf=p2ts->buf;
560
561 buf[0]=0x47;
562 buf[1]=(pid>>8);
563 buf[2]=pid&0xff;
564 p2ts->cc=0;
565 p2ts->cb=cb;
566 p2ts->priv=priv;
567}
568EXPORT_SYMBOL(dvb_filter_pes2ts_init);
569
570int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts, unsigned char *pes,
571 int len, int payload_start)
572{
573 unsigned char *buf=p2ts->buf;
574 int ret=0, rest;
575
576 //len=6+((pes[4]<<8)|pes[5]);
577
578 if (payload_start)
579 buf[1]|=0x40;
580 else
581 buf[1]&=~0x40;
582 while (len>=184) {
583 buf[3]=0x10|((p2ts->cc++)&0x0f);
584 memcpy(buf+4, pes, 184);
585 if ((ret=p2ts->cb(p2ts->priv, buf)))
586 return ret;
587 len-=184; pes+=184;
588 buf[1]&=~0x40;
589 }
590 if (!len)
591 return 0;
592 buf[3]=0x30|((p2ts->cc++)&0x0f);
593 rest=183-len;
594 if (rest) {
595 buf[5]=0x00;
596 if (rest-1)
597 memset(buf+6, 0xff, rest-1);
598 }
599 buf[4]=rest;
600 memcpy(buf+5+rest, pes, len);
601 return p2ts->cb(p2ts->priv, buf);
602}
603EXPORT_SYMBOL(dvb_filter_pes2ts);
diff --git a/drivers/media/dvb/dvb-core/dvb_filter.h b/drivers/media/dvb/dvb-core/dvb_filter.h
new file mode 100644
index 00000000000..375e3be184b
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_filter.h
@@ -0,0 +1,246 @@
1/*
2 * dvb_filter.h
3 *
4 * Copyright (C) 2003 Convergence GmbH
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either version 2.1
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#ifndef _DVB_FILTER_H_
22#define _DVB_FILTER_H_
23
24#include <linux/slab.h>
25
26#include "demux.h"
27
28typedef int (dvb_filter_pes2ts_cb_t) (void *, unsigned char *);
29
30struct dvb_filter_pes2ts {
31 unsigned char buf[188];
32 unsigned char cc;
33 dvb_filter_pes2ts_cb_t *cb;
34 void *priv;
35};
36
37void dvb_filter_pes2ts_init(struct dvb_filter_pes2ts *p2ts, unsigned short pid,
38 dvb_filter_pes2ts_cb_t *cb, void *priv);
39
40int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts, unsigned char *pes,
41 int len, int payload_start);
42
43
44#define PROG_STREAM_MAP 0xBC
45#define PRIVATE_STREAM1 0xBD
46#define PADDING_STREAM 0xBE
47#define PRIVATE_STREAM2 0xBF
48#define AUDIO_STREAM_S 0xC0
49#define AUDIO_STREAM_E 0xDF
50#define VIDEO_STREAM_S 0xE0
51#define VIDEO_STREAM_E 0xEF
52#define ECM_STREAM 0xF0
53#define EMM_STREAM 0xF1
54#define DSM_CC_STREAM 0xF2
55#define ISO13522_STREAM 0xF3
56#define PROG_STREAM_DIR 0xFF
57
58#define DVB_PICTURE_START 0x00
59#define DVB_USER_START 0xb2
60#define DVB_SEQUENCE_HEADER 0xb3
61#define DVB_SEQUENCE_ERROR 0xb4
62#define DVB_EXTENSION_START 0xb5
63#define DVB_SEQUENCE_END 0xb7
64#define DVB_GOP_START 0xb8
65#define DVB_EXCEPT_SLICE 0xb0
66
67#define SEQUENCE_EXTENSION 0x01
68#define SEQUENCE_DISPLAY_EXTENSION 0x02
69#define PICTURE_CODING_EXTENSION 0x08
70#define QUANT_MATRIX_EXTENSION 0x03
71#define PICTURE_DISPLAY_EXTENSION 0x07
72
73#define I_FRAME 0x01
74#define B_FRAME 0x02
75#define P_FRAME 0x03
76
77/* Initialize sequence_data */
78#define INIT_HORIZONTAL_SIZE 720
79#define INIT_VERTICAL_SIZE 576
80#define INIT_ASPECT_RATIO 0x02
81#define INIT_FRAME_RATE 0x03
82#define INIT_DISP_HORIZONTAL_SIZE 540
83#define INIT_DISP_VERTICAL_SIZE 576
84
85
86//flags2
87#define PTS_DTS_FLAGS 0xC0
88#define ESCR_FLAG 0x20
89#define ES_RATE_FLAG 0x10
90#define DSM_TRICK_FLAG 0x08
91#define ADD_CPY_FLAG 0x04
92#define PES_CRC_FLAG 0x02
93#define PES_EXT_FLAG 0x01
94
95//pts_dts flags
96#define PTS_ONLY 0x80
97#define PTS_DTS 0xC0
98
99#define TS_SIZE 188
100#define TRANS_ERROR 0x80
101#define PAY_START 0x40
102#define TRANS_PRIO 0x20
103#define PID_MASK_HI 0x1F
104//flags
105#define TRANS_SCRMBL1 0x80
106#define TRANS_SCRMBL2 0x40
107#define ADAPT_FIELD 0x20
108#define PAYLOAD 0x10
109#define COUNT_MASK 0x0F
110
111// adaptation flags
112#define DISCON_IND 0x80
113#define RAND_ACC_IND 0x40
114#define ES_PRI_IND 0x20
115#define PCR_FLAG 0x10
116#define OPCR_FLAG 0x08
117#define SPLICE_FLAG 0x04
118#define TRANS_PRIV 0x02
119#define ADAP_EXT_FLAG 0x01
120
121// adaptation extension flags
122#define LTW_FLAG 0x80
123#define PIECE_RATE 0x40
124#define SEAM_SPLICE 0x20
125
126
127#define MAX_PLENGTH 0xFFFF
128#define MMAX_PLENGTH (256*MAX_PLENGTH)
129
130#ifndef IPACKS
131#define IPACKS 2048
132#endif
133
134struct ipack {
135 int size;
136 int found;
137 u8 *buf;
138 u8 cid;
139 u32 plength;
140 u8 plen[2];
141 u8 flag1;
142 u8 flag2;
143 u8 hlength;
144 u8 pts[5];
145 u16 *pid;
146 int mpeg;
147 u8 check;
148 int which;
149 int done;
150 void *data;
151 void (*func)(u8 *buf, int size, void *priv);
152 int count;
153 int repack_subids;
154};
155
156struct dvb_video_info {
157 u32 horizontal_size;
158 u32 vertical_size;
159 u32 aspect_ratio;
160 u32 framerate;
161 u32 video_format;
162 u32 bit_rate;
163 u32 comp_bit_rate;
164 u32 vbv_buffer_size;
165 s16 vbv_delay;
166 u32 CSPF;
167 u32 off;
168};
169
170#define OFF_SIZE 4
171#define FIRST_FIELD 0
172#define SECOND_FIELD 1
173#define VIDEO_FRAME_PICTURE 0x03
174
175struct mpg_picture {
176 int channel;
177 struct dvb_video_info vinfo;
178 u32 *sequence_gop_header;
179 u32 *picture_header;
180 s32 time_code;
181 int low_delay;
182 int closed_gop;
183 int broken_link;
184 int sequence_header_flag;
185 int gop_flag;
186 int sequence_end_flag;
187
188 u8 profile_and_level;
189 s32 picture_coding_parameter;
190 u32 matrix[32];
191 s8 matrix_change_flag;
192
193 u8 picture_header_parameter;
194 /* bit 0 - 2: bwd f code
195 bit 3 : fpb vector
196 bit 4 - 6: fwd f code
197 bit 7 : fpf vector */
198
199 int mpeg1_flag;
200 int progressive_sequence;
201 int sequence_display_extension_flag;
202 u32 sequence_header_data;
203 s16 last_frame_centre_horizontal_offset;
204 s16 last_frame_centre_vertical_offset;
205
206 u32 pts[2]; /* [0] 1st field, [1] 2nd field */
207 int top_field_first;
208 int repeat_first_field;
209 int progressive_frame;
210 int bank;
211 int forward_bank;
212 int backward_bank;
213 int compress;
214 s16 frame_centre_horizontal_offset[OFF_SIZE];
215 /* [0-2] 1st field, [3] 2nd field */
216 s16 frame_centre_vertical_offset[OFF_SIZE];
217 /* [0-2] 1st field, [3] 2nd field */
218 s16 temporal_reference[2];
219 /* [0] 1st field, [1] 2nd field */
220
221 s8 picture_coding_type[2];
222 /* [0] 1st field, [1] 2nd field */
223 s8 picture_structure[2];
224 /* [0] 1st field, [1] 2nd field */
225 s8 picture_display_extension_flag[2];
226 /* [0] 1st field, [1] 2nd field */
227 /* picture_display_extenion() 0:no 1:exit*/
228 s8 pts_flag[2];
229 /* [0] 1st field, [1] 2nd field */
230};
231
232struct dvb_audio_info {
233 int layer;
234 u32 bit_rate;
235 u32 frequency;
236 u32 mode;
237 u32 mode_extension ;
238 u32 emphasis;
239 u32 framesize;
240 u32 off;
241};
242
243int dvb_filter_get_ac3info(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr);
244
245
246#endif
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
new file mode 100644
index 00000000000..efe9c30605e
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -0,0 +1,2173 @@
1/*
2 * dvb_frontend.c: DVB frontend tuning interface/thread
3 *
4 *
5 * Copyright (C) 1999-2001 Ralph Metzler
6 * Marcus Metzler
7 * Holger Waechtler
8 * for convergence integrated media GmbH
9 *
10 * Copyright (C) 2004 Andrew de Quincey (tuning thread cleanup)
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
26 */
27
28#include <linux/string.h>
29#include <linux/kernel.h>
30#include <linux/sched.h>
31#include <linux/wait.h>
32#include <linux/slab.h>
33#include <linux/poll.h>
34#include <linux/semaphore.h>
35#include <linux/module.h>
36#include <linux/list.h>
37#include <linux/freezer.h>
38#include <linux/jiffies.h>
39#include <linux/kthread.h>
40#include <asm/processor.h>
41
42#include "dvb_frontend.h"
43#include "dvbdev.h"
44#include <linux/dvb/version.h>
45
46static int dvb_frontend_debug;
47static int dvb_shutdown_timeout;
48static int dvb_force_auto_inversion;
49static int dvb_override_tune_delay;
50static int dvb_powerdown_on_sleep = 1;
51static int dvb_mfe_wait_time = 5;
52
53module_param_named(frontend_debug, dvb_frontend_debug, int, 0644);
54MODULE_PARM_DESC(frontend_debug, "Turn on/off frontend core debugging (default:off).");
55module_param(dvb_shutdown_timeout, int, 0644);
56MODULE_PARM_DESC(dvb_shutdown_timeout, "wait <shutdown_timeout> seconds after close() before suspending hardware");
57module_param(dvb_force_auto_inversion, int, 0644);
58MODULE_PARM_DESC(dvb_force_auto_inversion, "0: normal (default), 1: INVERSION_AUTO forced always");
59module_param(dvb_override_tune_delay, int, 0644);
60MODULE_PARM_DESC(dvb_override_tune_delay, "0: normal (default), >0 => delay in milliseconds to wait for lock after a tune attempt");
61module_param(dvb_powerdown_on_sleep, int, 0644);
62MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB voltage off on sleep (default)");
63module_param(dvb_mfe_wait_time, int, 0644);
64MODULE_PARM_DESC(dvb_mfe_wait_time, "Wait up to <mfe_wait_time> seconds on open() for multi-frontend to become available (default:5 seconds)");
65
66#define dprintk if (dvb_frontend_debug) printk
67
68#define FESTATE_IDLE 1
69#define FESTATE_RETUNE 2
70#define FESTATE_TUNING_FAST 4
71#define FESTATE_TUNING_SLOW 8
72#define FESTATE_TUNED 16
73#define FESTATE_ZIGZAG_FAST 32
74#define FESTATE_ZIGZAG_SLOW 64
75#define FESTATE_DISEQC 128
76#define FESTATE_ERROR 256
77#define FESTATE_WAITFORLOCK (FESTATE_TUNING_FAST | FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_FAST | FESTATE_ZIGZAG_SLOW | FESTATE_DISEQC)
78#define FESTATE_SEARCHING_FAST (FESTATE_TUNING_FAST | FESTATE_ZIGZAG_FAST)
79#define FESTATE_SEARCHING_SLOW (FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_SLOW)
80#define FESTATE_LOSTLOCK (FESTATE_ZIGZAG_FAST | FESTATE_ZIGZAG_SLOW)
81
82#define FE_ALGO_HW 1
83/*
84 * FESTATE_IDLE. No tuning parameters have been supplied and the loop is idling.
85 * FESTATE_RETUNE. Parameters have been supplied, but we have not yet performed the first tune.
86 * FESTATE_TUNING_FAST. Tuning parameters have been supplied and fast zigzag scan is in progress.
87 * FESTATE_TUNING_SLOW. Tuning parameters have been supplied. Fast zigzag failed, so we're trying again, but slower.
88 * FESTATE_TUNED. The frontend has successfully locked on.
89 * FESTATE_ZIGZAG_FAST. The lock has been lost, and a fast zigzag has been initiated to try and regain it.
90 * FESTATE_ZIGZAG_SLOW. The lock has been lost. Fast zigzag has been failed, so we're trying again, but slower.
91 * FESTATE_DISEQC. A DISEQC command has just been issued.
92 * FESTATE_WAITFORLOCK. When we're waiting for a lock.
93 * FESTATE_SEARCHING_FAST. When we're searching for a signal using a fast zigzag scan.
94 * FESTATE_SEARCHING_SLOW. When we're searching for a signal using a slow zigzag scan.
95 * FESTATE_LOSTLOCK. When the lock has been lost, and we're searching it again.
96 */
97
98#define DVB_FE_NO_EXIT 0
99#define DVB_FE_NORMAL_EXIT 1
100#define DVB_FE_DEVICE_REMOVED 2
101
102static DEFINE_MUTEX(frontend_mutex);
103
104struct dvb_frontend_private {
105
106 /* thread/frontend values */
107 struct dvb_device *dvbdev;
108 struct dvb_frontend_parameters parameters_in;
109 struct dvb_frontend_parameters parameters_out;
110 struct dvb_fe_events events;
111 struct semaphore sem;
112 struct list_head list_head;
113 wait_queue_head_t wait_queue;
114 struct task_struct *thread;
115 unsigned long release_jiffies;
116 unsigned int exit;
117 unsigned int wakeup;
118 fe_status_t status;
119 unsigned long tune_mode_flags;
120 unsigned int delay;
121 unsigned int reinitialise;
122 int tone;
123 int voltage;
124
125 /* swzigzag values */
126 unsigned int state;
127 unsigned int bending;
128 int lnb_drift;
129 unsigned int inversion;
130 unsigned int auto_step;
131 unsigned int auto_sub_step;
132 unsigned int started_auto_step;
133 unsigned int min_delay;
134 unsigned int max_drift;
135 unsigned int step_size;
136 int quality;
137 unsigned int check_wrapped;
138 enum dvbfe_search algo_status;
139};
140
141static void dvb_frontend_wakeup(struct dvb_frontend *fe);
142
143static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status)
144{
145 struct dvb_frontend_private *fepriv = fe->frontend_priv;
146 struct dvb_fe_events *events = &fepriv->events;
147 struct dvb_frontend_event *e;
148 int wp;
149
150 dprintk ("%s\n", __func__);
151
152 if (mutex_lock_interruptible (&events->mtx))
153 return;
154
155 wp = (events->eventw + 1) % MAX_EVENT;
156
157 if (wp == events->eventr) {
158 events->overflow = 1;
159 events->eventr = (events->eventr + 1) % MAX_EVENT;
160 }
161
162 e = &events->events[events->eventw];
163
164 if (status & FE_HAS_LOCK)
165 if (fe->ops.get_frontend)
166 fe->ops.get_frontend(fe, &fepriv->parameters_out);
167
168 e->parameters = fepriv->parameters_out;
169
170 events->eventw = wp;
171
172 mutex_unlock(&events->mtx);
173
174 e->status = status;
175
176 wake_up_interruptible (&events->wait_queue);
177}
178
179static int dvb_frontend_get_event(struct dvb_frontend *fe,
180 struct dvb_frontend_event *event, int flags)
181{
182 struct dvb_frontend_private *fepriv = fe->frontend_priv;
183 struct dvb_fe_events *events = &fepriv->events;
184
185 dprintk ("%s\n", __func__);
186
187 if (events->overflow) {
188 events->overflow = 0;
189 return -EOVERFLOW;
190 }
191
192 if (events->eventw == events->eventr) {
193 int ret;
194
195 if (flags & O_NONBLOCK)
196 return -EWOULDBLOCK;
197
198 up(&fepriv->sem);
199
200 ret = wait_event_interruptible (events->wait_queue,
201 events->eventw != events->eventr);
202
203 if (down_interruptible (&fepriv->sem))
204 return -ERESTARTSYS;
205
206 if (ret < 0)
207 return ret;
208 }
209
210 if (mutex_lock_interruptible (&events->mtx))
211 return -ERESTARTSYS;
212
213 memcpy (event, &events->events[events->eventr],
214 sizeof(struct dvb_frontend_event));
215
216 events->eventr = (events->eventr + 1) % MAX_EVENT;
217
218 mutex_unlock(&events->mtx);
219
220 return 0;
221}
222
223static void dvb_frontend_init(struct dvb_frontend *fe)
224{
225 dprintk ("DVB: initialising adapter %i frontend %i (%s)...\n",
226 fe->dvb->num,
227 fe->id,
228 fe->ops.info.name);
229
230 if (fe->ops.init)
231 fe->ops.init(fe);
232 if (fe->ops.tuner_ops.init) {
233 if (fe->ops.i2c_gate_ctrl)
234 fe->ops.i2c_gate_ctrl(fe, 1);
235 fe->ops.tuner_ops.init(fe);
236 if (fe->ops.i2c_gate_ctrl)
237 fe->ops.i2c_gate_ctrl(fe, 0);
238 }
239}
240
241void dvb_frontend_reinitialise(struct dvb_frontend *fe)
242{
243 struct dvb_frontend_private *fepriv = fe->frontend_priv;
244
245 fepriv->reinitialise = 1;
246 dvb_frontend_wakeup(fe);
247}
248EXPORT_SYMBOL(dvb_frontend_reinitialise);
249
250static void dvb_frontend_swzigzag_update_delay(struct dvb_frontend_private *fepriv, int locked)
251{
252 int q2;
253
254 dprintk ("%s\n", __func__);
255
256 if (locked)
257 (fepriv->quality) = (fepriv->quality * 220 + 36*256) / 256;
258 else
259 (fepriv->quality) = (fepriv->quality * 220 + 0) / 256;
260
261 q2 = fepriv->quality - 128;
262 q2 *= q2;
263
264 fepriv->delay = fepriv->min_delay + q2 * HZ / (128*128);
265}
266
267/**
268 * Performs automatic twiddling of frontend parameters.
269 *
270 * @param fe The frontend concerned.
271 * @param check_wrapped Checks if an iteration has completed. DO NOT SET ON THE FIRST ATTEMPT
272 * @returns Number of complete iterations that have been performed.
273 */
274static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wrapped)
275{
276 int autoinversion;
277 int ready = 0;
278 int fe_set_err = 0;
279 struct dvb_frontend_private *fepriv = fe->frontend_priv;
280 int original_inversion = fepriv->parameters_in.inversion;
281 u32 original_frequency = fepriv->parameters_in.frequency;
282
283 /* are we using autoinversion? */
284 autoinversion = ((!(fe->ops.info.caps & FE_CAN_INVERSION_AUTO)) &&
285 (fepriv->parameters_in.inversion == INVERSION_AUTO));
286
287 /* setup parameters correctly */
288 while(!ready) {
289 /* calculate the lnb_drift */
290 fepriv->lnb_drift = fepriv->auto_step * fepriv->step_size;
291
292 /* wrap the auto_step if we've exceeded the maximum drift */
293 if (fepriv->lnb_drift > fepriv->max_drift) {
294 fepriv->auto_step = 0;
295 fepriv->auto_sub_step = 0;
296 fepriv->lnb_drift = 0;
297 }
298
299 /* perform inversion and +/- zigzag */
300 switch(fepriv->auto_sub_step) {
301 case 0:
302 /* try with the current inversion and current drift setting */
303 ready = 1;
304 break;
305
306 case 1:
307 if (!autoinversion) break;
308
309 fepriv->inversion = (fepriv->inversion == INVERSION_OFF) ? INVERSION_ON : INVERSION_OFF;
310 ready = 1;
311 break;
312
313 case 2:
314 if (fepriv->lnb_drift == 0) break;
315
316 fepriv->lnb_drift = -fepriv->lnb_drift;
317 ready = 1;
318 break;
319
320 case 3:
321 if (fepriv->lnb_drift == 0) break;
322 if (!autoinversion) break;
323
324 fepriv->inversion = (fepriv->inversion == INVERSION_OFF) ? INVERSION_ON : INVERSION_OFF;
325 fepriv->lnb_drift = -fepriv->lnb_drift;
326 ready = 1;
327 break;
328
329 default:
330 fepriv->auto_step++;
331 fepriv->auto_sub_step = -1; /* it'll be incremented to 0 in a moment */
332 break;
333 }
334
335 if (!ready) fepriv->auto_sub_step++;
336 }
337
338 /* if this attempt would hit where we started, indicate a complete
339 * iteration has occurred */
340 if ((fepriv->auto_step == fepriv->started_auto_step) &&
341 (fepriv->auto_sub_step == 0) && check_wrapped) {
342 return 1;
343 }
344
345 dprintk("%s: drift:%i inversion:%i auto_step:%i "
346 "auto_sub_step:%i started_auto_step:%i\n",
347 __func__, fepriv->lnb_drift, fepriv->inversion,
348 fepriv->auto_step, fepriv->auto_sub_step, fepriv->started_auto_step);
349
350 /* set the frontend itself */
351 fepriv->parameters_in.frequency += fepriv->lnb_drift;
352 if (autoinversion)
353 fepriv->parameters_in.inversion = fepriv->inversion;
354 if (fe->ops.set_frontend)
355 fe_set_err = fe->ops.set_frontend(fe, &fepriv->parameters_in);
356 fepriv->parameters_out = fepriv->parameters_in;
357 if (fe_set_err < 0) {
358 fepriv->state = FESTATE_ERROR;
359 return fe_set_err;
360 }
361
362 fepriv->parameters_in.frequency = original_frequency;
363 fepriv->parameters_in.inversion = original_inversion;
364
365 fepriv->auto_sub_step++;
366 return 0;
367}
368
369static void dvb_frontend_swzigzag(struct dvb_frontend *fe)
370{
371 fe_status_t s = 0;
372 int retval = 0;
373 struct dvb_frontend_private *fepriv = fe->frontend_priv;
374
375 /* if we've got no parameters, just keep idling */
376 if (fepriv->state & FESTATE_IDLE) {
377 fepriv->delay = 3*HZ;
378 fepriv->quality = 0;
379 return;
380 }
381
382 /* in SCAN mode, we just set the frontend when asked and leave it alone */
383 if (fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT) {
384 if (fepriv->state & FESTATE_RETUNE) {
385 if (fe->ops.set_frontend)
386 retval = fe->ops.set_frontend(fe,
387 &fepriv->parameters_in);
388 fepriv->parameters_out = fepriv->parameters_in;
389 if (retval < 0)
390 fepriv->state = FESTATE_ERROR;
391 else
392 fepriv->state = FESTATE_TUNED;
393 }
394 fepriv->delay = 3*HZ;
395 fepriv->quality = 0;
396 return;
397 }
398
399 /* get the frontend status */
400 if (fepriv->state & FESTATE_RETUNE) {
401 s = 0;
402 } else {
403 if (fe->ops.read_status)
404 fe->ops.read_status(fe, &s);
405 if (s != fepriv->status) {
406 dvb_frontend_add_event(fe, s);
407 fepriv->status = s;
408 }
409 }
410
411 /* if we're not tuned, and we have a lock, move to the TUNED state */
412 if ((fepriv->state & FESTATE_WAITFORLOCK) && (s & FE_HAS_LOCK)) {
413 dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK);
414 fepriv->state = FESTATE_TUNED;
415
416 /* if we're tuned, then we have determined the correct inversion */
417 if ((!(fe->ops.info.caps & FE_CAN_INVERSION_AUTO)) &&
418 (fepriv->parameters_in.inversion == INVERSION_AUTO)) {
419 fepriv->parameters_in.inversion = fepriv->inversion;
420 }
421 return;
422 }
423
424 /* if we are tuned already, check we're still locked */
425 if (fepriv->state & FESTATE_TUNED) {
426 dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK);
427
428 /* we're tuned, and the lock is still good... */
429 if (s & FE_HAS_LOCK) {
430 return;
431 } else { /* if we _WERE_ tuned, but now don't have a lock */
432 fepriv->state = FESTATE_ZIGZAG_FAST;
433 fepriv->started_auto_step = fepriv->auto_step;
434 fepriv->check_wrapped = 0;
435 }
436 }
437
438 /* don't actually do anything if we're in the LOSTLOCK state,
439 * the frontend is set to FE_CAN_RECOVER, and the max_drift is 0 */
440 if ((fepriv->state & FESTATE_LOSTLOCK) &&
441 (fe->ops.info.caps & FE_CAN_RECOVER) && (fepriv->max_drift == 0)) {
442 dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK);
443 return;
444 }
445
446 /* don't do anything if we're in the DISEQC state, since this
447 * might be someone with a motorized dish controlled by DISEQC.
448 * If its actually a re-tune, there will be a SET_FRONTEND soon enough. */
449 if (fepriv->state & FESTATE_DISEQC) {
450 dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK);
451 return;
452 }
453
454 /* if we're in the RETUNE state, set everything up for a brand
455 * new scan, keeping the current inversion setting, as the next
456 * tune is _very_ likely to require the same */
457 if (fepriv->state & FESTATE_RETUNE) {
458 fepriv->lnb_drift = 0;
459 fepriv->auto_step = 0;
460 fepriv->auto_sub_step = 0;
461 fepriv->started_auto_step = 0;
462 fepriv->check_wrapped = 0;
463 }
464
465 /* fast zigzag. */
466 if ((fepriv->state & FESTATE_SEARCHING_FAST) || (fepriv->state & FESTATE_RETUNE)) {
467 fepriv->delay = fepriv->min_delay;
468
469 /* perform a tune */
470 retval = dvb_frontend_swzigzag_autotune(fe,
471 fepriv->check_wrapped);
472 if (retval < 0) {
473 return;
474 } else if (retval) {
475 /* OK, if we've run out of trials at the fast speed.
476 * Drop back to slow for the _next_ attempt */
477 fepriv->state = FESTATE_SEARCHING_SLOW;
478 fepriv->started_auto_step = fepriv->auto_step;
479 return;
480 }
481 fepriv->check_wrapped = 1;
482
483 /* if we've just retuned, enter the ZIGZAG_FAST state.
484 * This ensures we cannot return from an
485 * FE_SET_FRONTEND ioctl before the first frontend tune
486 * occurs */
487 if (fepriv->state & FESTATE_RETUNE) {
488 fepriv->state = FESTATE_TUNING_FAST;
489 }
490 }
491
492 /* slow zigzag */
493 if (fepriv->state & FESTATE_SEARCHING_SLOW) {
494 dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK);
495
496 /* Note: don't bother checking for wrapping; we stay in this
497 * state until we get a lock */
498 dvb_frontend_swzigzag_autotune(fe, 0);
499 }
500}
501
502static int dvb_frontend_is_exiting(struct dvb_frontend *fe)
503{
504 struct dvb_frontend_private *fepriv = fe->frontend_priv;
505
506 if (fepriv->exit != DVB_FE_NO_EXIT)
507 return 1;
508
509 if (fepriv->dvbdev->writers == 1)
510 if (time_after(jiffies, fepriv->release_jiffies +
511 dvb_shutdown_timeout * HZ))
512 return 1;
513
514 return 0;
515}
516
517static int dvb_frontend_should_wakeup(struct dvb_frontend *fe)
518{
519 struct dvb_frontend_private *fepriv = fe->frontend_priv;
520
521 if (fepriv->wakeup) {
522 fepriv->wakeup = 0;
523 return 1;
524 }
525 return dvb_frontend_is_exiting(fe);
526}
527
528static void dvb_frontend_wakeup(struct dvb_frontend *fe)
529{
530 struct dvb_frontend_private *fepriv = fe->frontend_priv;
531
532 fepriv->wakeup = 1;
533 wake_up_interruptible(&fepriv->wait_queue);
534}
535
536static int dvb_frontend_thread(void *data)
537{
538 struct dvb_frontend *fe = data;
539 struct dvb_frontend_private *fepriv = fe->frontend_priv;
540 unsigned long timeout;
541 fe_status_t s;
542 enum dvbfe_algo algo;
543
544 struct dvb_frontend_parameters *params;
545
546 dprintk("%s\n", __func__);
547
548 fepriv->check_wrapped = 0;
549 fepriv->quality = 0;
550 fepriv->delay = 3*HZ;
551 fepriv->status = 0;
552 fepriv->wakeup = 0;
553 fepriv->reinitialise = 0;
554
555 dvb_frontend_init(fe);
556
557 set_freezable();
558 while (1) {
559 up(&fepriv->sem); /* is locked when we enter the thread... */
560restart:
561 timeout = wait_event_interruptible_timeout(fepriv->wait_queue,
562 dvb_frontend_should_wakeup(fe) || kthread_should_stop()
563 || freezing(current),
564 fepriv->delay);
565
566 if (kthread_should_stop() || dvb_frontend_is_exiting(fe)) {
567 /* got signal or quitting */
568 fepriv->exit = DVB_FE_NORMAL_EXIT;
569 break;
570 }
571
572 if (try_to_freeze())
573 goto restart;
574
575 if (down_interruptible(&fepriv->sem))
576 break;
577
578 if (fepriv->reinitialise) {
579 dvb_frontend_init(fe);
580 if (fepriv->tone != -1) {
581 fe->ops.set_tone(fe, fepriv->tone);
582 }
583 if (fepriv->voltage != -1) {
584 fe->ops.set_voltage(fe, fepriv->voltage);
585 }
586 fepriv->reinitialise = 0;
587 }
588
589 /* do an iteration of the tuning loop */
590 if (fe->ops.get_frontend_algo) {
591 algo = fe->ops.get_frontend_algo(fe);
592 switch (algo) {
593 case DVBFE_ALGO_HW:
594 dprintk("%s: Frontend ALGO = DVBFE_ALGO_HW\n", __func__);
595 params = NULL; /* have we been asked to RETUNE ? */
596
597 if (fepriv->state & FESTATE_RETUNE) {
598 dprintk("%s: Retune requested, FESTATE_RETUNE\n", __func__);
599 params = &fepriv->parameters_in;
600 fepriv->state = FESTATE_TUNED;
601 }
602
603 if (fe->ops.tune)
604 fe->ops.tune(fe, params, fepriv->tune_mode_flags, &fepriv->delay, &s);
605 if (params)
606 fepriv->parameters_out = *params;
607
608 if (s != fepriv->status && !(fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT)) {
609 dprintk("%s: state changed, adding current state\n", __func__);
610 dvb_frontend_add_event(fe, s);
611 fepriv->status = s;
612 }
613 break;
614 case DVBFE_ALGO_SW:
615 dprintk("%s: Frontend ALGO = DVBFE_ALGO_SW\n", __func__);
616 dvb_frontend_swzigzag(fe);
617 break;
618 case DVBFE_ALGO_CUSTOM:
619 dprintk("%s: Frontend ALGO = DVBFE_ALGO_CUSTOM, state=%d\n", __func__, fepriv->state);
620 if (fepriv->state & FESTATE_RETUNE) {
621 dprintk("%s: Retune requested, FESTAT_RETUNE\n", __func__);
622 fepriv->state = FESTATE_TUNED;
623 }
624 /* Case where we are going to search for a carrier
625 * User asked us to retune again for some reason, possibly
626 * requesting a search with a new set of parameters
627 */
628 if (fepriv->algo_status & DVBFE_ALGO_SEARCH_AGAIN) {
629 if (fe->ops.search) {
630 fepriv->algo_status = fe->ops.search(fe, &fepriv->parameters_in);
631 /* We did do a search as was requested, the flags are
632 * now unset as well and has the flags wrt to search.
633 */
634 } else {
635 fepriv->algo_status &= ~DVBFE_ALGO_SEARCH_AGAIN;
636 }
637 }
638 /* Track the carrier if the search was successful */
639 if (fepriv->algo_status == DVBFE_ALGO_SEARCH_SUCCESS) {
640 if (fe->ops.track)
641 fe->ops.track(fe, &fepriv->parameters_in);
642 } else {
643 fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN;
644 fepriv->delay = HZ / 2;
645 }
646 fepriv->parameters_out = fepriv->parameters_in;
647 fe->ops.read_status(fe, &s);
648 if (s != fepriv->status) {
649 dvb_frontend_add_event(fe, s); /* update event list */
650 fepriv->status = s;
651 if (!(s & FE_HAS_LOCK)) {
652 fepriv->delay = HZ / 10;
653 fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN;
654 } else {
655 fepriv->delay = 60 * HZ;
656 }
657 }
658 break;
659 default:
660 dprintk("%s: UNDEFINED ALGO !\n", __func__);
661 break;
662 }
663 } else {
664 dvb_frontend_swzigzag(fe);
665 }
666 }
667
668 if (dvb_powerdown_on_sleep) {
669 if (fe->ops.set_voltage)
670 fe->ops.set_voltage(fe, SEC_VOLTAGE_OFF);
671 if (fe->ops.tuner_ops.sleep) {
672 if (fe->ops.i2c_gate_ctrl)
673 fe->ops.i2c_gate_ctrl(fe, 1);
674 fe->ops.tuner_ops.sleep(fe);
675 if (fe->ops.i2c_gate_ctrl)
676 fe->ops.i2c_gate_ctrl(fe, 0);
677 }
678 if (fe->ops.sleep)
679 fe->ops.sleep(fe);
680 }
681
682 fepriv->thread = NULL;
683 if (kthread_should_stop())
684 fepriv->exit = DVB_FE_DEVICE_REMOVED;
685 else
686 fepriv->exit = DVB_FE_NO_EXIT;
687 mb();
688
689 dvb_frontend_wakeup(fe);
690 return 0;
691}
692
693static void dvb_frontend_stop(struct dvb_frontend *fe)
694{
695 struct dvb_frontend_private *fepriv = fe->frontend_priv;
696
697 dprintk ("%s\n", __func__);
698
699 fepriv->exit = DVB_FE_NORMAL_EXIT;
700 mb();
701
702 if (!fepriv->thread)
703 return;
704
705 kthread_stop(fepriv->thread);
706
707 sema_init(&fepriv->sem, 1);
708 fepriv->state = FESTATE_IDLE;
709
710 /* paranoia check in case a signal arrived */
711 if (fepriv->thread)
712 printk("dvb_frontend_stop: warning: thread %p won't exit\n",
713 fepriv->thread);
714}
715
716s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime)
717{
718 return ((curtime.tv_usec < lasttime.tv_usec) ?
719 1000000 - lasttime.tv_usec + curtime.tv_usec :
720 curtime.tv_usec - lasttime.tv_usec);
721}
722EXPORT_SYMBOL(timeval_usec_diff);
723
724static inline void timeval_usec_add(struct timeval *curtime, u32 add_usec)
725{
726 curtime->tv_usec += add_usec;
727 if (curtime->tv_usec >= 1000000) {
728 curtime->tv_usec -= 1000000;
729 curtime->tv_sec++;
730 }
731}
732
733/*
734 * Sleep until gettimeofday() > waketime + add_usec
735 * This needs to be as precise as possible, but as the delay is
736 * usually between 2ms and 32ms, it is done using a scheduled msleep
737 * followed by usleep (normally a busy-wait loop) for the remainder
738 */
739void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec)
740{
741 struct timeval lasttime;
742 s32 delta, newdelta;
743
744 timeval_usec_add(waketime, add_usec);
745
746 do_gettimeofday(&lasttime);
747 delta = timeval_usec_diff(lasttime, *waketime);
748 if (delta > 2500) {
749 msleep((delta - 1500) / 1000);
750 do_gettimeofday(&lasttime);
751 newdelta = timeval_usec_diff(lasttime, *waketime);
752 delta = (newdelta > delta) ? 0 : newdelta;
753 }
754 if (delta > 0)
755 udelay(delta);
756}
757EXPORT_SYMBOL(dvb_frontend_sleep_until);
758
759static int dvb_frontend_start(struct dvb_frontend *fe)
760{
761 int ret;
762 struct dvb_frontend_private *fepriv = fe->frontend_priv;
763 struct task_struct *fe_thread;
764
765 dprintk ("%s\n", __func__);
766
767 if (fepriv->thread) {
768 if (fepriv->exit == DVB_FE_NO_EXIT)
769 return 0;
770 else
771 dvb_frontend_stop (fe);
772 }
773
774 if (signal_pending(current))
775 return -EINTR;
776 if (down_interruptible (&fepriv->sem))
777 return -EINTR;
778
779 fepriv->state = FESTATE_IDLE;
780 fepriv->exit = DVB_FE_NO_EXIT;
781 fepriv->thread = NULL;
782 mb();
783
784 fe_thread = kthread_run(dvb_frontend_thread, fe,
785 "kdvb-ad-%i-fe-%i", fe->dvb->num,fe->id);
786 if (IS_ERR(fe_thread)) {
787 ret = PTR_ERR(fe_thread);
788 printk("dvb_frontend_start: failed to start kthread (%d)\n", ret);
789 up(&fepriv->sem);
790 return ret;
791 }
792 fepriv->thread = fe_thread;
793 return 0;
794}
795
796static void dvb_frontend_get_frequency_limits(struct dvb_frontend *fe,
797 u32 *freq_min, u32 *freq_max)
798{
799 *freq_min = max(fe->ops.info.frequency_min, fe->ops.tuner_ops.info.frequency_min);
800
801 if (fe->ops.info.frequency_max == 0)
802 *freq_max = fe->ops.tuner_ops.info.frequency_max;
803 else if (fe->ops.tuner_ops.info.frequency_max == 0)
804 *freq_max = fe->ops.info.frequency_max;
805 else
806 *freq_max = min(fe->ops.info.frequency_max, fe->ops.tuner_ops.info.frequency_max);
807
808 if (*freq_min == 0 || *freq_max == 0)
809 printk(KERN_WARNING "DVB: adapter %i frontend %u frequency limits undefined - fix the driver\n",
810 fe->dvb->num,fe->id);
811}
812
813static int dvb_frontend_check_parameters(struct dvb_frontend *fe,
814 struct dvb_frontend_parameters *parms)
815{
816 u32 freq_min;
817 u32 freq_max;
818
819 /* range check: frequency */
820 dvb_frontend_get_frequency_limits(fe, &freq_min, &freq_max);
821 if ((freq_min && parms->frequency < freq_min) ||
822 (freq_max && parms->frequency > freq_max)) {
823 printk(KERN_WARNING "DVB: adapter %i frontend %i frequency %u out of range (%u..%u)\n",
824 fe->dvb->num, fe->id, parms->frequency, freq_min, freq_max);
825 return -EINVAL;
826 }
827
828 /* range check: symbol rate */
829 if (fe->ops.info.type == FE_QPSK) {
830 if ((fe->ops.info.symbol_rate_min &&
831 parms->u.qpsk.symbol_rate < fe->ops.info.symbol_rate_min) ||
832 (fe->ops.info.symbol_rate_max &&
833 parms->u.qpsk.symbol_rate > fe->ops.info.symbol_rate_max)) {
834 printk(KERN_WARNING "DVB: adapter %i frontend %i symbol rate %u out of range (%u..%u)\n",
835 fe->dvb->num, fe->id, parms->u.qpsk.symbol_rate,
836 fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max);
837 return -EINVAL;
838 }
839
840 } else if (fe->ops.info.type == FE_QAM) {
841 if ((fe->ops.info.symbol_rate_min &&
842 parms->u.qam.symbol_rate < fe->ops.info.symbol_rate_min) ||
843 (fe->ops.info.symbol_rate_max &&
844 parms->u.qam.symbol_rate > fe->ops.info.symbol_rate_max)) {
845 printk(KERN_WARNING "DVB: adapter %i frontend %i symbol rate %u out of range (%u..%u)\n",
846 fe->dvb->num, fe->id, parms->u.qam.symbol_rate,
847 fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max);
848 return -EINVAL;
849 }
850 }
851
852 /* check for supported modulation */
853 if (fe->ops.info.type == FE_QAM &&
854 (parms->u.qam.modulation > QAM_AUTO ||
855 !((1 << (parms->u.qam.modulation + 10)) & fe->ops.info.caps))) {
856 printk(KERN_WARNING "DVB: adapter %i frontend %i modulation %u not supported\n",
857 fe->dvb->num, fe->id, parms->u.qam.modulation);
858 return -EINVAL;
859 }
860
861 return 0;
862}
863
864static int dvb_frontend_clear_cache(struct dvb_frontend *fe)
865{
866 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
867 int i;
868
869 memset(c, 0, sizeof(struct dtv_frontend_properties));
870
871 c->state = DTV_CLEAR;
872 c->delivery_system = SYS_UNDEFINED;
873 c->inversion = INVERSION_AUTO;
874 c->fec_inner = FEC_AUTO;
875 c->transmission_mode = TRANSMISSION_MODE_AUTO;
876 c->bandwidth_hz = BANDWIDTH_AUTO;
877 c->guard_interval = GUARD_INTERVAL_AUTO;
878 c->hierarchy = HIERARCHY_AUTO;
879 c->symbol_rate = QAM_AUTO;
880 c->code_rate_HP = FEC_AUTO;
881 c->code_rate_LP = FEC_AUTO;
882
883 c->isdbt_partial_reception = -1;
884 c->isdbt_sb_mode = -1;
885 c->isdbt_sb_subchannel = -1;
886 c->isdbt_sb_segment_idx = -1;
887 c->isdbt_sb_segment_count = -1;
888 c->isdbt_layer_enabled = 0x7;
889 for (i = 0; i < 3; i++) {
890 c->layer[i].fec = FEC_AUTO;
891 c->layer[i].modulation = QAM_AUTO;
892 c->layer[i].interleaving = -1;
893 c->layer[i].segment_count = -1;
894 }
895
896 return 0;
897}
898
899#define _DTV_CMD(n, s, b) \
900[n] = { \
901 .name = #n, \
902 .cmd = n, \
903 .set = s,\
904 .buffer = b \
905}
906
907static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = {
908 _DTV_CMD(DTV_TUNE, 1, 0),
909 _DTV_CMD(DTV_CLEAR, 1, 0),
910
911 /* Set */
912 _DTV_CMD(DTV_FREQUENCY, 1, 0),
913 _DTV_CMD(DTV_BANDWIDTH_HZ, 1, 0),
914 _DTV_CMD(DTV_MODULATION, 1, 0),
915 _DTV_CMD(DTV_INVERSION, 1, 0),
916 _DTV_CMD(DTV_DISEQC_MASTER, 1, 1),
917 _DTV_CMD(DTV_SYMBOL_RATE, 1, 0),
918 _DTV_CMD(DTV_INNER_FEC, 1, 0),
919 _DTV_CMD(DTV_VOLTAGE, 1, 0),
920 _DTV_CMD(DTV_TONE, 1, 0),
921 _DTV_CMD(DTV_PILOT, 1, 0),
922 _DTV_CMD(DTV_ROLLOFF, 1, 0),
923 _DTV_CMD(DTV_DELIVERY_SYSTEM, 1, 0),
924 _DTV_CMD(DTV_HIERARCHY, 1, 0),
925 _DTV_CMD(DTV_CODE_RATE_HP, 1, 0),
926 _DTV_CMD(DTV_CODE_RATE_LP, 1, 0),
927 _DTV_CMD(DTV_GUARD_INTERVAL, 1, 0),
928 _DTV_CMD(DTV_TRANSMISSION_MODE, 1, 0),
929
930 _DTV_CMD(DTV_ISDBT_PARTIAL_RECEPTION, 1, 0),
931 _DTV_CMD(DTV_ISDBT_SOUND_BROADCASTING, 1, 0),
932 _DTV_CMD(DTV_ISDBT_SB_SUBCHANNEL_ID, 1, 0),
933 _DTV_CMD(DTV_ISDBT_SB_SEGMENT_IDX, 1, 0),
934 _DTV_CMD(DTV_ISDBT_SB_SEGMENT_COUNT, 1, 0),
935 _DTV_CMD(DTV_ISDBT_LAYER_ENABLED, 1, 0),
936 _DTV_CMD(DTV_ISDBT_LAYERA_FEC, 1, 0),
937 _DTV_CMD(DTV_ISDBT_LAYERA_MODULATION, 1, 0),
938 _DTV_CMD(DTV_ISDBT_LAYERA_SEGMENT_COUNT, 1, 0),
939 _DTV_CMD(DTV_ISDBT_LAYERA_TIME_INTERLEAVING, 1, 0),
940 _DTV_CMD(DTV_ISDBT_LAYERB_FEC, 1, 0),
941 _DTV_CMD(DTV_ISDBT_LAYERB_MODULATION, 1, 0),
942 _DTV_CMD(DTV_ISDBT_LAYERB_SEGMENT_COUNT, 1, 0),
943 _DTV_CMD(DTV_ISDBT_LAYERB_TIME_INTERLEAVING, 1, 0),
944 _DTV_CMD(DTV_ISDBT_LAYERC_FEC, 1, 0),
945 _DTV_CMD(DTV_ISDBT_LAYERC_MODULATION, 1, 0),
946 _DTV_CMD(DTV_ISDBT_LAYERC_SEGMENT_COUNT, 1, 0),
947 _DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING, 1, 0),
948
949 _DTV_CMD(DTV_ISDBT_PARTIAL_RECEPTION, 0, 0),
950 _DTV_CMD(DTV_ISDBT_SOUND_BROADCASTING, 0, 0),
951 _DTV_CMD(DTV_ISDBT_SB_SUBCHANNEL_ID, 0, 0),
952 _DTV_CMD(DTV_ISDBT_SB_SEGMENT_IDX, 0, 0),
953 _DTV_CMD(DTV_ISDBT_SB_SEGMENT_COUNT, 0, 0),
954 _DTV_CMD(DTV_ISDBT_LAYER_ENABLED, 0, 0),
955 _DTV_CMD(DTV_ISDBT_LAYERA_FEC, 0, 0),
956 _DTV_CMD(DTV_ISDBT_LAYERA_MODULATION, 0, 0),
957 _DTV_CMD(DTV_ISDBT_LAYERA_SEGMENT_COUNT, 0, 0),
958 _DTV_CMD(DTV_ISDBT_LAYERA_TIME_INTERLEAVING, 0, 0),
959 _DTV_CMD(DTV_ISDBT_LAYERB_FEC, 0, 0),
960 _DTV_CMD(DTV_ISDBT_LAYERB_MODULATION, 0, 0),
961 _DTV_CMD(DTV_ISDBT_LAYERB_SEGMENT_COUNT, 0, 0),
962 _DTV_CMD(DTV_ISDBT_LAYERB_TIME_INTERLEAVING, 0, 0),
963 _DTV_CMD(DTV_ISDBT_LAYERC_FEC, 0, 0),
964 _DTV_CMD(DTV_ISDBT_LAYERC_MODULATION, 0, 0),
965 _DTV_CMD(DTV_ISDBT_LAYERC_SEGMENT_COUNT, 0, 0),
966 _DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING, 0, 0),
967
968 _DTV_CMD(DTV_ISDBS_TS_ID, 1, 0),
969 _DTV_CMD(DTV_DVBT2_PLP_ID, 1, 0),
970
971 /* Get */
972 _DTV_CMD(DTV_DISEQC_SLAVE_REPLY, 0, 1),
973 _DTV_CMD(DTV_API_VERSION, 0, 0),
974 _DTV_CMD(DTV_CODE_RATE_HP, 0, 0),
975 _DTV_CMD(DTV_CODE_RATE_LP, 0, 0),
976 _DTV_CMD(DTV_GUARD_INTERVAL, 0, 0),
977 _DTV_CMD(DTV_TRANSMISSION_MODE, 0, 0),
978 _DTV_CMD(DTV_HIERARCHY, 0, 0),
979};
980
981static void dtv_property_dump(struct dtv_property *tvp)
982{
983 int i;
984
985 if (tvp->cmd <= 0 || tvp->cmd > DTV_MAX_COMMAND) {
986 printk(KERN_WARNING "%s: tvp.cmd = 0x%08x undefined\n",
987 __func__, tvp->cmd);
988 return;
989 }
990
991 dprintk("%s() tvp.cmd = 0x%08x (%s)\n"
992 ,__func__
993 ,tvp->cmd
994 ,dtv_cmds[ tvp->cmd ].name);
995
996 if(dtv_cmds[ tvp->cmd ].buffer) {
997
998 dprintk("%s() tvp.u.buffer.len = 0x%02x\n"
999 ,__func__
1000 ,tvp->u.buffer.len);
1001
1002 for(i = 0; i < tvp->u.buffer.len; i++)
1003 dprintk("%s() tvp.u.buffer.data[0x%02x] = 0x%02x\n"
1004 ,__func__
1005 ,i
1006 ,tvp->u.buffer.data[i]);
1007
1008 } else
1009 dprintk("%s() tvp.u.data = 0x%08x\n", __func__, tvp->u.data);
1010}
1011
1012static int is_legacy_delivery_system(fe_delivery_system_t s)
1013{
1014 if((s == SYS_UNDEFINED) || (s == SYS_DVBC_ANNEX_AC) ||
1015 (s == SYS_DVBC_ANNEX_B) || (s == SYS_DVBT) || (s == SYS_DVBS) ||
1016 (s == SYS_ATSC))
1017 return 1;
1018
1019 return 0;
1020}
1021
1022/* Synchronise the legacy tuning parameters into the cache, so that demodulator
1023 * drivers can use a single set_frontend tuning function, regardless of whether
1024 * it's being used for the legacy or new API, reducing code and complexity.
1025 */
1026static void dtv_property_cache_sync(struct dvb_frontend *fe,
1027 struct dtv_frontend_properties *c,
1028 const struct dvb_frontend_parameters *p)
1029{
1030 c->frequency = p->frequency;
1031 c->inversion = p->inversion;
1032
1033 switch (fe->ops.info.type) {
1034 case FE_QPSK:
1035 c->modulation = QPSK; /* implied for DVB-S in legacy API */
1036 c->rolloff = ROLLOFF_35;/* implied for DVB-S */
1037 c->symbol_rate = p->u.qpsk.symbol_rate;
1038 c->fec_inner = p->u.qpsk.fec_inner;
1039 c->delivery_system = SYS_DVBS;
1040 break;
1041 case FE_QAM:
1042 c->symbol_rate = p->u.qam.symbol_rate;
1043 c->fec_inner = p->u.qam.fec_inner;
1044 c->modulation = p->u.qam.modulation;
1045 c->delivery_system = SYS_DVBC_ANNEX_AC;
1046 break;
1047 case FE_OFDM:
1048 if (p->u.ofdm.bandwidth == BANDWIDTH_6_MHZ)
1049 c->bandwidth_hz = 6000000;
1050 else if (p->u.ofdm.bandwidth == BANDWIDTH_7_MHZ)
1051 c->bandwidth_hz = 7000000;
1052 else if (p->u.ofdm.bandwidth == BANDWIDTH_8_MHZ)
1053 c->bandwidth_hz = 8000000;
1054 else
1055 /* Including BANDWIDTH_AUTO */
1056 c->bandwidth_hz = 0;
1057 c->code_rate_HP = p->u.ofdm.code_rate_HP;
1058 c->code_rate_LP = p->u.ofdm.code_rate_LP;
1059 c->modulation = p->u.ofdm.constellation;
1060 c->transmission_mode = p->u.ofdm.transmission_mode;
1061 c->guard_interval = p->u.ofdm.guard_interval;
1062 c->hierarchy = p->u.ofdm.hierarchy_information;
1063 c->delivery_system = SYS_DVBT;
1064 break;
1065 case FE_ATSC:
1066 c->modulation = p->u.vsb.modulation;
1067 if ((c->modulation == VSB_8) || (c->modulation == VSB_16))
1068 c->delivery_system = SYS_ATSC;
1069 else
1070 c->delivery_system = SYS_DVBC_ANNEX_B;
1071 break;
1072 }
1073}
1074
1075/* Ensure the cached values are set correctly in the frontend
1076 * legacy tuning structures, for the advanced tuning API.
1077 */
1078static void dtv_property_legacy_params_sync(struct dvb_frontend *fe)
1079{
1080 const struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1081 struct dvb_frontend_private *fepriv = fe->frontend_priv;
1082 struct dvb_frontend_parameters *p = &fepriv->parameters_in;
1083
1084 p->frequency = c->frequency;
1085 p->inversion = c->inversion;
1086
1087 switch (fe->ops.info.type) {
1088 case FE_QPSK:
1089 dprintk("%s() Preparing QPSK req\n", __func__);
1090 p->u.qpsk.symbol_rate = c->symbol_rate;
1091 p->u.qpsk.fec_inner = c->fec_inner;
1092 break;
1093 case FE_QAM:
1094 dprintk("%s() Preparing QAM req\n", __func__);
1095 p->u.qam.symbol_rate = c->symbol_rate;
1096 p->u.qam.fec_inner = c->fec_inner;
1097 p->u.qam.modulation = c->modulation;
1098 break;
1099 case FE_OFDM:
1100 dprintk("%s() Preparing OFDM req\n", __func__);
1101 if (c->bandwidth_hz == 6000000)
1102 p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;
1103 else if (c->bandwidth_hz == 7000000)
1104 p->u.ofdm.bandwidth = BANDWIDTH_7_MHZ;
1105 else if (c->bandwidth_hz == 8000000)
1106 p->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
1107 else
1108 p->u.ofdm.bandwidth = BANDWIDTH_AUTO;
1109 p->u.ofdm.code_rate_HP = c->code_rate_HP;
1110 p->u.ofdm.code_rate_LP = c->code_rate_LP;
1111 p->u.ofdm.constellation = c->modulation;
1112 p->u.ofdm.transmission_mode = c->transmission_mode;
1113 p->u.ofdm.guard_interval = c->guard_interval;
1114 p->u.ofdm.hierarchy_information = c->hierarchy;
1115 break;
1116 case FE_ATSC:
1117 dprintk("%s() Preparing VSB req\n", __func__);
1118 p->u.vsb.modulation = c->modulation;
1119 break;
1120 }
1121}
1122
1123/* Ensure the cached values are set correctly in the frontend
1124 * legacy tuning structures, for the legacy tuning API.
1125 */
1126static void dtv_property_adv_params_sync(struct dvb_frontend *fe)
1127{
1128 const struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1129 struct dvb_frontend_private *fepriv = fe->frontend_priv;
1130 struct dvb_frontend_parameters *p = &fepriv->parameters_in;
1131
1132 p->frequency = c->frequency;
1133 p->inversion = c->inversion;
1134
1135 switch(c->modulation) {
1136 case PSK_8:
1137 case APSK_16:
1138 case APSK_32:
1139 case QPSK:
1140 p->u.qpsk.symbol_rate = c->symbol_rate;
1141 p->u.qpsk.fec_inner = c->fec_inner;
1142 break;
1143 default:
1144 break;
1145 }
1146
1147 /* Fake out a generic DVB-T request so we pass validation in the ioctl */
1148 if ((c->delivery_system == SYS_ISDBT) ||
1149 (c->delivery_system == SYS_DVBT2)) {
1150 p->u.ofdm.constellation = QAM_AUTO;
1151 p->u.ofdm.code_rate_HP = FEC_AUTO;
1152 p->u.ofdm.code_rate_LP = FEC_AUTO;
1153 p->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO;
1154 p->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO;
1155 p->u.ofdm.hierarchy_information = HIERARCHY_AUTO;
1156 if (c->bandwidth_hz == 8000000)
1157 p->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
1158 else if (c->bandwidth_hz == 7000000)
1159 p->u.ofdm.bandwidth = BANDWIDTH_7_MHZ;
1160 else if (c->bandwidth_hz == 6000000)
1161 p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;
1162 else
1163 p->u.ofdm.bandwidth = BANDWIDTH_AUTO;
1164 }
1165}
1166
1167static void dtv_property_cache_submit(struct dvb_frontend *fe)
1168{
1169 const struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1170
1171 /* For legacy delivery systems we don't need the delivery_system to
1172 * be specified, but we populate the older structures from the cache
1173 * so we can call set_frontend on older drivers.
1174 */
1175 if(is_legacy_delivery_system(c->delivery_system)) {
1176
1177 dprintk("%s() legacy, modulation = %d\n", __func__, c->modulation);
1178 dtv_property_legacy_params_sync(fe);
1179
1180 } else {
1181 dprintk("%s() adv, modulation = %d\n", __func__, c->modulation);
1182
1183 /* For advanced delivery systems / modulation types ...
1184 * we seed the lecacy dvb_frontend_parameters structure
1185 * so that the sanity checking code later in the IOCTL processing
1186 * can validate our basic frequency ranges, symbolrates, modulation
1187 * etc.
1188 */
1189 dtv_property_adv_params_sync(fe);
1190 }
1191}
1192
1193static int dvb_frontend_ioctl_legacy(struct file *file,
1194 unsigned int cmd, void *parg);
1195static int dvb_frontend_ioctl_properties(struct file *file,
1196 unsigned int cmd, void *parg);
1197
1198static int dtv_property_process_get(struct dvb_frontend *fe,
1199 struct dtv_property *tvp,
1200 struct file *file)
1201{
1202 const struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1203 struct dvb_frontend_private *fepriv = fe->frontend_priv;
1204 struct dtv_frontend_properties cdetected;
1205 int r;
1206
1207 /*
1208 * If the driver implements a get_frontend function, then convert
1209 * detected parameters to S2API properties.
1210 */
1211 if (fe->ops.get_frontend) {
1212 cdetected = *c;
1213 dtv_property_cache_sync(fe, &cdetected, &fepriv->parameters_out);
1214 c = &cdetected;
1215 }
1216
1217 switch(tvp->cmd) {
1218 case DTV_FREQUENCY:
1219 tvp->u.data = c->frequency;
1220 break;
1221 case DTV_MODULATION:
1222 tvp->u.data = c->modulation;
1223 break;
1224 case DTV_BANDWIDTH_HZ:
1225 tvp->u.data = c->bandwidth_hz;
1226 break;
1227 case DTV_INVERSION:
1228 tvp->u.data = c->inversion;
1229 break;
1230 case DTV_SYMBOL_RATE:
1231 tvp->u.data = c->symbol_rate;
1232 break;
1233 case DTV_INNER_FEC:
1234 tvp->u.data = c->fec_inner;
1235 break;
1236 case DTV_PILOT:
1237 tvp->u.data = c->pilot;
1238 break;
1239 case DTV_ROLLOFF:
1240 tvp->u.data = c->rolloff;
1241 break;
1242 case DTV_DELIVERY_SYSTEM:
1243 tvp->u.data = c->delivery_system;
1244 break;
1245 case DTV_VOLTAGE:
1246 tvp->u.data = c->voltage;
1247 break;
1248 case DTV_TONE:
1249 tvp->u.data = c->sectone;
1250 break;
1251 case DTV_API_VERSION:
1252 tvp->u.data = (DVB_API_VERSION << 8) | DVB_API_VERSION_MINOR;
1253 break;
1254 case DTV_CODE_RATE_HP:
1255 tvp->u.data = c->code_rate_HP;
1256 break;
1257 case DTV_CODE_RATE_LP:
1258 tvp->u.data = c->code_rate_LP;
1259 break;
1260 case DTV_GUARD_INTERVAL:
1261 tvp->u.data = c->guard_interval;
1262 break;
1263 case DTV_TRANSMISSION_MODE:
1264 tvp->u.data = c->transmission_mode;
1265 break;
1266 case DTV_HIERARCHY:
1267 tvp->u.data = c->hierarchy;
1268 break;
1269
1270 /* ISDB-T Support here */
1271 case DTV_ISDBT_PARTIAL_RECEPTION:
1272 tvp->u.data = c->isdbt_partial_reception;
1273 break;
1274 case DTV_ISDBT_SOUND_BROADCASTING:
1275 tvp->u.data = c->isdbt_sb_mode;
1276 break;
1277 case DTV_ISDBT_SB_SUBCHANNEL_ID:
1278 tvp->u.data = c->isdbt_sb_subchannel;
1279 break;
1280 case DTV_ISDBT_SB_SEGMENT_IDX:
1281 tvp->u.data = c->isdbt_sb_segment_idx;
1282 break;
1283 case DTV_ISDBT_SB_SEGMENT_COUNT:
1284 tvp->u.data = c->isdbt_sb_segment_count;
1285 break;
1286 case DTV_ISDBT_LAYER_ENABLED:
1287 tvp->u.data = c->isdbt_layer_enabled;
1288 break;
1289 case DTV_ISDBT_LAYERA_FEC:
1290 tvp->u.data = c->layer[0].fec;
1291 break;
1292 case DTV_ISDBT_LAYERA_MODULATION:
1293 tvp->u.data = c->layer[0].modulation;
1294 break;
1295 case DTV_ISDBT_LAYERA_SEGMENT_COUNT:
1296 tvp->u.data = c->layer[0].segment_count;
1297 break;
1298 case DTV_ISDBT_LAYERA_TIME_INTERLEAVING:
1299 tvp->u.data = c->layer[0].interleaving;
1300 break;
1301 case DTV_ISDBT_LAYERB_FEC:
1302 tvp->u.data = c->layer[1].fec;
1303 break;
1304 case DTV_ISDBT_LAYERB_MODULATION:
1305 tvp->u.data = c->layer[1].modulation;
1306 break;
1307 case DTV_ISDBT_LAYERB_SEGMENT_COUNT:
1308 tvp->u.data = c->layer[1].segment_count;
1309 break;
1310 case DTV_ISDBT_LAYERB_TIME_INTERLEAVING:
1311 tvp->u.data = c->layer[1].interleaving;
1312 break;
1313 case DTV_ISDBT_LAYERC_FEC:
1314 tvp->u.data = c->layer[2].fec;
1315 break;
1316 case DTV_ISDBT_LAYERC_MODULATION:
1317 tvp->u.data = c->layer[2].modulation;
1318 break;
1319 case DTV_ISDBT_LAYERC_SEGMENT_COUNT:
1320 tvp->u.data = c->layer[2].segment_count;
1321 break;
1322 case DTV_ISDBT_LAYERC_TIME_INTERLEAVING:
1323 tvp->u.data = c->layer[2].interleaving;
1324 break;
1325 case DTV_ISDBS_TS_ID:
1326 tvp->u.data = c->isdbs_ts_id;
1327 break;
1328 case DTV_DVBT2_PLP_ID:
1329 tvp->u.data = c->dvbt2_plp_id;
1330 break;
1331 default:
1332 return -EINVAL;
1333 }
1334
1335 /* Allow the frontend to override outgoing properties */
1336 if (fe->ops.get_property) {
1337 r = fe->ops.get_property(fe, tvp);
1338 if (r < 0)
1339 return r;
1340 }
1341
1342 dtv_property_dump(tvp);
1343
1344 return 0;
1345}
1346
1347static int dtv_property_process_set(struct dvb_frontend *fe,
1348 struct dtv_property *tvp,
1349 struct file *file)
1350{
1351 int r = 0;
1352 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1353 struct dvb_frontend_private *fepriv = fe->frontend_priv;
1354 dtv_property_dump(tvp);
1355
1356 /* Allow the frontend to validate incoming properties */
1357 if (fe->ops.set_property) {
1358 r = fe->ops.set_property(fe, tvp);
1359 if (r < 0)
1360 return r;
1361 }
1362
1363 switch(tvp->cmd) {
1364 case DTV_CLEAR:
1365 /* Reset a cache of data specific to the frontend here. This does
1366 * not effect hardware.
1367 */
1368 dvb_frontend_clear_cache(fe);
1369 dprintk("%s() Flushing property cache\n", __func__);
1370 break;
1371 case DTV_TUNE:
1372 /* interpret the cache of data, build either a traditional frontend
1373 * tunerequest so we can pass validation in the FE_SET_FRONTEND
1374 * ioctl.
1375 */
1376 c->state = tvp->cmd;
1377 dprintk("%s() Finalised property cache\n", __func__);
1378 dtv_property_cache_submit(fe);
1379
1380 r = dvb_frontend_ioctl_legacy(file, FE_SET_FRONTEND,
1381 &fepriv->parameters_in);
1382 break;
1383 case DTV_FREQUENCY:
1384 c->frequency = tvp->u.data;
1385 break;
1386 case DTV_MODULATION:
1387 c->modulation = tvp->u.data;
1388 break;
1389 case DTV_BANDWIDTH_HZ:
1390 c->bandwidth_hz = tvp->u.data;
1391 break;
1392 case DTV_INVERSION:
1393 c->inversion = tvp->u.data;
1394 break;
1395 case DTV_SYMBOL_RATE:
1396 c->symbol_rate = tvp->u.data;
1397 break;
1398 case DTV_INNER_FEC:
1399 c->fec_inner = tvp->u.data;
1400 break;
1401 case DTV_PILOT:
1402 c->pilot = tvp->u.data;
1403 break;
1404 case DTV_ROLLOFF:
1405 c->rolloff = tvp->u.data;
1406 break;
1407 case DTV_DELIVERY_SYSTEM:
1408 c->delivery_system = tvp->u.data;
1409 break;
1410 case DTV_VOLTAGE:
1411 c->voltage = tvp->u.data;
1412 r = dvb_frontend_ioctl_legacy(file, FE_SET_VOLTAGE,
1413 (void *)c->voltage);
1414 break;
1415 case DTV_TONE:
1416 c->sectone = tvp->u.data;
1417 r = dvb_frontend_ioctl_legacy(file, FE_SET_TONE,
1418 (void *)c->sectone);
1419 break;
1420 case DTV_CODE_RATE_HP:
1421 c->code_rate_HP = tvp->u.data;
1422 break;
1423 case DTV_CODE_RATE_LP:
1424 c->code_rate_LP = tvp->u.data;
1425 break;
1426 case DTV_GUARD_INTERVAL:
1427 c->guard_interval = tvp->u.data;
1428 break;
1429 case DTV_TRANSMISSION_MODE:
1430 c->transmission_mode = tvp->u.data;
1431 break;
1432 case DTV_HIERARCHY:
1433 c->hierarchy = tvp->u.data;
1434 break;
1435
1436 /* ISDB-T Support here */
1437 case DTV_ISDBT_PARTIAL_RECEPTION:
1438 c->isdbt_partial_reception = tvp->u.data;
1439 break;
1440 case DTV_ISDBT_SOUND_BROADCASTING:
1441 c->isdbt_sb_mode = tvp->u.data;
1442 break;
1443 case DTV_ISDBT_SB_SUBCHANNEL_ID:
1444 c->isdbt_sb_subchannel = tvp->u.data;
1445 break;
1446 case DTV_ISDBT_SB_SEGMENT_IDX:
1447 c->isdbt_sb_segment_idx = tvp->u.data;
1448 break;
1449 case DTV_ISDBT_SB_SEGMENT_COUNT:
1450 c->isdbt_sb_segment_count = tvp->u.data;
1451 break;
1452 case DTV_ISDBT_LAYER_ENABLED:
1453 c->isdbt_layer_enabled = tvp->u.data;
1454 break;
1455 case DTV_ISDBT_LAYERA_FEC:
1456 c->layer[0].fec = tvp->u.data;
1457 break;
1458 case DTV_ISDBT_LAYERA_MODULATION:
1459 c->layer[0].modulation = tvp->u.data;
1460 break;
1461 case DTV_ISDBT_LAYERA_SEGMENT_COUNT:
1462 c->layer[0].segment_count = tvp->u.data;
1463 break;
1464 case DTV_ISDBT_LAYERA_TIME_INTERLEAVING:
1465 c->layer[0].interleaving = tvp->u.data;
1466 break;
1467 case DTV_ISDBT_LAYERB_FEC:
1468 c->layer[1].fec = tvp->u.data;
1469 break;
1470 case DTV_ISDBT_LAYERB_MODULATION:
1471 c->layer[1].modulation = tvp->u.data;
1472 break;
1473 case DTV_ISDBT_LAYERB_SEGMENT_COUNT:
1474 c->layer[1].segment_count = tvp->u.data;
1475 break;
1476 case DTV_ISDBT_LAYERB_TIME_INTERLEAVING:
1477 c->layer[1].interleaving = tvp->u.data;
1478 break;
1479 case DTV_ISDBT_LAYERC_FEC:
1480 c->layer[2].fec = tvp->u.data;
1481 break;
1482 case DTV_ISDBT_LAYERC_MODULATION:
1483 c->layer[2].modulation = tvp->u.data;
1484 break;
1485 case DTV_ISDBT_LAYERC_SEGMENT_COUNT:
1486 c->layer[2].segment_count = tvp->u.data;
1487 break;
1488 case DTV_ISDBT_LAYERC_TIME_INTERLEAVING:
1489 c->layer[2].interleaving = tvp->u.data;
1490 break;
1491 case DTV_ISDBS_TS_ID:
1492 c->isdbs_ts_id = tvp->u.data;
1493 break;
1494 case DTV_DVBT2_PLP_ID:
1495 c->dvbt2_plp_id = tvp->u.data;
1496 break;
1497 default:
1498 return -EINVAL;
1499 }
1500
1501 return r;
1502}
1503
1504static int dvb_frontend_ioctl(struct file *file,
1505 unsigned int cmd, void *parg)
1506{
1507 struct dvb_device *dvbdev = file->private_data;
1508 struct dvb_frontend *fe = dvbdev->priv;
1509 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1510 struct dvb_frontend_private *fepriv = fe->frontend_priv;
1511 int err = -EOPNOTSUPP;
1512
1513 dprintk("%s (%d)\n", __func__, _IOC_NR(cmd));
1514
1515 if (fepriv->exit != DVB_FE_NO_EXIT)
1516 return -ENODEV;
1517
1518 if ((file->f_flags & O_ACCMODE) == O_RDONLY &&
1519 (_IOC_DIR(cmd) != _IOC_READ || cmd == FE_GET_EVENT ||
1520 cmd == FE_DISEQC_RECV_SLAVE_REPLY))
1521 return -EPERM;
1522
1523 if (down_interruptible (&fepriv->sem))
1524 return -ERESTARTSYS;
1525
1526 if ((cmd == FE_SET_PROPERTY) || (cmd == FE_GET_PROPERTY))
1527 err = dvb_frontend_ioctl_properties(file, cmd, parg);
1528 else {
1529 c->state = DTV_UNDEFINED;
1530 err = dvb_frontend_ioctl_legacy(file, cmd, parg);
1531 }
1532
1533 up(&fepriv->sem);
1534 return err;
1535}
1536
1537static int dvb_frontend_ioctl_properties(struct file *file,
1538 unsigned int cmd, void *parg)
1539{
1540 struct dvb_device *dvbdev = file->private_data;
1541 struct dvb_frontend *fe = dvbdev->priv;
1542 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1543 int err = 0;
1544
1545 struct dtv_properties *tvps = NULL;
1546 struct dtv_property *tvp = NULL;
1547 int i;
1548
1549 dprintk("%s\n", __func__);
1550
1551 if(cmd == FE_SET_PROPERTY) {
1552 tvps = (struct dtv_properties __user *)parg;
1553
1554 dprintk("%s() properties.num = %d\n", __func__, tvps->num);
1555 dprintk("%s() properties.props = %p\n", __func__, tvps->props);
1556
1557 /* Put an arbitrary limit on the number of messages that can
1558 * be sent at once */
1559 if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS))
1560 return -EINVAL;
1561
1562 tvp = kmalloc(tvps->num * sizeof(struct dtv_property), GFP_KERNEL);
1563 if (!tvp) {
1564 err = -ENOMEM;
1565 goto out;
1566 }
1567
1568 if (copy_from_user(tvp, tvps->props, tvps->num * sizeof(struct dtv_property))) {
1569 err = -EFAULT;
1570 goto out;
1571 }
1572
1573 for (i = 0; i < tvps->num; i++) {
1574 err = dtv_property_process_set(fe, tvp + i, file);
1575 if (err < 0)
1576 goto out;
1577 (tvp + i)->result = err;
1578 }
1579
1580 if (c->state == DTV_TUNE)
1581 dprintk("%s() Property cache is full, tuning\n", __func__);
1582
1583 } else
1584 if(cmd == FE_GET_PROPERTY) {
1585
1586 tvps = (struct dtv_properties __user *)parg;
1587
1588 dprintk("%s() properties.num = %d\n", __func__, tvps->num);
1589 dprintk("%s() properties.props = %p\n", __func__, tvps->props);
1590
1591 /* Put an arbitrary limit on the number of messages that can
1592 * be sent at once */
1593 if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS))
1594 return -EINVAL;
1595
1596 tvp = kmalloc(tvps->num * sizeof(struct dtv_property), GFP_KERNEL);
1597 if (!tvp) {
1598 err = -ENOMEM;
1599 goto out;
1600 }
1601
1602 if (copy_from_user(tvp, tvps->props, tvps->num * sizeof(struct dtv_property))) {
1603 err = -EFAULT;
1604 goto out;
1605 }
1606
1607 for (i = 0; i < tvps->num; i++) {
1608 err = dtv_property_process_get(fe, tvp + i, file);
1609 if (err < 0)
1610 goto out;
1611 (tvp + i)->result = err;
1612 }
1613
1614 if (copy_to_user(tvps->props, tvp, tvps->num * sizeof(struct dtv_property))) {
1615 err = -EFAULT;
1616 goto out;
1617 }
1618
1619 } else
1620 err = -EOPNOTSUPP;
1621
1622out:
1623 kfree(tvp);
1624 return err;
1625}
1626
1627static int dvb_frontend_ioctl_legacy(struct file *file,
1628 unsigned int cmd, void *parg)
1629{
1630 struct dvb_device *dvbdev = file->private_data;
1631 struct dvb_frontend *fe = dvbdev->priv;
1632 struct dvb_frontend_private *fepriv = fe->frontend_priv;
1633 int cb_err, err = -EOPNOTSUPP;
1634
1635 if (fe->dvb->fe_ioctl_override) {
1636 cb_err = fe->dvb->fe_ioctl_override(fe, cmd, parg,
1637 DVB_FE_IOCTL_PRE);
1638 if (cb_err < 0)
1639 return cb_err;
1640 if (cb_err > 0)
1641 return 0;
1642 /* fe_ioctl_override returning 0 allows
1643 * dvb-core to continue handling the ioctl */
1644 }
1645
1646 switch (cmd) {
1647 case FE_GET_INFO: {
1648 struct dvb_frontend_info* info = parg;
1649 memcpy(info, &fe->ops.info, sizeof(struct dvb_frontend_info));
1650 dvb_frontend_get_frequency_limits(fe, &info->frequency_min, &info->frequency_max);
1651
1652 /* Force the CAN_INVERSION_AUTO bit on. If the frontend doesn't
1653 * do it, it is done for it. */
1654 info->caps |= FE_CAN_INVERSION_AUTO;
1655 err = 0;
1656 break;
1657 }
1658
1659 case FE_READ_STATUS: {
1660 fe_status_t* status = parg;
1661
1662 /* if retune was requested but hasn't occurred yet, prevent
1663 * that user get signal state from previous tuning */
1664 if (fepriv->state == FESTATE_RETUNE ||
1665 fepriv->state == FESTATE_ERROR) {
1666 err=0;
1667 *status = 0;
1668 break;
1669 }
1670
1671 if (fe->ops.read_status)
1672 err = fe->ops.read_status(fe, status);
1673 break;
1674 }
1675 case FE_READ_BER:
1676 if (fe->ops.read_ber)
1677 err = fe->ops.read_ber(fe, (__u32*) parg);
1678 break;
1679
1680 case FE_READ_SIGNAL_STRENGTH:
1681 if (fe->ops.read_signal_strength)
1682 err = fe->ops.read_signal_strength(fe, (__u16*) parg);
1683 break;
1684
1685 case FE_READ_SNR:
1686 if (fe->ops.read_snr)
1687 err = fe->ops.read_snr(fe, (__u16*) parg);
1688 break;
1689
1690 case FE_READ_UNCORRECTED_BLOCKS:
1691 if (fe->ops.read_ucblocks)
1692 err = fe->ops.read_ucblocks(fe, (__u32*) parg);
1693 break;
1694
1695
1696 case FE_DISEQC_RESET_OVERLOAD:
1697 if (fe->ops.diseqc_reset_overload) {
1698 err = fe->ops.diseqc_reset_overload(fe);
1699 fepriv->state = FESTATE_DISEQC;
1700 fepriv->status = 0;
1701 }
1702 break;
1703
1704 case FE_DISEQC_SEND_MASTER_CMD:
1705 if (fe->ops.diseqc_send_master_cmd) {
1706 err = fe->ops.diseqc_send_master_cmd(fe, (struct dvb_diseqc_master_cmd*) parg);
1707 fepriv->state = FESTATE_DISEQC;
1708 fepriv->status = 0;
1709 }
1710 break;
1711
1712 case FE_DISEQC_SEND_BURST:
1713 if (fe->ops.diseqc_send_burst) {
1714 err = fe->ops.diseqc_send_burst(fe, (fe_sec_mini_cmd_t) parg);
1715 fepriv->state = FESTATE_DISEQC;
1716 fepriv->status = 0;
1717 }
1718 break;
1719
1720 case FE_SET_TONE:
1721 if (fe->ops.set_tone) {
1722 err = fe->ops.set_tone(fe, (fe_sec_tone_mode_t) parg);
1723 fepriv->tone = (fe_sec_tone_mode_t) parg;
1724 fepriv->state = FESTATE_DISEQC;
1725 fepriv->status = 0;
1726 }
1727 break;
1728
1729 case FE_SET_VOLTAGE:
1730 if (fe->ops.set_voltage) {
1731 err = fe->ops.set_voltage(fe, (fe_sec_voltage_t) parg);
1732 fepriv->voltage = (fe_sec_voltage_t) parg;
1733 fepriv->state = FESTATE_DISEQC;
1734 fepriv->status = 0;
1735 }
1736 break;
1737
1738 case FE_DISHNETWORK_SEND_LEGACY_CMD:
1739 if (fe->ops.dishnetwork_send_legacy_command) {
1740 err = fe->ops.dishnetwork_send_legacy_command(fe, (unsigned long) parg);
1741 fepriv->state = FESTATE_DISEQC;
1742 fepriv->status = 0;
1743 } else if (fe->ops.set_voltage) {
1744 /*
1745 * NOTE: This is a fallback condition. Some frontends
1746 * (stv0299 for instance) take longer than 8msec to
1747 * respond to a set_voltage command. Those switches
1748 * need custom routines to switch properly. For all
1749 * other frontends, the following should work ok.
1750 * Dish network legacy switches (as used by Dish500)
1751 * are controlled by sending 9-bit command words
1752 * spaced 8msec apart.
1753 * the actual command word is switch/port dependent
1754 * so it is up to the userspace application to send
1755 * the right command.
1756 * The command must always start with a '0' after
1757 * initialization, so parg is 8 bits and does not
1758 * include the initialization or start bit
1759 */
1760 unsigned long swcmd = ((unsigned long) parg) << 1;
1761 struct timeval nexttime;
1762 struct timeval tv[10];
1763 int i;
1764 u8 last = 1;
1765 if (dvb_frontend_debug)
1766 printk("%s switch command: 0x%04lx\n", __func__, swcmd);
1767 do_gettimeofday(&nexttime);
1768 if (dvb_frontend_debug)
1769 memcpy(&tv[0], &nexttime, sizeof(struct timeval));
1770 /* before sending a command, initialize by sending
1771 * a 32ms 18V to the switch
1772 */
1773 fe->ops.set_voltage(fe, SEC_VOLTAGE_18);
1774 dvb_frontend_sleep_until(&nexttime, 32000);
1775
1776 for (i = 0; i < 9; i++) {
1777 if (dvb_frontend_debug)
1778 do_gettimeofday(&tv[i + 1]);
1779 if ((swcmd & 0x01) != last) {
1780 /* set voltage to (last ? 13V : 18V) */
1781 fe->ops.set_voltage(fe, (last) ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18);
1782 last = (last) ? 0 : 1;
1783 }
1784 swcmd = swcmd >> 1;
1785 if (i != 8)
1786 dvb_frontend_sleep_until(&nexttime, 8000);
1787 }
1788 if (dvb_frontend_debug) {
1789 printk("%s(%d): switch delay (should be 32k followed by all 8k\n",
1790 __func__, fe->dvb->num);
1791 for (i = 1; i < 10; i++)
1792 printk("%d: %d\n", i, timeval_usec_diff(tv[i-1] , tv[i]));
1793 }
1794 err = 0;
1795 fepriv->state = FESTATE_DISEQC;
1796 fepriv->status = 0;
1797 }
1798 break;
1799
1800 case FE_DISEQC_RECV_SLAVE_REPLY:
1801 if (fe->ops.diseqc_recv_slave_reply)
1802 err = fe->ops.diseqc_recv_slave_reply(fe, (struct dvb_diseqc_slave_reply*) parg);
1803 break;
1804
1805 case FE_ENABLE_HIGH_LNB_VOLTAGE:
1806 if (fe->ops.enable_high_lnb_voltage)
1807 err = fe->ops.enable_high_lnb_voltage(fe, (long) parg);
1808 break;
1809
1810 case FE_SET_FRONTEND: {
1811 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1812 struct dvb_frontend_tune_settings fetunesettings;
1813
1814 if (c->state == DTV_TUNE) {
1815 if (dvb_frontend_check_parameters(fe, &fepriv->parameters_in) < 0) {
1816 err = -EINVAL;
1817 break;
1818 }
1819 } else {
1820 if (dvb_frontend_check_parameters(fe, parg) < 0) {
1821 err = -EINVAL;
1822 break;
1823 }
1824
1825 memcpy (&fepriv->parameters_in, parg,
1826 sizeof (struct dvb_frontend_parameters));
1827 dtv_property_cache_sync(fe, c, &fepriv->parameters_in);
1828 }
1829
1830 memset(&fetunesettings, 0, sizeof(struct dvb_frontend_tune_settings));
1831 memcpy(&fetunesettings.parameters, parg,
1832 sizeof (struct dvb_frontend_parameters));
1833
1834 /* force auto frequency inversion if requested */
1835 if (dvb_force_auto_inversion) {
1836 fepriv->parameters_in.inversion = INVERSION_AUTO;
1837 fetunesettings.parameters.inversion = INVERSION_AUTO;
1838 }
1839 if (fe->ops.info.type == FE_OFDM) {
1840 /* without hierarchical coding code_rate_LP is irrelevant,
1841 * so we tolerate the otherwise invalid FEC_NONE setting */
1842 if (fepriv->parameters_in.u.ofdm.hierarchy_information == HIERARCHY_NONE &&
1843 fepriv->parameters_in.u.ofdm.code_rate_LP == FEC_NONE)
1844 fepriv->parameters_in.u.ofdm.code_rate_LP = FEC_AUTO;
1845 }
1846
1847 /* get frontend-specific tuning settings */
1848 if (fe->ops.get_tune_settings && (fe->ops.get_tune_settings(fe, &fetunesettings) == 0)) {
1849 fepriv->min_delay = (fetunesettings.min_delay_ms * HZ) / 1000;
1850 fepriv->max_drift = fetunesettings.max_drift;
1851 fepriv->step_size = fetunesettings.step_size;
1852 } else {
1853 /* default values */
1854 switch(fe->ops.info.type) {
1855 case FE_QPSK:
1856 fepriv->min_delay = HZ/20;
1857 fepriv->step_size = fepriv->parameters_in.u.qpsk.symbol_rate / 16000;
1858 fepriv->max_drift = fepriv->parameters_in.u.qpsk.symbol_rate / 2000;
1859 break;
1860
1861 case FE_QAM:
1862 fepriv->min_delay = HZ/20;
1863 fepriv->step_size = 0; /* no zigzag */
1864 fepriv->max_drift = 0;
1865 break;
1866
1867 case FE_OFDM:
1868 fepriv->min_delay = HZ/20;
1869 fepriv->step_size = fe->ops.info.frequency_stepsize * 2;
1870 fepriv->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
1871 break;
1872 case FE_ATSC:
1873 fepriv->min_delay = HZ/20;
1874 fepriv->step_size = 0;
1875 fepriv->max_drift = 0;
1876 break;
1877 }
1878 }
1879 if (dvb_override_tune_delay > 0)
1880 fepriv->min_delay = (dvb_override_tune_delay * HZ) / 1000;
1881
1882 fepriv->state = FESTATE_RETUNE;
1883
1884 /* Request the search algorithm to search */
1885 fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN;
1886
1887 dvb_frontend_wakeup(fe);
1888 dvb_frontend_add_event(fe, 0);
1889 fepriv->status = 0;
1890 err = 0;
1891 break;
1892 }
1893
1894 case FE_GET_EVENT:
1895 err = dvb_frontend_get_event (fe, parg, file->f_flags);
1896 break;
1897
1898 case FE_GET_FRONTEND:
1899 if (fe->ops.get_frontend) {
1900 err = fe->ops.get_frontend(fe, &fepriv->parameters_out);
1901 memcpy(parg, &fepriv->parameters_out, sizeof(struct dvb_frontend_parameters));
1902 }
1903 break;
1904
1905 case FE_SET_FRONTEND_TUNE_MODE:
1906 fepriv->tune_mode_flags = (unsigned long) parg;
1907 err = 0;
1908 break;
1909 };
1910
1911 if (fe->dvb->fe_ioctl_override) {
1912 cb_err = fe->dvb->fe_ioctl_override(fe, cmd, parg,
1913 DVB_FE_IOCTL_POST);
1914 if (cb_err < 0)
1915 return cb_err;
1916 }
1917
1918 return err;
1919}
1920
1921
1922static unsigned int dvb_frontend_poll(struct file *file, struct poll_table_struct *wait)
1923{
1924 struct dvb_device *dvbdev = file->private_data;
1925 struct dvb_frontend *fe = dvbdev->priv;
1926 struct dvb_frontend_private *fepriv = fe->frontend_priv;
1927
1928 dprintk ("%s\n", __func__);
1929
1930 poll_wait (file, &fepriv->events.wait_queue, wait);
1931
1932 if (fepriv->events.eventw != fepriv->events.eventr)
1933 return (POLLIN | POLLRDNORM | POLLPRI);
1934
1935 return 0;
1936}
1937
1938static int dvb_frontend_open(struct inode *inode, struct file *file)
1939{
1940 struct dvb_device *dvbdev = file->private_data;
1941 struct dvb_frontend *fe = dvbdev->priv;
1942 struct dvb_frontend_private *fepriv = fe->frontend_priv;
1943 struct dvb_adapter *adapter = fe->dvb;
1944 int ret;
1945
1946 dprintk ("%s\n", __func__);
1947 if (fepriv->exit == DVB_FE_DEVICE_REMOVED)
1948 return -ENODEV;
1949
1950 if (adapter->mfe_shared) {
1951 mutex_lock (&adapter->mfe_lock);
1952
1953 if (adapter->mfe_dvbdev == NULL)
1954 adapter->mfe_dvbdev = dvbdev;
1955
1956 else if (adapter->mfe_dvbdev != dvbdev) {
1957 struct dvb_device
1958 *mfedev = adapter->mfe_dvbdev;
1959 struct dvb_frontend
1960 *mfe = mfedev->priv;
1961 struct dvb_frontend_private
1962 *mfepriv = mfe->frontend_priv;
1963 int mferetry = (dvb_mfe_wait_time << 1);
1964
1965 mutex_unlock (&adapter->mfe_lock);
1966 while (mferetry-- && (mfedev->users != -1 ||
1967 mfepriv->thread != NULL)) {
1968 if(msleep_interruptible(500)) {
1969 if(signal_pending(current))
1970 return -EINTR;
1971 }
1972 }
1973
1974 mutex_lock (&adapter->mfe_lock);
1975 if(adapter->mfe_dvbdev != dvbdev) {
1976 mfedev = adapter->mfe_dvbdev;
1977 mfe = mfedev->priv;
1978 mfepriv = mfe->frontend_priv;
1979 if (mfedev->users != -1 ||
1980 mfepriv->thread != NULL) {
1981 mutex_unlock (&adapter->mfe_lock);
1982 return -EBUSY;
1983 }
1984 adapter->mfe_dvbdev = dvbdev;
1985 }
1986 }
1987 }
1988
1989 if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl) {
1990 if ((ret = fe->ops.ts_bus_ctrl(fe, 1)) < 0)
1991 goto err0;
1992
1993 /* If we took control of the bus, we need to force
1994 reinitialization. This is because many ts_bus_ctrl()
1995 functions strobe the RESET pin on the demod, and if the
1996 frontend thread already exists then the dvb_init() routine
1997 won't get called (which is what usually does initial
1998 register configuration). */
1999 fepriv->reinitialise = 1;
2000 }
2001
2002 if ((ret = dvb_generic_open (inode, file)) < 0)
2003 goto err1;
2004
2005 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
2006 /* normal tune mode when opened R/W */
2007 fepriv->tune_mode_flags &= ~FE_TUNE_MODE_ONESHOT;
2008 fepriv->tone = -1;
2009 fepriv->voltage = -1;
2010
2011 ret = dvb_frontend_start (fe);
2012 if (ret)
2013 goto err2;
2014
2015 /* empty event queue */
2016 fepriv->events.eventr = fepriv->events.eventw = 0;
2017 }
2018
2019 if (adapter->mfe_shared)
2020 mutex_unlock (&adapter->mfe_lock);
2021 return ret;
2022
2023err2:
2024 dvb_generic_release(inode, file);
2025err1:
2026 if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl)
2027 fe->ops.ts_bus_ctrl(fe, 0);
2028err0:
2029 if (adapter->mfe_shared)
2030 mutex_unlock (&adapter->mfe_lock);
2031 return ret;
2032}
2033
2034static int dvb_frontend_release(struct inode *inode, struct file *file)
2035{
2036 struct dvb_device *dvbdev = file->private_data;
2037 struct dvb_frontend *fe = dvbdev->priv;
2038 struct dvb_frontend_private *fepriv = fe->frontend_priv;
2039 int ret;
2040
2041 dprintk ("%s\n", __func__);
2042
2043 if ((file->f_flags & O_ACCMODE) != O_RDONLY)
2044 fepriv->release_jiffies = jiffies;
2045
2046 ret = dvb_generic_release (inode, file);
2047
2048 if (dvbdev->users == -1) {
2049 if (fepriv->exit != DVB_FE_NO_EXIT) {
2050 fops_put(file->f_op);
2051 file->f_op = NULL;
2052 wake_up(&dvbdev->wait_queue);
2053 }
2054 if (fe->ops.ts_bus_ctrl)
2055 fe->ops.ts_bus_ctrl(fe, 0);
2056 }
2057
2058 return ret;
2059}
2060
2061static const struct file_operations dvb_frontend_fops = {
2062 .owner = THIS_MODULE,
2063 .unlocked_ioctl = dvb_generic_ioctl,
2064 .poll = dvb_frontend_poll,
2065 .open = dvb_frontend_open,
2066 .release = dvb_frontend_release,
2067 .llseek = noop_llseek,
2068};
2069
2070int dvb_register_frontend(struct dvb_adapter* dvb,
2071 struct dvb_frontend* fe)
2072{
2073 struct dvb_frontend_private *fepriv;
2074 static const struct dvb_device dvbdev_template = {
2075 .users = ~0,
2076 .writers = 1,
2077 .readers = (~0)-1,
2078 .fops = &dvb_frontend_fops,
2079 .kernel_ioctl = dvb_frontend_ioctl
2080 };
2081
2082 dprintk ("%s\n", __func__);
2083
2084 if (mutex_lock_interruptible(&frontend_mutex))
2085 return -ERESTARTSYS;
2086
2087 fe->frontend_priv = kzalloc(sizeof(struct dvb_frontend_private), GFP_KERNEL);
2088 if (fe->frontend_priv == NULL) {
2089 mutex_unlock(&frontend_mutex);
2090 return -ENOMEM;
2091 }
2092 fepriv = fe->frontend_priv;
2093
2094 sema_init(&fepriv->sem, 1);
2095 init_waitqueue_head (&fepriv->wait_queue);
2096 init_waitqueue_head (&fepriv->events.wait_queue);
2097 mutex_init(&fepriv->events.mtx);
2098 fe->dvb = dvb;
2099 fepriv->inversion = INVERSION_OFF;
2100
2101 printk ("DVB: registering adapter %i frontend %i (%s)...\n",
2102 fe->dvb->num,
2103 fe->id,
2104 fe->ops.info.name);
2105
2106 dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template,
2107 fe, DVB_DEVICE_FRONTEND);
2108
2109 mutex_unlock(&frontend_mutex);
2110 return 0;
2111}
2112EXPORT_SYMBOL(dvb_register_frontend);
2113
2114int dvb_unregister_frontend(struct dvb_frontend* fe)
2115{
2116 struct dvb_frontend_private *fepriv = fe->frontend_priv;
2117 dprintk ("%s\n", __func__);
2118
2119 mutex_lock(&frontend_mutex);
2120 dvb_frontend_stop (fe);
2121 mutex_unlock(&frontend_mutex);
2122
2123 if (fepriv->dvbdev->users < -1)
2124 wait_event(fepriv->dvbdev->wait_queue,
2125 fepriv->dvbdev->users==-1);
2126
2127 mutex_lock(&frontend_mutex);
2128 dvb_unregister_device (fepriv->dvbdev);
2129
2130 /* fe is invalid now */
2131 kfree(fepriv);
2132 mutex_unlock(&frontend_mutex);
2133 return 0;
2134}
2135EXPORT_SYMBOL(dvb_unregister_frontend);
2136
2137#ifdef CONFIG_MEDIA_ATTACH
2138void dvb_frontend_detach(struct dvb_frontend* fe)
2139{
2140 void *ptr;
2141
2142 if (fe->ops.release_sec) {
2143 fe->ops.release_sec(fe);
2144 symbol_put_addr(fe->ops.release_sec);
2145 }
2146 if (fe->ops.tuner_ops.release) {
2147 fe->ops.tuner_ops.release(fe);
2148 symbol_put_addr(fe->ops.tuner_ops.release);
2149 }
2150 if (fe->ops.analog_ops.release) {
2151 fe->ops.analog_ops.release(fe);
2152 symbol_put_addr(fe->ops.analog_ops.release);
2153 }
2154 ptr = (void*)fe->ops.release;
2155 if (ptr) {
2156 fe->ops.release(fe);
2157 symbol_put_addr(ptr);
2158 }
2159}
2160#else
2161void dvb_frontend_detach(struct dvb_frontend* fe)
2162{
2163 if (fe->ops.release_sec)
2164 fe->ops.release_sec(fe);
2165 if (fe->ops.tuner_ops.release)
2166 fe->ops.tuner_ops.release(fe);
2167 if (fe->ops.analog_ops.release)
2168 fe->ops.analog_ops.release(fe);
2169 if (fe->ops.release)
2170 fe->ops.release(fe);
2171}
2172#endif
2173EXPORT_SYMBOL(dvb_frontend_detach);
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
new file mode 100644
index 00000000000..5590eb6eb40
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -0,0 +1,392 @@
1/*
2 * dvb_frontend.h
3 *
4 * Copyright (C) 2001 convergence integrated media GmbH
5 * Copyright (C) 2004 convergence GmbH
6 *
7 * Written by Ralph Metzler
8 * Overhauled by Holger Waechtler
9 * Kernel I2C stuff by Michael Hunold <hunold@convergence.de>
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation; either version 2.1
14 * of the License, or (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21
22 * You should have received a copy of the GNU Lesser General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 *
26 */
27
28#ifndef _DVB_FRONTEND_H_
29#define _DVB_FRONTEND_H_
30
31#include <linux/types.h>
32#include <linux/sched.h>
33#include <linux/ioctl.h>
34#include <linux/i2c.h>
35#include <linux/module.h>
36#include <linux/errno.h>
37#include <linux/delay.h>
38#include <linux/mutex.h>
39#include <linux/slab.h>
40
41#include <linux/dvb/frontend.h>
42
43#include "dvbdev.h"
44
45struct dvb_frontend_tune_settings {
46 int min_delay_ms;
47 int step_size;
48 int max_drift;
49 struct dvb_frontend_parameters parameters;
50};
51
52struct dvb_frontend;
53
54struct dvb_tuner_info {
55 char name[128];
56
57 u32 frequency_min;
58 u32 frequency_max;
59 u32 frequency_step;
60
61 u32 bandwidth_min;
62 u32 bandwidth_max;
63 u32 bandwidth_step;
64};
65
66struct analog_parameters {
67 unsigned int frequency;
68 unsigned int mode;
69 unsigned int audmode;
70 u64 std;
71};
72
73enum dvbfe_modcod {
74 DVBFE_MODCOD_DUMMY_PLFRAME = 0,
75 DVBFE_MODCOD_QPSK_1_4,
76 DVBFE_MODCOD_QPSK_1_3,
77 DVBFE_MODCOD_QPSK_2_5,
78 DVBFE_MODCOD_QPSK_1_2,
79 DVBFE_MODCOD_QPSK_3_5,
80 DVBFE_MODCOD_QPSK_2_3,
81 DVBFE_MODCOD_QPSK_3_4,
82 DVBFE_MODCOD_QPSK_4_5,
83 DVBFE_MODCOD_QPSK_5_6,
84 DVBFE_MODCOD_QPSK_8_9,
85 DVBFE_MODCOD_QPSK_9_10,
86 DVBFE_MODCOD_8PSK_3_5,
87 DVBFE_MODCOD_8PSK_2_3,
88 DVBFE_MODCOD_8PSK_3_4,
89 DVBFE_MODCOD_8PSK_5_6,
90 DVBFE_MODCOD_8PSK_8_9,
91 DVBFE_MODCOD_8PSK_9_10,
92 DVBFE_MODCOD_16APSK_2_3,
93 DVBFE_MODCOD_16APSK_3_4,
94 DVBFE_MODCOD_16APSK_4_5,
95 DVBFE_MODCOD_16APSK_5_6,
96 DVBFE_MODCOD_16APSK_8_9,
97 DVBFE_MODCOD_16APSK_9_10,
98 DVBFE_MODCOD_32APSK_3_4,
99 DVBFE_MODCOD_32APSK_4_5,
100 DVBFE_MODCOD_32APSK_5_6,
101 DVBFE_MODCOD_32APSK_8_9,
102 DVBFE_MODCOD_32APSK_9_10,
103 DVBFE_MODCOD_RESERVED_1,
104 DVBFE_MODCOD_BPSK_1_3,
105 DVBFE_MODCOD_BPSK_1_4,
106 DVBFE_MODCOD_RESERVED_2
107};
108
109enum tuner_param {
110 DVBFE_TUNER_FREQUENCY = (1 << 0),
111 DVBFE_TUNER_TUNERSTEP = (1 << 1),
112 DVBFE_TUNER_IFFREQ = (1 << 2),
113 DVBFE_TUNER_BANDWIDTH = (1 << 3),
114 DVBFE_TUNER_REFCLOCK = (1 << 4),
115 DVBFE_TUNER_IQSENSE = (1 << 5),
116 DVBFE_TUNER_DUMMY = (1 << 31)
117};
118
119/*
120 * ALGO_HW: (Hardware Algorithm)
121 * ----------------------------------------------------------------
122 * Devices that support this algorithm do everything in hardware
123 * and no software support is needed to handle them.
124 * Requesting these devices to LOCK is the only thing required,
125 * device is supposed to do everything in the hardware.
126 *
127 * ALGO_SW: (Software Algorithm)
128 * ----------------------------------------------------------------
129 * These are dumb devices, that require software to do everything
130 *
131 * ALGO_CUSTOM: (Customizable Agorithm)
132 * ----------------------------------------------------------------
133 * Devices having this algorithm can be customized to have specific
134 * algorithms in the frontend driver, rather than simply doing a
135 * software zig-zag. In this case the zigzag maybe hardware assisted
136 * or it maybe completely done in hardware. In all cases, usage of
137 * this algorithm, in conjunction with the search and track
138 * callbacks, utilizes the driver specific algorithm.
139 *
140 * ALGO_RECOVERY: (Recovery Algorithm)
141 * ----------------------------------------------------------------
142 * These devices have AUTO recovery capabilities from LOCK failure
143 */
144enum dvbfe_algo {
145 DVBFE_ALGO_HW = (1 << 0),
146 DVBFE_ALGO_SW = (1 << 1),
147 DVBFE_ALGO_CUSTOM = (1 << 2),
148 DVBFE_ALGO_RECOVERY = (1 << 31)
149};
150
151struct tuner_state {
152 u32 frequency;
153 u32 tunerstep;
154 u32 ifreq;
155 u32 bandwidth;
156 u32 iqsense;
157 u32 refclock;
158};
159
160/*
161 * search callback possible return status
162 *
163 * DVBFE_ALGO_SEARCH_SUCCESS
164 * The frontend search algorithm completed and returned successfully
165 *
166 * DVBFE_ALGO_SEARCH_ASLEEP
167 * The frontend search algorithm is sleeping
168 *
169 * DVBFE_ALGO_SEARCH_FAILED
170 * The frontend search for a signal failed
171 *
172 * DVBFE_ALGO_SEARCH_INVALID
173 * The frontend search algorith was probably supplied with invalid
174 * parameters and the search is an invalid one
175 *
176 * DVBFE_ALGO_SEARCH_ERROR
177 * The frontend search algorithm failed due to some error
178 *
179 * DVBFE_ALGO_SEARCH_AGAIN
180 * The frontend search algorithm was requested to search again
181 */
182enum dvbfe_search {
183 DVBFE_ALGO_SEARCH_SUCCESS = (1 << 0),
184 DVBFE_ALGO_SEARCH_ASLEEP = (1 << 1),
185 DVBFE_ALGO_SEARCH_FAILED = (1 << 2),
186 DVBFE_ALGO_SEARCH_INVALID = (1 << 3),
187 DVBFE_ALGO_SEARCH_AGAIN = (1 << 4),
188 DVBFE_ALGO_SEARCH_ERROR = (1 << 31),
189};
190
191
192struct dvb_tuner_ops {
193
194 struct dvb_tuner_info info;
195
196 int (*release)(struct dvb_frontend *fe);
197 int (*init)(struct dvb_frontend *fe);
198 int (*sleep)(struct dvb_frontend *fe);
199
200 /** This is for simple PLLs - set all parameters in one go. */
201 int (*set_params)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p);
202 int (*set_analog_params)(struct dvb_frontend *fe, struct analog_parameters *p);
203
204 /** This is support for demods like the mt352 - fills out the supplied buffer with what to write. */
205 int (*calc_regs)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p, u8 *buf, int buf_len);
206
207 /** This is to allow setting tuner-specific configs */
208 int (*set_config)(struct dvb_frontend *fe, void *priv_cfg);
209
210 int (*get_frequency)(struct dvb_frontend *fe, u32 *frequency);
211 int (*get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth);
212
213#define TUNER_STATUS_LOCKED 1
214#define TUNER_STATUS_STEREO 2
215 int (*get_status)(struct dvb_frontend *fe, u32 *status);
216 int (*get_rf_strength)(struct dvb_frontend *fe, u16 *strength);
217
218 /** These are provided separately from set_params in order to facilitate silicon
219 * tuners which require sophisticated tuning loops, controlling each parameter separately. */
220 int (*set_frequency)(struct dvb_frontend *fe, u32 frequency);
221 int (*set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth);
222
223 /*
224 * These are provided separately from set_params in order to facilitate silicon
225 * tuners which require sophisticated tuning loops, controlling each parameter separately.
226 */
227 int (*set_state)(struct dvb_frontend *fe, enum tuner_param param, struct tuner_state *state);
228 int (*get_state)(struct dvb_frontend *fe, enum tuner_param param, struct tuner_state *state);
229};
230
231struct analog_demod_info {
232 char *name;
233};
234
235struct analog_demod_ops {
236
237 struct analog_demod_info info;
238
239 void (*set_params)(struct dvb_frontend *fe,
240 struct analog_parameters *params);
241 int (*has_signal)(struct dvb_frontend *fe);
242 int (*get_afc)(struct dvb_frontend *fe);
243 void (*tuner_status)(struct dvb_frontend *fe);
244 void (*standby)(struct dvb_frontend *fe);
245 void (*release)(struct dvb_frontend *fe);
246 int (*i2c_gate_ctrl)(struct dvb_frontend *fe, int enable);
247
248 /** This is to allow setting tuner-specific configuration */
249 int (*set_config)(struct dvb_frontend *fe, void *priv_cfg);
250};
251
252struct dvb_frontend_ops {
253
254 struct dvb_frontend_info info;
255
256 void (*release)(struct dvb_frontend* fe);
257 void (*release_sec)(struct dvb_frontend* fe);
258
259 int (*init)(struct dvb_frontend* fe);
260 int (*sleep)(struct dvb_frontend* fe);
261
262 int (*write)(struct dvb_frontend* fe, const u8 buf[], int len);
263
264 /* if this is set, it overrides the default swzigzag */
265 int (*tune)(struct dvb_frontend* fe,
266 struct dvb_frontend_parameters* params,
267 unsigned int mode_flags,
268 unsigned int *delay,
269 fe_status_t *status);
270 /* get frontend tuning algorithm from the module */
271 enum dvbfe_algo (*get_frontend_algo)(struct dvb_frontend *fe);
272
273 /* these two are only used for the swzigzag code */
274 int (*set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
275 int (*get_tune_settings)(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* settings);
276
277 int (*get_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
278
279 int (*read_status)(struct dvb_frontend* fe, fe_status_t* status);
280 int (*read_ber)(struct dvb_frontend* fe, u32* ber);
281 int (*read_signal_strength)(struct dvb_frontend* fe, u16* strength);
282 int (*read_snr)(struct dvb_frontend* fe, u16* snr);
283 int (*read_ucblocks)(struct dvb_frontend* fe, u32* ucblocks);
284
285 int (*diseqc_reset_overload)(struct dvb_frontend* fe);
286 int (*diseqc_send_master_cmd)(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd);
287 int (*diseqc_recv_slave_reply)(struct dvb_frontend* fe, struct dvb_diseqc_slave_reply* reply);
288 int (*diseqc_send_burst)(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd);
289 int (*set_tone)(struct dvb_frontend* fe, fe_sec_tone_mode_t tone);
290 int (*set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage);
291 int (*enable_high_lnb_voltage)(struct dvb_frontend* fe, long arg);
292 int (*dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned long cmd);
293 int (*i2c_gate_ctrl)(struct dvb_frontend* fe, int enable);
294 int (*ts_bus_ctrl)(struct dvb_frontend* fe, int acquire);
295
296 /* These callbacks are for devices that implement their own
297 * tuning algorithms, rather than a simple swzigzag
298 */
299 enum dvbfe_search (*search)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p);
300 int (*track)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p);
301
302 struct dvb_tuner_ops tuner_ops;
303 struct analog_demod_ops analog_ops;
304
305 int (*set_property)(struct dvb_frontend* fe, struct dtv_property* tvp);
306 int (*get_property)(struct dvb_frontend* fe, struct dtv_property* tvp);
307};
308
309#define MAX_EVENT 8
310
311struct dvb_fe_events {
312 struct dvb_frontend_event events[MAX_EVENT];
313 int eventw;
314 int eventr;
315 int overflow;
316 wait_queue_head_t wait_queue;
317 struct mutex mtx;
318};
319
320struct dtv_frontend_properties {
321
322 /* Cache State */
323 u32 state;
324
325 u32 frequency;
326 fe_modulation_t modulation;
327
328 fe_sec_voltage_t voltage;
329 fe_sec_tone_mode_t sectone;
330 fe_spectral_inversion_t inversion;
331 fe_code_rate_t fec_inner;
332 fe_transmit_mode_t transmission_mode;
333 u32 bandwidth_hz; /* 0 = AUTO */
334 fe_guard_interval_t guard_interval;
335 fe_hierarchy_t hierarchy;
336 u32 symbol_rate;
337 fe_code_rate_t code_rate_HP;
338 fe_code_rate_t code_rate_LP;
339
340 fe_pilot_t pilot;
341 fe_rolloff_t rolloff;
342
343 fe_delivery_system_t delivery_system;
344
345 /* ISDB-T specifics */
346 u8 isdbt_partial_reception;
347 u8 isdbt_sb_mode;
348 u8 isdbt_sb_subchannel;
349 u32 isdbt_sb_segment_idx;
350 u32 isdbt_sb_segment_count;
351 u8 isdbt_layer_enabled;
352 struct {
353 u8 segment_count;
354 fe_code_rate_t fec;
355 fe_modulation_t modulation;
356 u8 interleaving;
357 } layer[3];
358
359 /* ISDB-T specifics */
360 u32 isdbs_ts_id;
361
362 /* DVB-T2 specifics */
363 u32 dvbt2_plp_id;
364};
365
366struct dvb_frontend {
367 struct dvb_frontend_ops ops;
368 struct dvb_adapter *dvb;
369 void *demodulator_priv;
370 void *tuner_priv;
371 void *frontend_priv;
372 void *sec_priv;
373 void *analog_demod_priv;
374 struct dtv_frontend_properties dtv_property_cache;
375#define DVB_FRONTEND_COMPONENT_TUNER 0
376 int (*callback)(void *adapter_priv, int component, int cmd, int arg);
377 int id;
378};
379
380extern int dvb_register_frontend(struct dvb_adapter *dvb,
381 struct dvb_frontend *fe);
382
383extern int dvb_unregister_frontend(struct dvb_frontend *fe);
384
385extern void dvb_frontend_detach(struct dvb_frontend *fe);
386
387extern void dvb_frontend_reinitialise(struct dvb_frontend *fe);
388
389extern void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec);
390extern s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime);
391
392#endif
diff --git a/drivers/media/dvb/dvb-core/dvb_math.c b/drivers/media/dvb/dvb-core/dvb_math.c
new file mode 100644
index 00000000000..beb7c93aa6c
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_math.c
@@ -0,0 +1,145 @@
1/*
2 * dvb-math provides some complex fixed-point math
3 * operations shared between the dvb related stuff
4 *
5 * Copyright (C) 2006 Christoph Pfister (christophpfister@gmail.com)
6 *
7 * This library is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#include <linux/bitops.h>
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <asm/bug.h>
26#include "dvb_math.h"
27
28static const unsigned short logtable[256] = {
29 0x0000, 0x0171, 0x02e0, 0x044e, 0x05ba, 0x0725, 0x088e, 0x09f7,
30 0x0b5d, 0x0cc3, 0x0e27, 0x0f8a, 0x10eb, 0x124b, 0x13aa, 0x1508,
31 0x1664, 0x17bf, 0x1919, 0x1a71, 0x1bc8, 0x1d1e, 0x1e73, 0x1fc6,
32 0x2119, 0x226a, 0x23ba, 0x2508, 0x2656, 0x27a2, 0x28ed, 0x2a37,
33 0x2b80, 0x2cc8, 0x2e0f, 0x2f54, 0x3098, 0x31dc, 0x331e, 0x345f,
34 0x359f, 0x36de, 0x381b, 0x3958, 0x3a94, 0x3bce, 0x3d08, 0x3e41,
35 0x3f78, 0x40af, 0x41e4, 0x4319, 0x444c, 0x457f, 0x46b0, 0x47e1,
36 0x4910, 0x4a3f, 0x4b6c, 0x4c99, 0x4dc5, 0x4eef, 0x5019, 0x5142,
37 0x526a, 0x5391, 0x54b7, 0x55dc, 0x5700, 0x5824, 0x5946, 0x5a68,
38 0x5b89, 0x5ca8, 0x5dc7, 0x5ee5, 0x6003, 0x611f, 0x623a, 0x6355,
39 0x646f, 0x6588, 0x66a0, 0x67b7, 0x68ce, 0x69e4, 0x6af8, 0x6c0c,
40 0x6d20, 0x6e32, 0x6f44, 0x7055, 0x7165, 0x7274, 0x7383, 0x7490,
41 0x759d, 0x76aa, 0x77b5, 0x78c0, 0x79ca, 0x7ad3, 0x7bdb, 0x7ce3,
42 0x7dea, 0x7ef0, 0x7ff6, 0x80fb, 0x81ff, 0x8302, 0x8405, 0x8507,
43 0x8608, 0x8709, 0x8809, 0x8908, 0x8a06, 0x8b04, 0x8c01, 0x8cfe,
44 0x8dfa, 0x8ef5, 0x8fef, 0x90e9, 0x91e2, 0x92db, 0x93d2, 0x94ca,
45 0x95c0, 0x96b6, 0x97ab, 0x98a0, 0x9994, 0x9a87, 0x9b7a, 0x9c6c,
46 0x9d5e, 0x9e4f, 0x9f3f, 0xa02e, 0xa11e, 0xa20c, 0xa2fa, 0xa3e7,
47 0xa4d4, 0xa5c0, 0xa6ab, 0xa796, 0xa881, 0xa96a, 0xaa53, 0xab3c,
48 0xac24, 0xad0c, 0xadf2, 0xaed9, 0xafbe, 0xb0a4, 0xb188, 0xb26c,
49 0xb350, 0xb433, 0xb515, 0xb5f7, 0xb6d9, 0xb7ba, 0xb89a, 0xb97a,
50 0xba59, 0xbb38, 0xbc16, 0xbcf4, 0xbdd1, 0xbead, 0xbf8a, 0xc065,
51 0xc140, 0xc21b, 0xc2f5, 0xc3cf, 0xc4a8, 0xc580, 0xc658, 0xc730,
52 0xc807, 0xc8de, 0xc9b4, 0xca8a, 0xcb5f, 0xcc34, 0xcd08, 0xcddc,
53 0xceaf, 0xcf82, 0xd054, 0xd126, 0xd1f7, 0xd2c8, 0xd399, 0xd469,
54 0xd538, 0xd607, 0xd6d6, 0xd7a4, 0xd872, 0xd93f, 0xda0c, 0xdad9,
55 0xdba5, 0xdc70, 0xdd3b, 0xde06, 0xded0, 0xdf9a, 0xe063, 0xe12c,
56 0xe1f5, 0xe2bd, 0xe385, 0xe44c, 0xe513, 0xe5d9, 0xe69f, 0xe765,
57 0xe82a, 0xe8ef, 0xe9b3, 0xea77, 0xeb3b, 0xebfe, 0xecc1, 0xed83,
58 0xee45, 0xef06, 0xefc8, 0xf088, 0xf149, 0xf209, 0xf2c8, 0xf387,
59 0xf446, 0xf505, 0xf5c3, 0xf680, 0xf73e, 0xf7fb, 0xf8b7, 0xf973,
60 0xfa2f, 0xfaea, 0xfba5, 0xfc60, 0xfd1a, 0xfdd4, 0xfe8e, 0xff47
61};
62
63unsigned int intlog2(u32 value)
64{
65 /**
66 * returns: log2(value) * 2^24
67 * wrong result if value = 0 (log2(0) is undefined)
68 */
69 unsigned int msb;
70 unsigned int logentry;
71 unsigned int significand;
72 unsigned int interpolation;
73
74 if (unlikely(value == 0)) {
75 WARN_ON(1);
76 return 0;
77 }
78
79 /* first detect the msb (count begins at 0) */
80 msb = fls(value) - 1;
81
82 /**
83 * now we use a logtable after the following method:
84 *
85 * log2(2^x * y) * 2^24 = x * 2^24 + log2(y) * 2^24
86 * where x = msb and therefore 1 <= y < 2
87 * first y is determined by shifting the value left
88 * so that msb is bit 31
89 * 0x00231f56 -> 0x8C7D5800
90 * the result is y * 2^31 -> "significand"
91 * then the highest 9 bits are used for a table lookup
92 * the highest bit is discarded because it's always set
93 * the highest nine bits in our example are 100011000
94 * so we would use the entry 0x18
95 */
96 significand = value << (31 - msb);
97 logentry = (significand >> 23) & 0xff;
98
99 /**
100 * last step we do is interpolation because of the
101 * limitations of the log table the error is that part of
102 * the significand which isn't used for lookup then we
103 * compute the ratio between the error and the next table entry
104 * and interpolate it between the log table entry used and the
105 * next one the biggest error possible is 0x7fffff
106 * (in our example it's 0x7D5800)
107 * needed value for next table entry is 0x800000
108 * so the interpolation is
109 * (error / 0x800000) * (logtable_next - logtable_current)
110 * in the implementation the division is moved to the end for
111 * better accuracy there is also an overflow correction if
112 * logtable_next is 256
113 */
114 interpolation = ((significand & 0x7fffff) *
115 ((logtable[(logentry + 1) & 0xff] -
116 logtable[logentry]) & 0xffff)) >> 15;
117
118 /* now we return the result */
119 return ((msb << 24) + (logtable[logentry] << 8) + interpolation);
120}
121EXPORT_SYMBOL(intlog2);
122
123unsigned int intlog10(u32 value)
124{
125 /**
126 * returns: log10(value) * 2^24
127 * wrong result if value = 0 (log10(0) is undefined)
128 */
129 u64 log;
130
131 if (unlikely(value == 0)) {
132 WARN_ON(1);
133 return 0;
134 }
135
136 log = intlog2(value);
137
138 /**
139 * we use the following method:
140 * log10(x) = log2(x) * log10(2)
141 */
142
143 return (log * 646456993) >> 31;
144}
145EXPORT_SYMBOL(intlog10);
diff --git a/drivers/media/dvb/dvb-core/dvb_math.h b/drivers/media/dvb/dvb-core/dvb_math.h
new file mode 100644
index 00000000000..aecc867e940
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_math.h
@@ -0,0 +1,58 @@
1/*
2 * dvb-math provides some complex fixed-point math
3 * operations shared between the dvb related stuff
4 *
5 * Copyright (C) 2006 Christoph Pfister (christophpfister@gmail.com)
6 *
7 * This library is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#ifndef __DVB_MATH_H
23#define __DVB_MATH_H
24
25#include <linux/types.h>
26
27/**
28 * computes log2 of a value; the result is shifted left by 24 bits
29 *
30 * to use rational values you can use the following method:
31 * intlog2(value) = intlog2(value * 2^x) - x * 2^24
32 *
33 * example: intlog2(8) will give 3 << 24 = 3 * 2^24
34 * example: intlog2(9) will give 3 << 24 + ... = 3.16... * 2^24
35 * example: intlog2(1.5) = intlog2(3) - 2^24 = 0.584... * 2^24
36 *
37 * @param value The value (must be != 0)
38 * @return log2(value) * 2^24
39 */
40extern unsigned int intlog2(u32 value);
41
42/**
43 * computes log10 of a value; the result is shifted left by 24 bits
44 *
45 * to use rational values you can use the following method:
46 * intlog10(value) = intlog10(value * 10^x) - x * 2^24
47 *
48 * example: intlog10(1000) will give 3 << 24 = 3 * 2^24
49 * due to the implementation intlog10(1000) might be not exactly 3 * 2^24
50 *
51 * look at intlog2 for similar examples
52 *
53 * @param value The value (must be != 0)
54 * @return log10(value) * 2^24
55 */
56extern unsigned int intlog10(u32 value);
57
58#endif
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c
new file mode 100644
index 00000000000..51752a9ef7a
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_net.c
@@ -0,0 +1,1518 @@
1/*
2 * dvb_net.c
3 *
4 * Copyright (C) 2001 Convergence integrated media GmbH
5 * Ralph Metzler <ralph@convergence.de>
6 * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
7 *
8 * ULE Decapsulation code:
9 * Copyright (C) 2003, 2004 gcs - Global Communication & Services GmbH.
10 * and Department of Scientific Computing
11 * Paris Lodron University of Salzburg.
12 * Hilmar Linder <hlinder@cosy.sbg.ac.at>
13 * and Wolfram Stering <wstering@cosy.sbg.ac.at>
14 *
15 * ULE Decaps according to RFC 4326.
16 *
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License
19 * as published by the Free Software Foundation; either version 2
20 * of the License, or (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
31 */
32
33/*
34 * ULE ChangeLog:
35 * Feb 2004: hl/ws v1: Implementing draft-fair-ipdvb-ule-01.txt
36 *
37 * Dec 2004: hl/ws v2: Implementing draft-ietf-ipdvb-ule-03.txt:
38 * ULE Extension header handling.
39 * Bugreports by Moritz Vieth and Hanno Tersteegen,
40 * Fraunhofer Institute for Open Communication Systems
41 * Competence Center for Advanced Satellite Communications.
42 * Bugfixes and robustness improvements.
43 * Filtering on dest MAC addresses, if present (D-Bit = 0)
44 * ULE_DEBUG compile-time option.
45 * Apr 2006: cp v3: Bugfixes and compliency with RFC 4326 (ULE) by
46 * Christian Praehauser <cpraehaus@cosy.sbg.ac.at>,
47 * Paris Lodron University of Salzburg.
48 */
49
50/*
51 * FIXME / TODO (dvb_net.c):
52 *
53 * Unloading does not work for 2.6.9 kernels: a refcount doesn't go to zero.
54 *
55 */
56
57#include <linux/module.h>
58#include <linux/kernel.h>
59#include <linux/netdevice.h>
60#include <linux/etherdevice.h>
61#include <linux/dvb/net.h>
62#include <linux/uio.h>
63#include <asm/uaccess.h>
64#include <linux/crc32.h>
65#include <linux/mutex.h>
66#include <linux/sched.h>
67
68#include "dvb_demux.h"
69#include "dvb_net.h"
70
71static int dvb_net_debug;
72module_param(dvb_net_debug, int, 0444);
73MODULE_PARM_DESC(dvb_net_debug, "enable debug messages");
74
75#define dprintk(x...) do { if (dvb_net_debug) printk(x); } while (0)
76
77
78static inline __u32 iov_crc32( __u32 c, struct kvec *iov, unsigned int cnt )
79{
80 unsigned int j;
81 for (j = 0; j < cnt; j++)
82 c = crc32_be( c, iov[j].iov_base, iov[j].iov_len );
83 return c;
84}
85
86
87#define DVB_NET_MULTICAST_MAX 10
88
89#undef ULE_DEBUG
90
91#ifdef ULE_DEBUG
92
93#define MAC_ADDR_PRINTFMT "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x"
94#define MAX_ADDR_PRINTFMT_ARGS(macap) (macap)[0],(macap)[1],(macap)[2],(macap)[3],(macap)[4],(macap)[5]
95
96#define isprint(c) ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'))
97
98static void hexdump( const unsigned char *buf, unsigned short len )
99{
100 char str[80], octet[10];
101 int ofs, i, l;
102
103 for (ofs = 0; ofs < len; ofs += 16) {
104 sprintf( str, "%03d: ", ofs );
105
106 for (i = 0; i < 16; i++) {
107 if ((i + ofs) < len)
108 sprintf( octet, "%02x ", buf[ofs + i] );
109 else
110 strcpy( octet, " " );
111
112 strcat( str, octet );
113 }
114 strcat( str, " " );
115 l = strlen( str );
116
117 for (i = 0; (i < 16) && ((i + ofs) < len); i++)
118 str[l++] = isprint( buf[ofs + i] ) ? buf[ofs + i] : '.';
119
120 str[l] = '\0';
121 printk( KERN_WARNING "%s\n", str );
122 }
123}
124
125#endif
126
127struct dvb_net_priv {
128 int in_use;
129 u16 pid;
130 struct net_device *net;
131 struct dvb_net *host;
132 struct dmx_demux *demux;
133 struct dmx_section_feed *secfeed;
134 struct dmx_section_filter *secfilter;
135 struct dmx_ts_feed *tsfeed;
136 int multi_num;
137 struct dmx_section_filter *multi_secfilter[DVB_NET_MULTICAST_MAX];
138 unsigned char multi_macs[DVB_NET_MULTICAST_MAX][6];
139 int rx_mode;
140#define RX_MODE_UNI 0
141#define RX_MODE_MULTI 1
142#define RX_MODE_ALL_MULTI 2
143#define RX_MODE_PROMISC 3
144 struct work_struct set_multicast_list_wq;
145 struct work_struct restart_net_feed_wq;
146 unsigned char feedtype; /* Either FEED_TYPE_ or FEED_TYPE_ULE */
147 int need_pusi; /* Set to 1, if synchronization on PUSI required. */
148 unsigned char tscc; /* TS continuity counter after sync on PUSI. */
149 struct sk_buff *ule_skb; /* ULE SNDU decodes into this buffer. */
150 unsigned char *ule_next_hdr; /* Pointer into skb to next ULE extension header. */
151 unsigned short ule_sndu_len; /* ULE SNDU length in bytes, w/o D-Bit. */
152 unsigned short ule_sndu_type; /* ULE SNDU type field, complete. */
153 unsigned char ule_sndu_type_1; /* ULE SNDU type field, if split across 2 TS cells. */
154 unsigned char ule_dbit; /* Whether the DestMAC address present
155 * or not (bit is set). */
156 unsigned char ule_bridged; /* Whether the ULE_BRIDGED extension header was found. */
157 int ule_sndu_remain; /* Nr. of bytes still required for current ULE SNDU. */
158 unsigned long ts_count; /* Current ts cell counter. */
159 struct mutex mutex;
160};
161
162
163/**
164 * Determine the packet's protocol ID. The rule here is that we
165 * assume 802.3 if the type field is short enough to be a length.
166 * This is normal practice and works for any 'now in use' protocol.
167 *
168 * stolen from eth.c out of the linux kernel, hacked for dvb-device
169 * by Michael Holzt <kju@debian.org>
170 */
171static __be16 dvb_net_eth_type_trans(struct sk_buff *skb,
172 struct net_device *dev)
173{
174 struct ethhdr *eth;
175 unsigned char *rawp;
176
177 skb_reset_mac_header(skb);
178 skb_pull(skb,dev->hard_header_len);
179 eth = eth_hdr(skb);
180
181 if (*eth->h_dest & 1) {
182 if(memcmp(eth->h_dest,dev->broadcast, ETH_ALEN)==0)
183 skb->pkt_type=PACKET_BROADCAST;
184 else
185 skb->pkt_type=PACKET_MULTICAST;
186 }
187
188 if (ntohs(eth->h_proto) >= 1536)
189 return eth->h_proto;
190
191 rawp = skb->data;
192
193 /**
194 * This is a magic hack to spot IPX packets. Older Novell breaks
195 * the protocol design and runs IPX over 802.3 without an 802.2 LLC
196 * layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
197 * won't work for fault tolerant netware but does for the rest.
198 */
199 if (*(unsigned short *)rawp == 0xFFFF)
200 return htons(ETH_P_802_3);
201
202 /**
203 * Real 802.2 LLC
204 */
205 return htons(ETH_P_802_2);
206}
207
208#define TS_SZ 188
209#define TS_SYNC 0x47
210#define TS_TEI 0x80
211#define TS_SC 0xC0
212#define TS_PUSI 0x40
213#define TS_AF_A 0x20
214#define TS_AF_D 0x10
215
216/* ULE Extension Header handlers. */
217
218#define ULE_TEST 0
219#define ULE_BRIDGED 1
220
221#define ULE_OPTEXTHDR_PADDING 0
222
223static int ule_test_sndu( struct dvb_net_priv *p )
224{
225 return -1;
226}
227
228static int ule_bridged_sndu( struct dvb_net_priv *p )
229{
230 struct ethhdr *hdr = (struct ethhdr*) p->ule_next_hdr;
231 if(ntohs(hdr->h_proto) < 1536) {
232 int framelen = p->ule_sndu_len - ((p->ule_next_hdr+sizeof(struct ethhdr)) - p->ule_skb->data);
233 /* A frame Type < 1536 for a bridged frame, introduces a LLC Length field. */
234 if(framelen != ntohs(hdr->h_proto)) {
235 return -1;
236 }
237 }
238 /* Note:
239 * From RFC4326:
240 * "A bridged SNDU is a Mandatory Extension Header of Type 1.
241 * It must be the final (or only) extension header specified in the header chain of a SNDU."
242 * The 'ule_bridged' flag will cause the extension header processing loop to terminate.
243 */
244 p->ule_bridged = 1;
245 return 0;
246}
247
248static int ule_exthdr_padding(struct dvb_net_priv *p)
249{
250 return 0;
251}
252
253/** Handle ULE extension headers.
254 * Function is called after a successful CRC32 verification of an ULE SNDU to complete its decoding.
255 * Returns: >= 0: nr. of bytes consumed by next extension header
256 * -1: Mandatory extension header that is not recognized or TEST SNDU; discard.
257 */
258static int handle_one_ule_extension( struct dvb_net_priv *p )
259{
260 /* Table of mandatory extension header handlers. The header type is the index. */
261 static int (*ule_mandatory_ext_handlers[255])( struct dvb_net_priv *p ) =
262 { [0] = ule_test_sndu, [1] = ule_bridged_sndu, [2] = NULL, };
263
264 /* Table of optional extension header handlers. The header type is the index. */
265 static int (*ule_optional_ext_handlers[255])( struct dvb_net_priv *p ) =
266 { [0] = ule_exthdr_padding, [1] = NULL, };
267
268 int ext_len = 0;
269 unsigned char hlen = (p->ule_sndu_type & 0x0700) >> 8;
270 unsigned char htype = p->ule_sndu_type & 0x00FF;
271
272 /* Discriminate mandatory and optional extension headers. */
273 if (hlen == 0) {
274 /* Mandatory extension header */
275 if (ule_mandatory_ext_handlers[htype]) {
276 ext_len = ule_mandatory_ext_handlers[htype]( p );
277 if(ext_len >= 0) {
278 p->ule_next_hdr += ext_len;
279 if (!p->ule_bridged) {
280 p->ule_sndu_type = ntohs(*(__be16 *)p->ule_next_hdr);
281 p->ule_next_hdr += 2;
282 } else {
283 p->ule_sndu_type = ntohs(*(__be16 *)(p->ule_next_hdr + ((p->ule_dbit ? 2 : 3) * ETH_ALEN)));
284 /* This assures the extension handling loop will terminate. */
285 }
286 }
287 // else: extension handler failed or SNDU should be discarded
288 } else
289 ext_len = -1; /* SNDU has to be discarded. */
290 } else {
291 /* Optional extension header. Calculate the length. */
292 ext_len = hlen << 1;
293 /* Process the optional extension header according to its type. */
294 if (ule_optional_ext_handlers[htype])
295 (void)ule_optional_ext_handlers[htype]( p );
296 p->ule_next_hdr += ext_len;
297 p->ule_sndu_type = ntohs( *(__be16 *)(p->ule_next_hdr-2) );
298 /*
299 * note: the length of the next header type is included in the
300 * length of THIS optional extension header
301 */
302 }
303
304 return ext_len;
305}
306
307static int handle_ule_extensions( struct dvb_net_priv *p )
308{
309 int total_ext_len = 0, l;
310
311 p->ule_next_hdr = p->ule_skb->data;
312 do {
313 l = handle_one_ule_extension( p );
314 if (l < 0)
315 return l; /* Stop extension header processing and discard SNDU. */
316 total_ext_len += l;
317#ifdef ULE_DEBUG
318 dprintk("handle_ule_extensions: ule_next_hdr=%p, ule_sndu_type=%i, "
319 "l=%i, total_ext_len=%i\n", p->ule_next_hdr,
320 (int) p->ule_sndu_type, l, total_ext_len);
321#endif
322
323 } while (p->ule_sndu_type < 1536);
324
325 return total_ext_len;
326}
327
328
329/** Prepare for a new ULE SNDU: reset the decoder state. */
330static inline void reset_ule( struct dvb_net_priv *p )
331{
332 p->ule_skb = NULL;
333 p->ule_next_hdr = NULL;
334 p->ule_sndu_len = 0;
335 p->ule_sndu_type = 0;
336 p->ule_sndu_type_1 = 0;
337 p->ule_sndu_remain = 0;
338 p->ule_dbit = 0xFF;
339 p->ule_bridged = 0;
340}
341
342/**
343 * Decode ULE SNDUs according to draft-ietf-ipdvb-ule-03.txt from a sequence of
344 * TS cells of a single PID.
345 */
346static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
347{
348 struct dvb_net_priv *priv = netdev_priv(dev);
349 unsigned long skipped = 0L;
350 const u8 *ts, *ts_end, *from_where = NULL;
351 u8 ts_remain = 0, how_much = 0, new_ts = 1;
352 struct ethhdr *ethh = NULL;
353 bool error = false;
354
355#ifdef ULE_DEBUG
356 /* The code inside ULE_DEBUG keeps a history of the last 100 TS cells processed. */
357 static unsigned char ule_hist[100*TS_SZ];
358 static unsigned char *ule_where = ule_hist, ule_dump;
359#endif
360
361 /* For all TS cells in current buffer.
362 * Appearently, we are called for every single TS cell.
363 */
364 for (ts = buf, ts_end = buf + buf_len; ts < ts_end; /* no default incr. */ ) {
365
366 if (new_ts) {
367 /* We are about to process a new TS cell. */
368
369#ifdef ULE_DEBUG
370 if (ule_where >= &ule_hist[100*TS_SZ]) ule_where = ule_hist;
371 memcpy( ule_where, ts, TS_SZ );
372 if (ule_dump) {
373 hexdump( ule_where, TS_SZ );
374 ule_dump = 0;
375 }
376 ule_where += TS_SZ;
377#endif
378
379 /* Check TS error conditions: sync_byte, transport_error_indicator, scrambling_control . */
380 if ((ts[0] != TS_SYNC) || (ts[1] & TS_TEI) || ((ts[3] & TS_SC) != 0)) {
381 printk(KERN_WARNING "%lu: Invalid TS cell: SYNC %#x, TEI %u, SC %#x.\n",
382 priv->ts_count, ts[0], ts[1] & TS_TEI >> 7, ts[3] & 0xC0 >> 6);
383
384 /* Drop partly decoded SNDU, reset state, resync on PUSI. */
385 if (priv->ule_skb) {
386 dev_kfree_skb( priv->ule_skb );
387 /* Prepare for next SNDU. */
388 dev->stats.rx_errors++;
389 dev->stats.rx_frame_errors++;
390 }
391 reset_ule(priv);
392 priv->need_pusi = 1;
393
394 /* Continue with next TS cell. */
395 ts += TS_SZ;
396 priv->ts_count++;
397 continue;
398 }
399
400 ts_remain = 184;
401 from_where = ts + 4;
402 }
403 /* Synchronize on PUSI, if required. */
404 if (priv->need_pusi) {
405 if (ts[1] & TS_PUSI) {
406 /* Find beginning of first ULE SNDU in current TS cell. */
407 /* Synchronize continuity counter. */
408 priv->tscc = ts[3] & 0x0F;
409 /* There is a pointer field here. */
410 if (ts[4] > ts_remain) {
411 printk(KERN_ERR "%lu: Invalid ULE packet "
412 "(pointer field %d)\n", priv->ts_count, ts[4]);
413 ts += TS_SZ;
414 priv->ts_count++;
415 continue;
416 }
417 /* Skip to destination of pointer field. */
418 from_where = &ts[5] + ts[4];
419 ts_remain -= 1 + ts[4];
420 skipped = 0;
421 } else {
422 skipped++;
423 ts += TS_SZ;
424 priv->ts_count++;
425 continue;
426 }
427 }
428
429 if (new_ts) {
430 /* Check continuity counter. */
431 if ((ts[3] & 0x0F) == priv->tscc)
432 priv->tscc = (priv->tscc + 1) & 0x0F;
433 else {
434 /* TS discontinuity handling: */
435 printk(KERN_WARNING "%lu: TS discontinuity: got %#x, "
436 "expected %#x.\n", priv->ts_count, ts[3] & 0x0F, priv->tscc);
437 /* Drop partly decoded SNDU, reset state, resync on PUSI. */
438 if (priv->ule_skb) {
439 dev_kfree_skb( priv->ule_skb );
440 /* Prepare for next SNDU. */
441 // reset_ule(priv); moved to below.
442 dev->stats.rx_errors++;
443 dev->stats.rx_frame_errors++;
444 }
445 reset_ule(priv);
446 /* skip to next PUSI. */
447 priv->need_pusi = 1;
448 continue;
449 }
450 /* If we still have an incomplete payload, but PUSI is
451 * set; some TS cells are missing.
452 * This is only possible here, if we missed exactly 16 TS
453 * cells (continuity counter wrap). */
454 if (ts[1] & TS_PUSI) {
455 if (! priv->need_pusi) {
456 if (!(*from_where < (ts_remain-1)) || *from_where != priv->ule_sndu_remain) {
457 /* Pointer field is invalid. Drop this TS cell and any started ULE SNDU. */
458 printk(KERN_WARNING "%lu: Invalid pointer "
459 "field: %u.\n", priv->ts_count, *from_where);
460
461 /* Drop partly decoded SNDU, reset state, resync on PUSI. */
462 if (priv->ule_skb) {
463 error = true;
464 dev_kfree_skb(priv->ule_skb);
465 }
466
467 if (error || priv->ule_sndu_remain) {
468 dev->stats.rx_errors++;
469 dev->stats.rx_frame_errors++;
470 error = false;
471 }
472
473 reset_ule(priv);
474 priv->need_pusi = 1;
475 continue;
476 }
477 /* Skip pointer field (we're processing a
478 * packed payload). */
479 from_where += 1;
480 ts_remain -= 1;
481 } else
482 priv->need_pusi = 0;
483
484 if (priv->ule_sndu_remain > 183) {
485 /* Current SNDU lacks more data than there could be available in the
486 * current TS cell. */
487 dev->stats.rx_errors++;
488 dev->stats.rx_length_errors++;
489 printk(KERN_WARNING "%lu: Expected %d more SNDU bytes, but "
490 "got PUSI (pf %d, ts_remain %d). Flushing incomplete payload.\n",
491 priv->ts_count, priv->ule_sndu_remain, ts[4], ts_remain);
492 dev_kfree_skb(priv->ule_skb);
493 /* Prepare for next SNDU. */
494 reset_ule(priv);
495 /* Resync: go to where pointer field points to: start of next ULE SNDU. */
496 from_where += ts[4];
497 ts_remain -= ts[4];
498 }
499 }
500 }
501
502 /* Check if new payload needs to be started. */
503 if (priv->ule_skb == NULL) {
504 /* Start a new payload with skb.
505 * Find ULE header. It is only guaranteed that the
506 * length field (2 bytes) is contained in the current
507 * TS.
508 * Check ts_remain has to be >= 2 here. */
509 if (ts_remain < 2) {
510 printk(KERN_WARNING "Invalid payload packing: only %d "
511 "bytes left in TS. Resyncing.\n", ts_remain);
512 priv->ule_sndu_len = 0;
513 priv->need_pusi = 1;
514 ts += TS_SZ;
515 continue;
516 }
517
518 if (! priv->ule_sndu_len) {
519 /* Got at least two bytes, thus extrace the SNDU length. */
520 priv->ule_sndu_len = from_where[0] << 8 | from_where[1];
521 if (priv->ule_sndu_len & 0x8000) {
522 /* D-Bit is set: no dest mac present. */
523 priv->ule_sndu_len &= 0x7FFF;
524 priv->ule_dbit = 1;
525 } else
526 priv->ule_dbit = 0;
527
528 if (priv->ule_sndu_len < 5) {
529 printk(KERN_WARNING "%lu: Invalid ULE SNDU length %u. "
530 "Resyncing.\n", priv->ts_count, priv->ule_sndu_len);
531 dev->stats.rx_errors++;
532 dev->stats.rx_length_errors++;
533 priv->ule_sndu_len = 0;
534 priv->need_pusi = 1;
535 new_ts = 1;
536 ts += TS_SZ;
537 priv->ts_count++;
538 continue;
539 }
540 ts_remain -= 2; /* consume the 2 bytes SNDU length. */
541 from_where += 2;
542 }
543
544 priv->ule_sndu_remain = priv->ule_sndu_len + 2;
545 /*
546 * State of current TS:
547 * ts_remain (remaining bytes in the current TS cell)
548 * 0 ule_type is not available now, we need the next TS cell
549 * 1 the first byte of the ule_type is present
550 * >=2 full ULE header present, maybe some payload data as well.
551 */
552 switch (ts_remain) {
553 case 1:
554 priv->ule_sndu_remain--;
555 priv->ule_sndu_type = from_where[0] << 8;
556 priv->ule_sndu_type_1 = 1; /* first byte of ule_type is set. */
557 ts_remain -= 1; from_where += 1;
558 /* Continue w/ next TS. */
559 case 0:
560 new_ts = 1;
561 ts += TS_SZ;
562 priv->ts_count++;
563 continue;
564
565 default: /* complete ULE header is present in current TS. */
566 /* Extract ULE type field. */
567 if (priv->ule_sndu_type_1) {
568 priv->ule_sndu_type_1 = 0;
569 priv->ule_sndu_type |= from_where[0];
570 from_where += 1; /* points to payload start. */
571 ts_remain -= 1;
572 } else {
573 /* Complete type is present in new TS. */
574 priv->ule_sndu_type = from_where[0] << 8 | from_where[1];
575 from_where += 2; /* points to payload start. */
576 ts_remain -= 2;
577 }
578 break;
579 }
580
581 /* Allocate the skb (decoder target buffer) with the correct size, as follows:
582 * prepare for the largest case: bridged SNDU with MAC address (dbit = 0). */
583 priv->ule_skb = dev_alloc_skb( priv->ule_sndu_len + ETH_HLEN + ETH_ALEN );
584 if (priv->ule_skb == NULL) {
585 printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n",
586 dev->name);
587 dev->stats.rx_dropped++;
588 return;
589 }
590
591 /* This includes the CRC32 _and_ dest mac, if !dbit. */
592 priv->ule_sndu_remain = priv->ule_sndu_len;
593 priv->ule_skb->dev = dev;
594 /* Leave space for Ethernet or bridged SNDU header (eth hdr plus one MAC addr). */
595 skb_reserve( priv->ule_skb, ETH_HLEN + ETH_ALEN );
596 }
597
598 /* Copy data into our current skb. */
599 how_much = min(priv->ule_sndu_remain, (int)ts_remain);
600 memcpy(skb_put(priv->ule_skb, how_much), from_where, how_much);
601 priv->ule_sndu_remain -= how_much;
602 ts_remain -= how_much;
603 from_where += how_much;
604
605 /* Check for complete payload. */
606 if (priv->ule_sndu_remain <= 0) {
607 /* Check CRC32, we've got it in our skb already. */
608 __be16 ulen = htons(priv->ule_sndu_len);
609 __be16 utype = htons(priv->ule_sndu_type);
610 const u8 *tail;
611 struct kvec iov[3] = {
612 { &ulen, sizeof ulen },
613 { &utype, sizeof utype },
614 { priv->ule_skb->data, priv->ule_skb->len - 4 }
615 };
616 u32 ule_crc = ~0L, expected_crc;
617 if (priv->ule_dbit) {
618 /* Set D-bit for CRC32 verification,
619 * if it was set originally. */
620 ulen |= htons(0x8000);
621 }
622
623 ule_crc = iov_crc32(ule_crc, iov, 3);
624 tail = skb_tail_pointer(priv->ule_skb);
625 expected_crc = *(tail - 4) << 24 |
626 *(tail - 3) << 16 |
627 *(tail - 2) << 8 |
628 *(tail - 1);
629 if (ule_crc != expected_crc) {
630 printk(KERN_WARNING "%lu: CRC32 check FAILED: %08x / %08x, SNDU len %d type %#x, ts_remain %d, next 2: %x.\n",
631 priv->ts_count, ule_crc, expected_crc, priv->ule_sndu_len, priv->ule_sndu_type, ts_remain, ts_remain > 2 ? *(unsigned short *)from_where : 0);
632
633#ifdef ULE_DEBUG
634 hexdump( iov[0].iov_base, iov[0].iov_len );
635 hexdump( iov[1].iov_base, iov[1].iov_len );
636 hexdump( iov[2].iov_base, iov[2].iov_len );
637
638 if (ule_where == ule_hist) {
639 hexdump( &ule_hist[98*TS_SZ], TS_SZ );
640 hexdump( &ule_hist[99*TS_SZ], TS_SZ );
641 } else if (ule_where == &ule_hist[TS_SZ]) {
642 hexdump( &ule_hist[99*TS_SZ], TS_SZ );
643 hexdump( ule_hist, TS_SZ );
644 } else {
645 hexdump( ule_where - TS_SZ - TS_SZ, TS_SZ );
646 hexdump( ule_where - TS_SZ, TS_SZ );
647 }
648 ule_dump = 1;
649#endif
650
651 dev->stats.rx_errors++;
652 dev->stats.rx_crc_errors++;
653 dev_kfree_skb(priv->ule_skb);
654 } else {
655 /* CRC32 verified OK. */
656 u8 dest_addr[ETH_ALEN];
657 static const u8 bc_addr[ETH_ALEN] =
658 { [ 0 ... ETH_ALEN-1] = 0xff };
659
660 /* CRC32 was OK. Remove it from skb. */
661 priv->ule_skb->tail -= 4;
662 priv->ule_skb->len -= 4;
663
664 if (!priv->ule_dbit) {
665 /*
666 * The destination MAC address is the
667 * next data in the skb. It comes
668 * before any extension headers.
669 *
670 * Check if the payload of this SNDU
671 * should be passed up the stack.
672 */
673 register int drop = 0;
674 if (priv->rx_mode != RX_MODE_PROMISC) {
675 if (priv->ule_skb->data[0] & 0x01) {
676 /* multicast or broadcast */
677 if (memcmp(priv->ule_skb->data, bc_addr, ETH_ALEN)) {
678 /* multicast */
679 if (priv->rx_mode == RX_MODE_MULTI) {
680 int i;
681 for(i = 0; i < priv->multi_num && memcmp(priv->ule_skb->data, priv->multi_macs[i], ETH_ALEN); i++)
682 ;
683 if (i == priv->multi_num)
684 drop = 1;
685 } else if (priv->rx_mode != RX_MODE_ALL_MULTI)
686 drop = 1; /* no broadcast; */
687 /* else: all multicast mode: accept all multicast packets */
688 }
689 /* else: broadcast */
690 }
691 else if (memcmp(priv->ule_skb->data, dev->dev_addr, ETH_ALEN))
692 drop = 1;
693 /* else: destination address matches the MAC address of our receiver device */
694 }
695 /* else: promiscuous mode; pass everything up the stack */
696
697 if (drop) {
698#ifdef ULE_DEBUG
699 dprintk("Dropping SNDU: MAC destination address does not match: dest addr: "MAC_ADDR_PRINTFMT", dev addr: "MAC_ADDR_PRINTFMT"\n",
700 MAX_ADDR_PRINTFMT_ARGS(priv->ule_skb->data), MAX_ADDR_PRINTFMT_ARGS(dev->dev_addr));
701#endif
702 dev_kfree_skb(priv->ule_skb);
703 goto sndu_done;
704 }
705 else
706 {
707 skb_copy_from_linear_data(priv->ule_skb,
708 dest_addr,
709 ETH_ALEN);
710 skb_pull(priv->ule_skb, ETH_ALEN);
711 }
712 }
713
714 /* Handle ULE Extension Headers. */
715 if (priv->ule_sndu_type < 1536) {
716 /* There is an extension header. Handle it accordingly. */
717 int l = handle_ule_extensions(priv);
718 if (l < 0) {
719 /* Mandatory extension header unknown or TEST SNDU. Drop it. */
720 // printk( KERN_WARNING "Dropping SNDU, extension headers.\n" );
721 dev_kfree_skb(priv->ule_skb);
722 goto sndu_done;
723 }
724 skb_pull(priv->ule_skb, l);
725 }
726
727 /*
728 * Construct/assure correct ethernet header.
729 * Note: in bridged mode (priv->ule_bridged !=
730 * 0) we already have the (original) ethernet
731 * header at the start of the payload (after
732 * optional dest. address and any extension
733 * headers).
734 */
735
736 if (!priv->ule_bridged) {
737 skb_push(priv->ule_skb, ETH_HLEN);
738 ethh = (struct ethhdr *)priv->ule_skb->data;
739 if (!priv->ule_dbit) {
740 /* dest_addr buffer is only valid if priv->ule_dbit == 0 */
741 memcpy(ethh->h_dest, dest_addr, ETH_ALEN);
742 memset(ethh->h_source, 0, ETH_ALEN);
743 }
744 else /* zeroize source and dest */
745 memset( ethh, 0, ETH_ALEN*2 );
746
747 ethh->h_proto = htons(priv->ule_sndu_type);
748 }
749 /* else: skb is in correct state; nothing to do. */
750 priv->ule_bridged = 0;
751
752 /* Stuff into kernel's protocol stack. */
753 priv->ule_skb->protocol = dvb_net_eth_type_trans(priv->ule_skb, dev);
754 /* If D-bit is set (i.e. destination MAC address not present),
755 * receive the packet anyhow. */
756 /* if (priv->ule_dbit && skb->pkt_type == PACKET_OTHERHOST)
757 priv->ule_skb->pkt_type = PACKET_HOST; */
758 dev->stats.rx_packets++;
759 dev->stats.rx_bytes += priv->ule_skb->len;
760 netif_rx(priv->ule_skb);
761 }
762 sndu_done:
763 /* Prepare for next SNDU. */
764 reset_ule(priv);
765 }
766
767 /* More data in current TS (look at the bytes following the CRC32)? */
768 if (ts_remain >= 2 && *((unsigned short *)from_where) != 0xFFFF) {
769 /* Next ULE SNDU starts right there. */
770 new_ts = 0;
771 priv->ule_skb = NULL;
772 priv->ule_sndu_type_1 = 0;
773 priv->ule_sndu_len = 0;
774 // printk(KERN_WARNING "More data in current TS: [%#x %#x %#x %#x]\n",
775 // *(from_where + 0), *(from_where + 1),
776 // *(from_where + 2), *(from_where + 3));
777 // printk(KERN_WARNING "ts @ %p, stopped @ %p:\n", ts, from_where + 0);
778 // hexdump(ts, 188);
779 } else {
780 new_ts = 1;
781 ts += TS_SZ;
782 priv->ts_count++;
783 if (priv->ule_skb == NULL) {
784 priv->need_pusi = 1;
785 priv->ule_sndu_type_1 = 0;
786 priv->ule_sndu_len = 0;
787 }
788 }
789 } /* for all available TS cells */
790}
791
792static int dvb_net_ts_callback(const u8 *buffer1, size_t buffer1_len,
793 const u8 *buffer2, size_t buffer2_len,
794 struct dmx_ts_feed *feed, enum dmx_success success)
795{
796 struct net_device *dev = feed->priv;
797
798 if (buffer2)
799 printk(KERN_WARNING "buffer2 not NULL: %p.\n", buffer2);
800 if (buffer1_len > 32768)
801 printk(KERN_WARNING "length > 32k: %zu.\n", buffer1_len);
802 /* printk("TS callback: %u bytes, %u TS cells @ %p.\n",
803 buffer1_len, buffer1_len / TS_SZ, buffer1); */
804 dvb_net_ule(dev, buffer1, buffer1_len);
805 return 0;
806}
807
808
809static void dvb_net_sec(struct net_device *dev,
810 const u8 *pkt, int pkt_len)
811{
812 u8 *eth;
813 struct sk_buff *skb;
814 struct net_device_stats *stats = &dev->stats;
815 int snap = 0;
816
817 /* note: pkt_len includes a 32bit checksum */
818 if (pkt_len < 16) {
819 printk("%s: IP/MPE packet length = %d too small.\n",
820 dev->name, pkt_len);
821 stats->rx_errors++;
822 stats->rx_length_errors++;
823 return;
824 }
825/* it seems some ISPs manage to screw up here, so we have to
826 * relax the error checks... */
827#if 0
828 if ((pkt[5] & 0xfd) != 0xc1) {
829 /* drop scrambled or broken packets */
830#else
831 if ((pkt[5] & 0x3c) != 0x00) {
832 /* drop scrambled */
833#endif
834 stats->rx_errors++;
835 stats->rx_crc_errors++;
836 return;
837 }
838 if (pkt[5] & 0x02) {
839 /* handle LLC/SNAP, see rfc-1042 */
840 if (pkt_len < 24 || memcmp(&pkt[12], "\xaa\xaa\x03\0\0\0", 6)) {
841 stats->rx_dropped++;
842 return;
843 }
844 snap = 8;
845 }
846 if (pkt[7]) {
847 /* FIXME: assemble datagram from multiple sections */
848 stats->rx_errors++;
849 stats->rx_frame_errors++;
850 return;
851 }
852
853 /* we have 14 byte ethernet header (ip header follows);
854 * 12 byte MPE header; 4 byte checksum; + 2 byte alignment, 8 byte LLC/SNAP
855 */
856 if (!(skb = dev_alloc_skb(pkt_len - 4 - 12 + 14 + 2 - snap))) {
857 //printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
858 stats->rx_dropped++;
859 return;
860 }
861 skb_reserve(skb, 2); /* longword align L3 header */
862 skb->dev = dev;
863
864 /* copy L3 payload */
865 eth = (u8 *) skb_put(skb, pkt_len - 12 - 4 + 14 - snap);
866 memcpy(eth + 14, pkt + 12 + snap, pkt_len - 12 - 4 - snap);
867
868 /* create ethernet header: */
869 eth[0]=pkt[0x0b];
870 eth[1]=pkt[0x0a];
871 eth[2]=pkt[0x09];
872 eth[3]=pkt[0x08];
873 eth[4]=pkt[0x04];
874 eth[5]=pkt[0x03];
875
876 eth[6]=eth[7]=eth[8]=eth[9]=eth[10]=eth[11]=0;
877
878 if (snap) {
879 eth[12] = pkt[18];
880 eth[13] = pkt[19];
881 } else {
882 /* protocol numbers are from rfc-1700 or
883 * http://www.iana.org/assignments/ethernet-numbers
884 */
885 if (pkt[12] >> 4 == 6) { /* version field from IP header */
886 eth[12] = 0x86; /* IPv6 */
887 eth[13] = 0xdd;
888 } else {
889 eth[12] = 0x08; /* IPv4 */
890 eth[13] = 0x00;
891 }
892 }
893
894 skb->protocol = dvb_net_eth_type_trans(skb, dev);
895
896 stats->rx_packets++;
897 stats->rx_bytes+=skb->len;
898 netif_rx(skb);
899}
900
901static int dvb_net_sec_callback(const u8 *buffer1, size_t buffer1_len,
902 const u8 *buffer2, size_t buffer2_len,
903 struct dmx_section_filter *filter,
904 enum dmx_success success)
905{
906 struct net_device *dev = filter->priv;
907
908 /**
909 * we rely on the DVB API definition where exactly one complete
910 * section is delivered in buffer1
911 */
912 dvb_net_sec (dev, buffer1, buffer1_len);
913 return 0;
914}
915
916static int dvb_net_tx(struct sk_buff *skb, struct net_device *dev)
917{
918 dev_kfree_skb(skb);
919 return NETDEV_TX_OK;
920}
921
922static u8 mask_normal[6]={0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
923static u8 mask_allmulti[6]={0xff, 0xff, 0xff, 0x00, 0x00, 0x00};
924static u8 mac_allmulti[6]={0x01, 0x00, 0x5e, 0x00, 0x00, 0x00};
925static u8 mask_promisc[6]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
926
927static int dvb_net_filter_sec_set(struct net_device *dev,
928 struct dmx_section_filter **secfilter,
929 u8 *mac, u8 *mac_mask)
930{
931 struct dvb_net_priv *priv = netdev_priv(dev);
932 int ret;
933
934 *secfilter=NULL;
935 ret = priv->secfeed->allocate_filter(priv->secfeed, secfilter);
936 if (ret<0) {
937 printk("%s: could not get filter\n", dev->name);
938 return ret;
939 }
940
941 (*secfilter)->priv=(void *) dev;
942
943 memset((*secfilter)->filter_value, 0x00, DMX_MAX_FILTER_SIZE);
944 memset((*secfilter)->filter_mask, 0x00, DMX_MAX_FILTER_SIZE);
945 memset((*secfilter)->filter_mode, 0xff, DMX_MAX_FILTER_SIZE);
946
947 (*secfilter)->filter_value[0]=0x3e;
948 (*secfilter)->filter_value[3]=mac[5];
949 (*secfilter)->filter_value[4]=mac[4];
950 (*secfilter)->filter_value[8]=mac[3];
951 (*secfilter)->filter_value[9]=mac[2];
952 (*secfilter)->filter_value[10]=mac[1];
953 (*secfilter)->filter_value[11]=mac[0];
954
955 (*secfilter)->filter_mask[0] = 0xff;
956 (*secfilter)->filter_mask[3] = mac_mask[5];
957 (*secfilter)->filter_mask[4] = mac_mask[4];
958 (*secfilter)->filter_mask[8] = mac_mask[3];
959 (*secfilter)->filter_mask[9] = mac_mask[2];
960 (*secfilter)->filter_mask[10] = mac_mask[1];
961 (*secfilter)->filter_mask[11]=mac_mask[0];
962
963 dprintk("%s: filter mac=%pM\n", dev->name, mac);
964 dprintk("%s: filter mask=%pM\n", dev->name, mac_mask);
965
966 return 0;
967}
968
969static int dvb_net_feed_start(struct net_device *dev)
970{
971 int ret = 0, i;
972 struct dvb_net_priv *priv = netdev_priv(dev);
973 struct dmx_demux *demux = priv->demux;
974 unsigned char *mac = (unsigned char *) dev->dev_addr;
975
976 dprintk("%s: rx_mode %i\n", __func__, priv->rx_mode);
977 mutex_lock(&priv->mutex);
978 if (priv->tsfeed || priv->secfeed || priv->secfilter || priv->multi_secfilter[0])
979 printk("%s: BUG %d\n", __func__, __LINE__);
980
981 priv->secfeed=NULL;
982 priv->secfilter=NULL;
983 priv->tsfeed = NULL;
984
985 if (priv->feedtype == DVB_NET_FEEDTYPE_MPE) {
986 dprintk("%s: alloc secfeed\n", __func__);
987 ret=demux->allocate_section_feed(demux, &priv->secfeed,
988 dvb_net_sec_callback);
989 if (ret<0) {
990 printk("%s: could not allocate section feed\n", dev->name);
991 goto error;
992 }
993
994 ret = priv->secfeed->set(priv->secfeed, priv->pid, 32768, 1);
995
996 if (ret<0) {
997 printk("%s: could not set section feed\n", dev->name);
998 priv->demux->release_section_feed(priv->demux, priv->secfeed);
999 priv->secfeed=NULL;
1000 goto error;
1001 }
1002
1003 if (priv->rx_mode != RX_MODE_PROMISC) {
1004 dprintk("%s: set secfilter\n", __func__);
1005 dvb_net_filter_sec_set(dev, &priv->secfilter, mac, mask_normal);
1006 }
1007
1008 switch (priv->rx_mode) {
1009 case RX_MODE_MULTI:
1010 for (i = 0; i < priv->multi_num; i++) {
1011 dprintk("%s: set multi_secfilter[%d]\n", __func__, i);
1012 dvb_net_filter_sec_set(dev, &priv->multi_secfilter[i],
1013 priv->multi_macs[i], mask_normal);
1014 }
1015 break;
1016 case RX_MODE_ALL_MULTI:
1017 priv->multi_num=1;
1018 dprintk("%s: set multi_secfilter[0]\n", __func__);
1019 dvb_net_filter_sec_set(dev, &priv->multi_secfilter[0],
1020 mac_allmulti, mask_allmulti);
1021 break;
1022 case RX_MODE_PROMISC:
1023 priv->multi_num=0;
1024 dprintk("%s: set secfilter\n", __func__);
1025 dvb_net_filter_sec_set(dev, &priv->secfilter, mac, mask_promisc);
1026 break;
1027 }
1028
1029 dprintk("%s: start filtering\n", __func__);
1030 priv->secfeed->start_filtering(priv->secfeed);
1031 } else if (priv->feedtype == DVB_NET_FEEDTYPE_ULE) {
1032 struct timespec timeout = { 0, 10000000 }; // 10 msec
1033
1034 /* we have payloads encapsulated in TS */
1035 dprintk("%s: alloc tsfeed\n", __func__);
1036 ret = demux->allocate_ts_feed(demux, &priv->tsfeed, dvb_net_ts_callback);
1037 if (ret < 0) {
1038 printk("%s: could not allocate ts feed\n", dev->name);
1039 goto error;
1040 }
1041
1042 /* Set netdevice pointer for ts decaps callback. */
1043 priv->tsfeed->priv = (void *)dev;
1044 ret = priv->tsfeed->set(priv->tsfeed,
1045 priv->pid, /* pid */
1046 TS_PACKET, /* type */
1047 DMX_TS_PES_OTHER, /* pes type */
1048 32768, /* circular buffer size */
1049 timeout /* timeout */
1050 );
1051
1052 if (ret < 0) {
1053 printk("%s: could not set ts feed\n", dev->name);
1054 priv->demux->release_ts_feed(priv->demux, priv->tsfeed);
1055 priv->tsfeed = NULL;
1056 goto error;
1057 }
1058
1059 dprintk("%s: start filtering\n", __func__);
1060 priv->tsfeed->start_filtering(priv->tsfeed);
1061 } else
1062 ret = -EINVAL;
1063
1064error:
1065 mutex_unlock(&priv->mutex);
1066 return ret;
1067}
1068
1069static int dvb_net_feed_stop(struct net_device *dev)
1070{
1071 struct dvb_net_priv *priv = netdev_priv(dev);
1072 int i, ret = 0;
1073
1074 dprintk("%s\n", __func__);
1075 mutex_lock(&priv->mutex);
1076 if (priv->feedtype == DVB_NET_FEEDTYPE_MPE) {
1077 if (priv->secfeed) {
1078 if (priv->secfeed->is_filtering) {
1079 dprintk("%s: stop secfeed\n", __func__);
1080 priv->secfeed->stop_filtering(priv->secfeed);
1081 }
1082
1083 if (priv->secfilter) {
1084 dprintk("%s: release secfilter\n", __func__);
1085 priv->secfeed->release_filter(priv->secfeed,
1086 priv->secfilter);
1087 priv->secfilter=NULL;
1088 }
1089
1090 for (i=0; i<priv->multi_num; i++) {
1091 if (priv->multi_secfilter[i]) {
1092 dprintk("%s: release multi_filter[%d]\n",
1093 __func__, i);
1094 priv->secfeed->release_filter(priv->secfeed,
1095 priv->multi_secfilter[i]);
1096 priv->multi_secfilter[i] = NULL;
1097 }
1098 }
1099
1100 priv->demux->release_section_feed(priv->demux, priv->secfeed);
1101 priv->secfeed = NULL;
1102 } else
1103 printk("%s: no feed to stop\n", dev->name);
1104 } else if (priv->feedtype == DVB_NET_FEEDTYPE_ULE) {
1105 if (priv->tsfeed) {
1106 if (priv->tsfeed->is_filtering) {
1107 dprintk("%s: stop tsfeed\n", __func__);
1108 priv->tsfeed->stop_filtering(priv->tsfeed);
1109 }
1110 priv->demux->release_ts_feed(priv->demux, priv->tsfeed);
1111 priv->tsfeed = NULL;
1112 }
1113 else
1114 printk("%s: no ts feed to stop\n", dev->name);
1115 } else
1116 ret = -EINVAL;
1117 mutex_unlock(&priv->mutex);
1118 return ret;
1119}
1120
1121
1122static int dvb_set_mc_filter(struct net_device *dev, unsigned char *addr)
1123{
1124 struct dvb_net_priv *priv = netdev_priv(dev);
1125
1126 if (priv->multi_num == DVB_NET_MULTICAST_MAX)
1127 return -ENOMEM;
1128
1129 memcpy(priv->multi_macs[priv->multi_num], addr, ETH_ALEN);
1130
1131 priv->multi_num++;
1132 return 0;
1133}
1134
1135
1136static void wq_set_multicast_list (struct work_struct *work)
1137{
1138 struct dvb_net_priv *priv =
1139 container_of(work, struct dvb_net_priv, set_multicast_list_wq);
1140 struct net_device *dev = priv->net;
1141
1142 dvb_net_feed_stop(dev);
1143 priv->rx_mode = RX_MODE_UNI;
1144 netif_addr_lock_bh(dev);
1145
1146 if (dev->flags & IFF_PROMISC) {
1147 dprintk("%s: promiscuous mode\n", dev->name);
1148 priv->rx_mode = RX_MODE_PROMISC;
1149 } else if ((dev->flags & IFF_ALLMULTI)) {
1150 dprintk("%s: allmulti mode\n", dev->name);
1151 priv->rx_mode = RX_MODE_ALL_MULTI;
1152 } else if (!netdev_mc_empty(dev)) {
1153 struct netdev_hw_addr *ha;
1154
1155 dprintk("%s: set_mc_list, %d entries\n",
1156 dev->name, netdev_mc_count(dev));
1157
1158 priv->rx_mode = RX_MODE_MULTI;
1159 priv->multi_num = 0;
1160
1161 netdev_for_each_mc_addr(ha, dev)
1162 dvb_set_mc_filter(dev, ha->addr);
1163 }
1164
1165 netif_addr_unlock_bh(dev);
1166 dvb_net_feed_start(dev);
1167}
1168
1169
1170static void dvb_net_set_multicast_list (struct net_device *dev)
1171{
1172 struct dvb_net_priv *priv = netdev_priv(dev);
1173 schedule_work(&priv->set_multicast_list_wq);
1174}
1175
1176
1177static void wq_restart_net_feed (struct work_struct *work)
1178{
1179 struct dvb_net_priv *priv =
1180 container_of(work, struct dvb_net_priv, restart_net_feed_wq);
1181 struct net_device *dev = priv->net;
1182
1183 if (netif_running(dev)) {
1184 dvb_net_feed_stop(dev);
1185 dvb_net_feed_start(dev);
1186 }
1187}
1188
1189
1190static int dvb_net_set_mac (struct net_device *dev, void *p)
1191{
1192 struct dvb_net_priv *priv = netdev_priv(dev);
1193 struct sockaddr *addr=p;
1194
1195 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
1196
1197 if (netif_running(dev))
1198 schedule_work(&priv->restart_net_feed_wq);
1199
1200 return 0;
1201}
1202
1203
1204static int dvb_net_open(struct net_device *dev)
1205{
1206 struct dvb_net_priv *priv = netdev_priv(dev);
1207
1208 priv->in_use++;
1209 dvb_net_feed_start(dev);
1210 return 0;
1211}
1212
1213
1214static int dvb_net_stop(struct net_device *dev)
1215{
1216 struct dvb_net_priv *priv = netdev_priv(dev);
1217
1218 priv->in_use--;
1219 return dvb_net_feed_stop(dev);
1220}
1221
1222static const struct header_ops dvb_header_ops = {
1223 .create = eth_header,
1224 .parse = eth_header_parse,
1225 .rebuild = eth_rebuild_header,
1226};
1227
1228
1229static const struct net_device_ops dvb_netdev_ops = {
1230 .ndo_open = dvb_net_open,
1231 .ndo_stop = dvb_net_stop,
1232 .ndo_start_xmit = dvb_net_tx,
1233 .ndo_set_multicast_list = dvb_net_set_multicast_list,
1234 .ndo_set_mac_address = dvb_net_set_mac,
1235 .ndo_change_mtu = eth_change_mtu,
1236 .ndo_validate_addr = eth_validate_addr,
1237};
1238
1239static void dvb_net_setup(struct net_device *dev)
1240{
1241 ether_setup(dev);
1242
1243 dev->header_ops = &dvb_header_ops;
1244 dev->netdev_ops = &dvb_netdev_ops;
1245 dev->mtu = 4096;
1246
1247 dev->flags |= IFF_NOARP;
1248}
1249
1250static int get_if(struct dvb_net *dvbnet)
1251{
1252 int i;
1253
1254 for (i=0; i<DVB_NET_DEVICES_MAX; i++)
1255 if (!dvbnet->state[i])
1256 break;
1257
1258 if (i == DVB_NET_DEVICES_MAX)
1259 return -1;
1260
1261 dvbnet->state[i]=1;
1262 return i;
1263}
1264
1265static int dvb_net_add_if(struct dvb_net *dvbnet, u16 pid, u8 feedtype)
1266{
1267 struct net_device *net;
1268 struct dvb_net_priv *priv;
1269 int result;
1270 int if_num;
1271
1272 if (feedtype != DVB_NET_FEEDTYPE_MPE && feedtype != DVB_NET_FEEDTYPE_ULE)
1273 return -EINVAL;
1274 if ((if_num = get_if(dvbnet)) < 0)
1275 return -EINVAL;
1276
1277 net = alloc_netdev(sizeof(struct dvb_net_priv), "dvb", dvb_net_setup);
1278 if (!net)
1279 return -ENOMEM;
1280
1281 if (dvbnet->dvbdev->id)
1282 snprintf(net->name, IFNAMSIZ, "dvb%d%u%d",
1283 dvbnet->dvbdev->adapter->num, dvbnet->dvbdev->id, if_num);
1284 else
1285 /* compatibility fix to keep dvb0_0 format */
1286 snprintf(net->name, IFNAMSIZ, "dvb%d_%d",
1287 dvbnet->dvbdev->adapter->num, if_num);
1288
1289 net->addr_len = 6;
1290 memcpy(net->dev_addr, dvbnet->dvbdev->adapter->proposed_mac, 6);
1291
1292 dvbnet->device[if_num] = net;
1293
1294 priv = netdev_priv(net);
1295 priv->net = net;
1296 priv->demux = dvbnet->demux;
1297 priv->pid = pid;
1298 priv->rx_mode = RX_MODE_UNI;
1299 priv->need_pusi = 1;
1300 priv->tscc = 0;
1301 priv->feedtype = feedtype;
1302 reset_ule(priv);
1303
1304 INIT_WORK(&priv->set_multicast_list_wq, wq_set_multicast_list);
1305 INIT_WORK(&priv->restart_net_feed_wq, wq_restart_net_feed);
1306 mutex_init(&priv->mutex);
1307
1308 net->base_addr = pid;
1309
1310 if ((result = register_netdev(net)) < 0) {
1311 dvbnet->device[if_num] = NULL;
1312 free_netdev(net);
1313 return result;
1314 }
1315 printk("dvb_net: created network interface %s\n", net->name);
1316
1317 return if_num;
1318}
1319
1320static int dvb_net_remove_if(struct dvb_net *dvbnet, unsigned long num)
1321{
1322 struct net_device *net = dvbnet->device[num];
1323 struct dvb_net_priv *priv;
1324
1325 if (!dvbnet->state[num])
1326 return -EINVAL;
1327 priv = netdev_priv(net);
1328 if (priv->in_use)
1329 return -EBUSY;
1330
1331 dvb_net_stop(net);
1332 flush_work_sync(&priv->set_multicast_list_wq);
1333 flush_work_sync(&priv->restart_net_feed_wq);
1334 printk("dvb_net: removed network interface %s\n", net->name);
1335 unregister_netdev(net);
1336 dvbnet->state[num]=0;
1337 dvbnet->device[num] = NULL;
1338 free_netdev(net);
1339
1340 return 0;
1341}
1342
1343static int dvb_net_do_ioctl(struct file *file,
1344 unsigned int cmd, void *parg)
1345{
1346 struct dvb_device *dvbdev = file->private_data;
1347 struct dvb_net *dvbnet = dvbdev->priv;
1348
1349 if (((file->f_flags&O_ACCMODE)==O_RDONLY))
1350 return -EPERM;
1351
1352 switch (cmd) {
1353 case NET_ADD_IF:
1354 {
1355 struct dvb_net_if *dvbnetif = parg;
1356 int result;
1357
1358 if (!capable(CAP_SYS_ADMIN))
1359 return -EPERM;
1360
1361 if (!try_module_get(dvbdev->adapter->module))
1362 return -EPERM;
1363
1364 result=dvb_net_add_if(dvbnet, dvbnetif->pid, dvbnetif->feedtype);
1365 if (result<0) {
1366 module_put(dvbdev->adapter->module);
1367 return result;
1368 }
1369 dvbnetif->if_num=result;
1370 break;
1371 }
1372 case NET_GET_IF:
1373 {
1374 struct net_device *netdev;
1375 struct dvb_net_priv *priv_data;
1376 struct dvb_net_if *dvbnetif = parg;
1377
1378 if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX ||
1379 !dvbnet->state[dvbnetif->if_num])
1380 return -EINVAL;
1381
1382 netdev = dvbnet->device[dvbnetif->if_num];
1383
1384 priv_data = netdev_priv(netdev);
1385 dvbnetif->pid=priv_data->pid;
1386 dvbnetif->feedtype=priv_data->feedtype;
1387 break;
1388 }
1389 case NET_REMOVE_IF:
1390 {
1391 int ret;
1392
1393 if (!capable(CAP_SYS_ADMIN))
1394 return -EPERM;
1395 if ((unsigned long) parg >= DVB_NET_DEVICES_MAX)
1396 return -EINVAL;
1397 ret = dvb_net_remove_if(dvbnet, (unsigned long) parg);
1398 if (!ret)
1399 module_put(dvbdev->adapter->module);
1400 return ret;
1401 }
1402
1403 /* binary compatibility cruft */
1404 case __NET_ADD_IF_OLD:
1405 {
1406 struct __dvb_net_if_old *dvbnetif = parg;
1407 int result;
1408
1409 if (!capable(CAP_SYS_ADMIN))
1410 return -EPERM;
1411
1412 if (!try_module_get(dvbdev->adapter->module))
1413 return -EPERM;
1414
1415 result=dvb_net_add_if(dvbnet, dvbnetif->pid, DVB_NET_FEEDTYPE_MPE);
1416 if (result<0) {
1417 module_put(dvbdev->adapter->module);
1418 return result;
1419 }
1420 dvbnetif->if_num=result;
1421 break;
1422 }
1423 case __NET_GET_IF_OLD:
1424 {
1425 struct net_device *netdev;
1426 struct dvb_net_priv *priv_data;
1427 struct __dvb_net_if_old *dvbnetif = parg;
1428
1429 if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX ||
1430 !dvbnet->state[dvbnetif->if_num])
1431 return -EINVAL;
1432
1433 netdev = dvbnet->device[dvbnetif->if_num];
1434
1435 priv_data = netdev_priv(netdev);
1436 dvbnetif->pid=priv_data->pid;
1437 break;
1438 }
1439 default:
1440 return -ENOTTY;
1441 }
1442 return 0;
1443}
1444
1445static long dvb_net_ioctl(struct file *file,
1446 unsigned int cmd, unsigned long arg)
1447{
1448 return dvb_usercopy(file, cmd, arg, dvb_net_do_ioctl);
1449}
1450
1451static int dvb_net_close(struct inode *inode, struct file *file)
1452{
1453 struct dvb_device *dvbdev = file->private_data;
1454 struct dvb_net *dvbnet = dvbdev->priv;
1455
1456 dvb_generic_release(inode, file);
1457
1458 if(dvbdev->users == 1 && dvbnet->exit == 1) {
1459 fops_put(file->f_op);
1460 file->f_op = NULL;
1461 wake_up(&dvbdev->wait_queue);
1462 }
1463 return 0;
1464}
1465
1466
1467static const struct file_operations dvb_net_fops = {
1468 .owner = THIS_MODULE,
1469 .unlocked_ioctl = dvb_net_ioctl,
1470 .open = dvb_generic_open,
1471 .release = dvb_net_close,
1472 .llseek = noop_llseek,
1473};
1474
1475static struct dvb_device dvbdev_net = {
1476 .priv = NULL,
1477 .users = 1,
1478 .writers = 1,
1479 .fops = &dvb_net_fops,
1480};
1481
1482
1483void dvb_net_release (struct dvb_net *dvbnet)
1484{
1485 int i;
1486
1487 dvbnet->exit = 1;
1488 if (dvbnet->dvbdev->users < 1)
1489 wait_event(dvbnet->dvbdev->wait_queue,
1490 dvbnet->dvbdev->users==1);
1491
1492 dvb_unregister_device(dvbnet->dvbdev);
1493
1494 for (i=0; i<DVB_NET_DEVICES_MAX; i++) {
1495 if (!dvbnet->state[i])
1496 continue;
1497 dvb_net_remove_if(dvbnet, i);
1498 }
1499}
1500EXPORT_SYMBOL(dvb_net_release);
1501
1502
1503int dvb_net_init (struct dvb_adapter *adap, struct dvb_net *dvbnet,
1504 struct dmx_demux *dmx)
1505{
1506 int i;
1507
1508 dvbnet->demux = dmx;
1509
1510 for (i=0; i<DVB_NET_DEVICES_MAX; i++)
1511 dvbnet->state[i] = 0;
1512
1513 dvb_register_device (adap, &dvbnet->dvbdev, &dvbdev_net,
1514 dvbnet, DVB_DEVICE_NET);
1515
1516 return 0;
1517}
1518EXPORT_SYMBOL(dvb_net_init);
diff --git a/drivers/media/dvb/dvb-core/dvb_net.h b/drivers/media/dvb/dvb-core/dvb_net.h
new file mode 100644
index 00000000000..1e53acd50cf
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_net.h
@@ -0,0 +1,66 @@
1/*
2 * dvb_net.h
3 *
4 * Copyright (C) 2001 Ralph Metzler for convergence integrated media GmbH
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either version 2.1
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 *
20 */
21
22#ifndef _DVB_NET_H_
23#define _DVB_NET_H_
24
25#include <linux/module.h>
26#include <linux/netdevice.h>
27#include <linux/inetdevice.h>
28#include <linux/etherdevice.h>
29#include <linux/skbuff.h>
30
31#include "dvbdev.h"
32
33#define DVB_NET_DEVICES_MAX 10
34
35#ifdef CONFIG_DVB_NET
36
37struct dvb_net {
38 struct dvb_device *dvbdev;
39 struct net_device *device[DVB_NET_DEVICES_MAX];
40 int state[DVB_NET_DEVICES_MAX];
41 unsigned int exit:1;
42 struct dmx_demux *demux;
43};
44
45void dvb_net_release(struct dvb_net *);
46int dvb_net_init(struct dvb_adapter *, struct dvb_net *, struct dmx_demux *);
47
48#else
49
50struct dvb_net {
51 struct dvb_device *dvbdev;
52};
53
54static inline void dvb_net_release(struct dvb_net *dvbnet)
55{
56}
57
58static inline int dvb_net_init(struct dvb_adapter *adap,
59 struct dvb_net *dvbnet, struct dmx_demux *dmx)
60{
61 return 0;
62}
63
64#endif /* ifdef CONFIG_DVB_NET */
65
66#endif
diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
new file mode 100644
index 00000000000..a5712cd7c65
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
@@ -0,0 +1,299 @@
1/*
2 *
3 * dvb_ringbuffer.c: ring buffer implementation for the dvb driver
4 *
5 * Copyright (C) 2003 Oliver Endriss
6 * Copyright (C) 2004 Andrew de Quincey
7 *
8 * based on code originally found in av7110.c & dvb_ci.c:
9 * Copyright (C) 1999-2003 Ralph Metzler
10 * & Marcus Metzler for convergence integrated media GmbH
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 2.1
15 * of the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Lesser General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 */
26
27
28
29#include <linux/errno.h>
30#include <linux/kernel.h>
31#include <linux/module.h>
32#include <linux/sched.h>
33#include <linux/string.h>
34#include <asm/uaccess.h>
35
36#include "dvb_ringbuffer.h"
37
38#define PKT_READY 0
39#define PKT_DISPOSED 1
40
41
42void dvb_ringbuffer_init(struct dvb_ringbuffer *rbuf, void *data, size_t len)
43{
44 rbuf->pread=rbuf->pwrite=0;
45 rbuf->data=data;
46 rbuf->size=len;
47 rbuf->error=0;
48
49 init_waitqueue_head(&rbuf->queue);
50
51 spin_lock_init(&(rbuf->lock));
52}
53
54
55
56int dvb_ringbuffer_empty(struct dvb_ringbuffer *rbuf)
57{
58 return (rbuf->pread==rbuf->pwrite);
59}
60
61
62
63ssize_t dvb_ringbuffer_free(struct dvb_ringbuffer *rbuf)
64{
65 ssize_t free;
66
67 free = rbuf->pread - rbuf->pwrite;
68 if (free <= 0)
69 free += rbuf->size;
70 return free-1;
71}
72
73
74
75ssize_t dvb_ringbuffer_avail(struct dvb_ringbuffer *rbuf)
76{
77 ssize_t avail;
78
79 avail = rbuf->pwrite - rbuf->pread;
80 if (avail < 0)
81 avail += rbuf->size;
82 return avail;
83}
84
85
86
87void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf)
88{
89 rbuf->pread = rbuf->pwrite;
90 rbuf->error = 0;
91}
92EXPORT_SYMBOL(dvb_ringbuffer_flush);
93
94void dvb_ringbuffer_reset(struct dvb_ringbuffer *rbuf)
95{
96 rbuf->pread = rbuf->pwrite = 0;
97 rbuf->error = 0;
98}
99
100void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf)
101{
102 unsigned long flags;
103
104 spin_lock_irqsave(&rbuf->lock, flags);
105 dvb_ringbuffer_flush(rbuf);
106 spin_unlock_irqrestore(&rbuf->lock, flags);
107
108 wake_up(&rbuf->queue);
109}
110
111ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf, u8 __user *buf, size_t len)
112{
113 size_t todo = len;
114 size_t split;
115
116 split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0;
117 if (split > 0) {
118 if (copy_to_user(buf, rbuf->data+rbuf->pread, split))
119 return -EFAULT;
120 buf += split;
121 todo -= split;
122 rbuf->pread = 0;
123 }
124 if (copy_to_user(buf, rbuf->data+rbuf->pread, todo))
125 return -EFAULT;
126
127 rbuf->pread = (rbuf->pread + todo) % rbuf->size;
128
129 return len;
130}
131
132void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len)
133{
134 size_t todo = len;
135 size_t split;
136
137 split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0;
138 if (split > 0) {
139 memcpy(buf, rbuf->data+rbuf->pread, split);
140 buf += split;
141 todo -= split;
142 rbuf->pread = 0;
143 }
144 memcpy(buf, rbuf->data+rbuf->pread, todo);
145
146 rbuf->pread = (rbuf->pread + todo) % rbuf->size;
147}
148
149
150ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, size_t len)
151{
152 size_t todo = len;
153 size_t split;
154
155 split = (rbuf->pwrite + len > rbuf->size) ? rbuf->size - rbuf->pwrite : 0;
156
157 if (split > 0) {
158 memcpy(rbuf->data+rbuf->pwrite, buf, split);
159 buf += split;
160 todo -= split;
161 rbuf->pwrite = 0;
162 }
163 memcpy(rbuf->data+rbuf->pwrite, buf, todo);
164 rbuf->pwrite = (rbuf->pwrite + todo) % rbuf->size;
165
166 return len;
167}
168
169ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, size_t len)
170{
171 int status;
172 ssize_t oldpwrite = rbuf->pwrite;
173
174 DVB_RINGBUFFER_WRITE_BYTE(rbuf, len >> 8);
175 DVB_RINGBUFFER_WRITE_BYTE(rbuf, len & 0xff);
176 DVB_RINGBUFFER_WRITE_BYTE(rbuf, PKT_READY);
177 status = dvb_ringbuffer_write(rbuf, buf, len);
178
179 if (status < 0) rbuf->pwrite = oldpwrite;
180 return status;
181}
182
183ssize_t dvb_ringbuffer_pkt_read_user(struct dvb_ringbuffer *rbuf, size_t idx,
184 int offset, u8 __user *buf, size_t len)
185{
186 size_t todo;
187 size_t split;
188 size_t pktlen;
189
190 pktlen = rbuf->data[idx] << 8;
191 pktlen |= rbuf->data[(idx + 1) % rbuf->size];
192 if (offset > pktlen) return -EINVAL;
193 if ((offset + len) > pktlen) len = pktlen - offset;
194
195 idx = (idx + DVB_RINGBUFFER_PKTHDRSIZE + offset) % rbuf->size;
196 todo = len;
197 split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0;
198 if (split > 0) {
199 if (copy_to_user(buf, rbuf->data+idx, split))
200 return -EFAULT;
201 buf += split;
202 todo -= split;
203 idx = 0;
204 }
205 if (copy_to_user(buf, rbuf->data+idx, todo))
206 return -EFAULT;
207
208 return len;
209}
210
211ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx,
212 int offset, u8* buf, size_t len)
213{
214 size_t todo;
215 size_t split;
216 size_t pktlen;
217
218 pktlen = rbuf->data[idx] << 8;
219 pktlen |= rbuf->data[(idx + 1) % rbuf->size];
220 if (offset > pktlen) return -EINVAL;
221 if ((offset + len) > pktlen) len = pktlen - offset;
222
223 idx = (idx + DVB_RINGBUFFER_PKTHDRSIZE + offset) % rbuf->size;
224 todo = len;
225 split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0;
226 if (split > 0) {
227 memcpy(buf, rbuf->data+idx, split);
228 buf += split;
229 todo -= split;
230 idx = 0;
231 }
232 memcpy(buf, rbuf->data+idx, todo);
233 return len;
234}
235
236void dvb_ringbuffer_pkt_dispose(struct dvb_ringbuffer *rbuf, size_t idx)
237{
238 size_t pktlen;
239
240 rbuf->data[(idx + 2) % rbuf->size] = PKT_DISPOSED;
241
242 // clean up disposed packets
243 while(dvb_ringbuffer_avail(rbuf) > DVB_RINGBUFFER_PKTHDRSIZE) {
244 if (DVB_RINGBUFFER_PEEK(rbuf, 2) == PKT_DISPOSED) {
245 pktlen = DVB_RINGBUFFER_PEEK(rbuf, 0) << 8;
246 pktlen |= DVB_RINGBUFFER_PEEK(rbuf, 1);
247 DVB_RINGBUFFER_SKIP(rbuf, pktlen + DVB_RINGBUFFER_PKTHDRSIZE);
248 } else {
249 // first packet is not disposed, so we stop cleaning now
250 break;
251 }
252 }
253}
254
255ssize_t dvb_ringbuffer_pkt_next(struct dvb_ringbuffer *rbuf, size_t idx, size_t* pktlen)
256{
257 int consumed;
258 int curpktlen;
259 int curpktstatus;
260
261 if (idx == -1) {
262 idx = rbuf->pread;
263 } else {
264 curpktlen = rbuf->data[idx] << 8;
265 curpktlen |= rbuf->data[(idx + 1) % rbuf->size];
266 idx = (idx + curpktlen + DVB_RINGBUFFER_PKTHDRSIZE) % rbuf->size;
267 }
268
269 consumed = (idx - rbuf->pread) % rbuf->size;
270
271 while((dvb_ringbuffer_avail(rbuf) - consumed) > DVB_RINGBUFFER_PKTHDRSIZE) {
272
273 curpktlen = rbuf->data[idx] << 8;
274 curpktlen |= rbuf->data[(idx + 1) % rbuf->size];
275 curpktstatus = rbuf->data[(idx + 2) % rbuf->size];
276
277 if (curpktstatus == PKT_READY) {
278 *pktlen = curpktlen;
279 return idx;
280 }
281
282 consumed += curpktlen + DVB_RINGBUFFER_PKTHDRSIZE;
283 idx = (idx + curpktlen + DVB_RINGBUFFER_PKTHDRSIZE) % rbuf->size;
284 }
285
286 // no packets available
287 return -1;
288}
289
290
291
292EXPORT_SYMBOL(dvb_ringbuffer_init);
293EXPORT_SYMBOL(dvb_ringbuffer_empty);
294EXPORT_SYMBOL(dvb_ringbuffer_free);
295EXPORT_SYMBOL(dvb_ringbuffer_avail);
296EXPORT_SYMBOL(dvb_ringbuffer_flush_spinlock_wakeup);
297EXPORT_SYMBOL(dvb_ringbuffer_read_user);
298EXPORT_SYMBOL(dvb_ringbuffer_read);
299EXPORT_SYMBOL(dvb_ringbuffer_write);
diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h
new file mode 100644
index 00000000000..41f04dae69b
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h
@@ -0,0 +1,186 @@
1/*
2 *
3 * dvb_ringbuffer.h: ring buffer implementation for the dvb driver
4 *
5 * Copyright (C) 2003 Oliver Endriss
6 * Copyright (C) 2004 Andrew de Quincey
7 *
8 * based on code originally found in av7110.c & dvb_ci.c:
9 * Copyright (C) 1999-2003 Ralph Metzler & Marcus Metzler
10 * for convergence integrated media GmbH
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 2.1
15 * of the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Lesser General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 */
26
27#ifndef _DVB_RINGBUFFER_H_
28#define _DVB_RINGBUFFER_H_
29
30#include <linux/spinlock.h>
31#include <linux/wait.h>
32
33struct dvb_ringbuffer {
34 u8 *data;
35 ssize_t size;
36 ssize_t pread;
37 ssize_t pwrite;
38 int error;
39
40 wait_queue_head_t queue;
41 spinlock_t lock;
42};
43
44#define DVB_RINGBUFFER_PKTHDRSIZE 3
45
46
47/*
48** Notes:
49** ------
50** (1) For performance reasons read and write routines don't check buffer sizes
51** and/or number of bytes free/available. This has to be done before these
52** routines are called. For example:
53**
54** *** write <buflen> bytes ***
55** free = dvb_ringbuffer_free(rbuf);
56** if (free >= buflen)
57** count = dvb_ringbuffer_write(rbuf, buffer, buflen);
58** else
59** ...
60**
61** *** read min. 1000, max. <bufsize> bytes ***
62** avail = dvb_ringbuffer_avail(rbuf);
63** if (avail >= 1000)
64** count = dvb_ringbuffer_read(rbuf, buffer, min(avail, bufsize));
65** else
66** ...
67**
68** (2) If there is exactly one reader and one writer, there is no need
69** to lock read or write operations.
70** Two or more readers must be locked against each other.
71** Flushing the buffer counts as a read operation.
72** Resetting the buffer counts as a read and write operation.
73** Two or more writers must be locked against each other.
74*/
75
76/* initialize ring buffer, lock and queue */
77extern void dvb_ringbuffer_init(struct dvb_ringbuffer *rbuf, void *data, size_t len);
78
79/* test whether buffer is empty */
80extern int dvb_ringbuffer_empty(struct dvb_ringbuffer *rbuf);
81
82/* return the number of free bytes in the buffer */
83extern ssize_t dvb_ringbuffer_free(struct dvb_ringbuffer *rbuf);
84
85/* return the number of bytes waiting in the buffer */
86extern ssize_t dvb_ringbuffer_avail(struct dvb_ringbuffer *rbuf);
87
88
89/*
90** Reset the read and write pointers to zero and flush the buffer
91** This counts as a read and write operation
92*/
93extern void dvb_ringbuffer_reset(struct dvb_ringbuffer *rbuf);
94
95
96/* read routines & macros */
97/* ---------------------- */
98/* flush buffer */
99extern void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf);
100
101/* flush buffer protected by spinlock and wake-up waiting task(s) */
102extern void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf);
103
104/* peek at byte <offs> in the buffer */
105#define DVB_RINGBUFFER_PEEK(rbuf,offs) \
106 (rbuf)->data[((rbuf)->pread+(offs))%(rbuf)->size]
107
108/* advance read ptr by <num> bytes */
109#define DVB_RINGBUFFER_SKIP(rbuf,num) \
110 (rbuf)->pread=((rbuf)->pread+(num))%(rbuf)->size
111
112/*
113** read <len> bytes from ring buffer into <buf>
114** <usermem> specifies whether <buf> resides in user space
115** returns number of bytes transferred or -EFAULT
116*/
117extern ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf,
118 u8 __user *buf, size_t len);
119extern void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf,
120 u8 *buf, size_t len);
121
122
123/* write routines & macros */
124/* ----------------------- */
125/* write single byte to ring buffer */
126#define DVB_RINGBUFFER_WRITE_BYTE(rbuf,byte) \
127 { (rbuf)->data[(rbuf)->pwrite]=(byte); \
128 (rbuf)->pwrite=((rbuf)->pwrite+1)%(rbuf)->size; }
129/*
130** write <len> bytes to ring buffer
131** <usermem> specifies whether <buf> resides in user space
132** returns number of bytes transferred or -EFAULT
133*/
134extern ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf,
135 size_t len);
136
137
138/**
139 * Write a packet into the ringbuffer.
140 *
141 * <rbuf> Ringbuffer to write to.
142 * <buf> Buffer to write.
143 * <len> Length of buffer (currently limited to 65535 bytes max).
144 * returns Number of bytes written, or -EFAULT, -ENOMEM, -EVINAL.
145 */
146extern ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf,
147 size_t len);
148
149/**
150 * Read from a packet in the ringbuffer. Note: unlike dvb_ringbuffer_read(), this
151 * does NOT update the read pointer in the ringbuffer. You must use
152 * dvb_ringbuffer_pkt_dispose() to mark a packet as no longer required.
153 *
154 * <rbuf> Ringbuffer concerned.
155 * <idx> Packet index as returned by dvb_ringbuffer_pkt_next().
156 * <offset> Offset into packet to read from.
157 * <buf> Destination buffer for data.
158 * <len> Size of destination buffer.
159 * <usermem> Set to 1 if <buf> is in userspace.
160 * returns Number of bytes read, or -EFAULT.
161 */
162extern ssize_t dvb_ringbuffer_pkt_read_user(struct dvb_ringbuffer *rbuf, size_t idx,
163 int offset, u8 __user *buf, size_t len);
164extern ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx,
165 int offset, u8 *buf, size_t len);
166
167/**
168 * Dispose of a packet in the ring buffer.
169 *
170 * <rbuf> Ring buffer concerned.
171 * <idx> Packet index as returned by dvb_ringbuffer_pkt_next().
172 */
173extern void dvb_ringbuffer_pkt_dispose(struct dvb_ringbuffer *rbuf, size_t idx);
174
175/**
176 * Get the index of the next packet in a ringbuffer.
177 *
178 * <rbuf> Ringbuffer concerned.
179 * <idx> Previous packet index, or -1 to return the first packet index.
180 * <pktlen> On success, will be updated to contain the length of the packet in bytes.
181 * returns Packet index (if >=0), or -1 if no packets available.
182 */
183extern ssize_t dvb_ringbuffer_pkt_next(struct dvb_ringbuffer *rbuf, size_t idx, size_t* pktlen);
184
185
186#endif /* _DVB_RINGBUFFER_H_ */
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
new file mode 100644
index 00000000000..f7328777595
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvbdev.c
@@ -0,0 +1,506 @@
1/*
2 * dvbdev.c
3 *
4 * Copyright (C) 2000 Ralph Metzler <ralph@convergence.de>
5 * & Marcus Metzler <marcus@convergence.de>
6 * for convergence integrated media GmbH
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 *
22 */
23
24#include <linux/types.h>
25#include <linux/errno.h>
26#include <linux/string.h>
27#include <linux/module.h>
28#include <linux/kernel.h>
29#include <linux/init.h>
30#include <linux/slab.h>
31#include <linux/device.h>
32#include <linux/fs.h>
33#include <linux/cdev.h>
34#include <linux/mutex.h>
35#include "dvbdev.h"
36
37static DEFINE_MUTEX(dvbdev_mutex);
38static int dvbdev_debug;
39
40module_param(dvbdev_debug, int, 0644);
41MODULE_PARM_DESC(dvbdev_debug, "Turn on/off device debugging (default:off).");
42
43#define dprintk if (dvbdev_debug) printk
44
45static LIST_HEAD(dvb_adapter_list);
46static DEFINE_MUTEX(dvbdev_register_lock);
47
48static const char * const dnames[] = {
49 "video", "audio", "sec", "frontend", "demux", "dvr", "ca",
50 "net", "osd"
51};
52
53#ifdef CONFIG_DVB_DYNAMIC_MINORS
54#define MAX_DVB_MINORS 256
55#define DVB_MAX_IDS MAX_DVB_MINORS
56#else
57#define DVB_MAX_IDS 4
58#define nums2minor(num,type,id) ((num << 6) | (id << 4) | type)
59#define MAX_DVB_MINORS (DVB_MAX_ADAPTERS*64)
60#endif
61
62static struct class *dvb_class;
63
64static struct dvb_device *dvb_minors[MAX_DVB_MINORS];
65static DECLARE_RWSEM(minor_rwsem);
66
67static int dvb_device_open(struct inode *inode, struct file *file)
68{
69 struct dvb_device *dvbdev;
70
71 mutex_lock(&dvbdev_mutex);
72 down_read(&minor_rwsem);
73 dvbdev = dvb_minors[iminor(inode)];
74
75 if (dvbdev && dvbdev->fops) {
76 int err = 0;
77 const struct file_operations *old_fops;
78
79 file->private_data = dvbdev;
80 old_fops = file->f_op;
81 file->f_op = fops_get(dvbdev->fops);
82 if (file->f_op == NULL) {
83 file->f_op = old_fops;
84 goto fail;
85 }
86 if(file->f_op->open)
87 err = file->f_op->open(inode,file);
88 if (err) {
89 fops_put(file->f_op);
90 file->f_op = fops_get(old_fops);
91 }
92 fops_put(old_fops);
93 up_read(&minor_rwsem);
94 mutex_unlock(&dvbdev_mutex);
95 return err;
96 }
97fail:
98 up_read(&minor_rwsem);
99 mutex_unlock(&dvbdev_mutex);
100 return -ENODEV;
101}
102
103
104static const struct file_operations dvb_device_fops =
105{
106 .owner = THIS_MODULE,
107 .open = dvb_device_open,
108 .llseek = noop_llseek,
109};
110
111static struct cdev dvb_device_cdev;
112
113int dvb_generic_open(struct inode *inode, struct file *file)
114{
115 struct dvb_device *dvbdev = file->private_data;
116
117 if (!dvbdev)
118 return -ENODEV;
119
120 if (!dvbdev->users)
121 return -EBUSY;
122
123 if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
124 if (!dvbdev->readers)
125 return -EBUSY;
126 dvbdev->readers--;
127 } else {
128 if (!dvbdev->writers)
129 return -EBUSY;
130 dvbdev->writers--;
131 }
132
133 dvbdev->users--;
134 return 0;
135}
136EXPORT_SYMBOL(dvb_generic_open);
137
138
139int dvb_generic_release(struct inode *inode, struct file *file)
140{
141 struct dvb_device *dvbdev = file->private_data;
142
143 if (!dvbdev)
144 return -ENODEV;
145
146 if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
147 dvbdev->readers++;
148 } else {
149 dvbdev->writers++;
150 }
151
152 dvbdev->users++;
153 return 0;
154}
155EXPORT_SYMBOL(dvb_generic_release);
156
157
158long dvb_generic_ioctl(struct file *file,
159 unsigned int cmd, unsigned long arg)
160{
161 struct dvb_device *dvbdev = file->private_data;
162
163 if (!dvbdev)
164 return -ENODEV;
165
166 if (!dvbdev->kernel_ioctl)
167 return -EINVAL;
168
169 return dvb_usercopy(file, cmd, arg, dvbdev->kernel_ioctl);
170}
171EXPORT_SYMBOL(dvb_generic_ioctl);
172
173
174static int dvbdev_get_free_id (struct dvb_adapter *adap, int type)
175{
176 u32 id = 0;
177
178 while (id < DVB_MAX_IDS) {
179 struct dvb_device *dev;
180 list_for_each_entry(dev, &adap->device_list, list_head)
181 if (dev->type == type && dev->id == id)
182 goto skip;
183 return id;
184skip:
185 id++;
186 }
187 return -ENFILE;
188}
189
190
191int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
192 const struct dvb_device *template, void *priv, int type)
193{
194 struct dvb_device *dvbdev;
195 struct file_operations *dvbdevfops;
196 struct device *clsdev;
197 int minor;
198 int id;
199
200 mutex_lock(&dvbdev_register_lock);
201
202 if ((id = dvbdev_get_free_id (adap, type)) < 0){
203 mutex_unlock(&dvbdev_register_lock);
204 *pdvbdev = NULL;
205 printk(KERN_ERR "%s: couldn't find free device id\n", __func__);
206 return -ENFILE;
207 }
208
209 *pdvbdev = dvbdev = kmalloc(sizeof(struct dvb_device), GFP_KERNEL);
210
211 if (!dvbdev){
212 mutex_unlock(&dvbdev_register_lock);
213 return -ENOMEM;
214 }
215
216 dvbdevfops = kzalloc(sizeof(struct file_operations), GFP_KERNEL);
217
218 if (!dvbdevfops){
219 kfree (dvbdev);
220 mutex_unlock(&dvbdev_register_lock);
221 return -ENOMEM;
222 }
223
224 memcpy(dvbdev, template, sizeof(struct dvb_device));
225 dvbdev->type = type;
226 dvbdev->id = id;
227 dvbdev->adapter = adap;
228 dvbdev->priv = priv;
229 dvbdev->fops = dvbdevfops;
230 init_waitqueue_head (&dvbdev->wait_queue);
231
232 memcpy(dvbdevfops, template->fops, sizeof(struct file_operations));
233 dvbdevfops->owner = adap->module;
234
235 list_add_tail (&dvbdev->list_head, &adap->device_list);
236
237 down_write(&minor_rwsem);
238#ifdef CONFIG_DVB_DYNAMIC_MINORS
239 for (minor = 0; minor < MAX_DVB_MINORS; minor++)
240 if (dvb_minors[minor] == NULL)
241 break;
242
243 if (minor == MAX_DVB_MINORS) {
244 kfree(dvbdevfops);
245 kfree(dvbdev);
246 mutex_unlock(&dvbdev_register_lock);
247 return -EINVAL;
248 }
249#else
250 minor = nums2minor(adap->num, type, id);
251#endif
252
253 dvbdev->minor = minor;
254 dvb_minors[minor] = dvbdev;
255 up_write(&minor_rwsem);
256
257 mutex_unlock(&dvbdev_register_lock);
258
259 clsdev = device_create(dvb_class, adap->device,
260 MKDEV(DVB_MAJOR, minor),
261 dvbdev, "dvb%d.%s%d", adap->num, dnames[type], id);
262 if (IS_ERR(clsdev)) {
263 printk(KERN_ERR "%s: failed to create device dvb%d.%s%d (%ld)\n",
264 __func__, adap->num, dnames[type], id, PTR_ERR(clsdev));
265 return PTR_ERR(clsdev);
266 }
267
268 dprintk(KERN_DEBUG "DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
269 adap->num, dnames[type], id, minor, minor);
270
271 return 0;
272}
273EXPORT_SYMBOL(dvb_register_device);
274
275
276void dvb_unregister_device(struct dvb_device *dvbdev)
277{
278 if (!dvbdev)
279 return;
280
281 down_write(&minor_rwsem);
282 dvb_minors[dvbdev->minor] = NULL;
283 up_write(&minor_rwsem);
284
285 device_destroy(dvb_class, MKDEV(DVB_MAJOR, dvbdev->minor));
286
287 list_del (&dvbdev->list_head);
288 kfree (dvbdev->fops);
289 kfree (dvbdev);
290}
291EXPORT_SYMBOL(dvb_unregister_device);
292
293static int dvbdev_check_free_adapter_num(int num)
294{
295 struct list_head *entry;
296 list_for_each(entry, &dvb_adapter_list) {
297 struct dvb_adapter *adap;
298 adap = list_entry(entry, struct dvb_adapter, list_head);
299 if (adap->num == num)
300 return 0;
301 }
302 return 1;
303}
304
305static int dvbdev_get_free_adapter_num (void)
306{
307 int num = 0;
308
309 while (num < DVB_MAX_ADAPTERS) {
310 if (dvbdev_check_free_adapter_num(num))
311 return num;
312 num++;
313 }
314
315 return -ENFILE;
316}
317
318
319int dvb_register_adapter(struct dvb_adapter *adap, const char *name,
320 struct module *module, struct device *device,
321 short *adapter_nums)
322{
323 int i, num;
324
325 mutex_lock(&dvbdev_register_lock);
326
327 for (i = 0; i < DVB_MAX_ADAPTERS; ++i) {
328 num = adapter_nums[i];
329 if (num >= 0 && num < DVB_MAX_ADAPTERS) {
330 /* use the one the driver asked for */
331 if (dvbdev_check_free_adapter_num(num))
332 break;
333 } else {
334 num = dvbdev_get_free_adapter_num();
335 break;
336 }
337 num = -1;
338 }
339
340 if (num < 0) {
341 mutex_unlock(&dvbdev_register_lock);
342 return -ENFILE;
343 }
344
345 memset (adap, 0, sizeof(struct dvb_adapter));
346 INIT_LIST_HEAD (&adap->device_list);
347
348 printk(KERN_INFO "DVB: registering new adapter (%s)\n", name);
349
350 adap->num = num;
351 adap->name = name;
352 adap->module = module;
353 adap->device = device;
354 adap->mfe_shared = 0;
355 adap->mfe_dvbdev = NULL;
356 mutex_init (&adap->mfe_lock);
357
358 list_add_tail (&adap->list_head, &dvb_adapter_list);
359
360 mutex_unlock(&dvbdev_register_lock);
361
362 return num;
363}
364EXPORT_SYMBOL(dvb_register_adapter);
365
366
367int dvb_unregister_adapter(struct dvb_adapter *adap)
368{
369 mutex_lock(&dvbdev_register_lock);
370 list_del (&adap->list_head);
371 mutex_unlock(&dvbdev_register_lock);
372 return 0;
373}
374EXPORT_SYMBOL(dvb_unregister_adapter);
375
376/* if the miracle happens and "generic_usercopy()" is included into
377 the kernel, then this can vanish. please don't make the mistake and
378 define this as video_usercopy(). this will introduce a dependecy
379 to the v4l "videodev.o" module, which is unnecessary for some
380 cards (ie. the budget dvb-cards don't need the v4l module...) */
381int dvb_usercopy(struct file *file,
382 unsigned int cmd, unsigned long arg,
383 int (*func)(struct file *file,
384 unsigned int cmd, void *arg))
385{
386 char sbuf[128];
387 void *mbuf = NULL;
388 void *parg = NULL;
389 int err = -EINVAL;
390
391 /* Copy arguments into temp kernel buffer */
392 switch (_IOC_DIR(cmd)) {
393 case _IOC_NONE:
394 /*
395 * For this command, the pointer is actually an integer
396 * argument.
397 */
398 parg = (void *) arg;
399 break;
400 case _IOC_READ: /* some v4l ioctls are marked wrong ... */
401 case _IOC_WRITE:
402 case (_IOC_WRITE | _IOC_READ):
403 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
404 parg = sbuf;
405 } else {
406 /* too big to allocate from stack */
407 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
408 if (NULL == mbuf)
409 return -ENOMEM;
410 parg = mbuf;
411 }
412
413 err = -EFAULT;
414 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
415 goto out;
416 break;
417 }
418
419 /* call driver */
420 mutex_lock(&dvbdev_mutex);
421 if ((err = func(file, cmd, parg)) == -ENOIOCTLCMD)
422 err = -EINVAL;
423 mutex_unlock(&dvbdev_mutex);
424
425 if (err < 0)
426 goto out;
427
428 /* Copy results into user buffer */
429 switch (_IOC_DIR(cmd))
430 {
431 case _IOC_READ:
432 case (_IOC_WRITE | _IOC_READ):
433 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
434 err = -EFAULT;
435 break;
436 }
437
438out:
439 kfree(mbuf);
440 return err;
441}
442
443static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env)
444{
445 struct dvb_device *dvbdev = dev_get_drvdata(dev);
446
447 add_uevent_var(env, "DVB_ADAPTER_NUM=%d", dvbdev->adapter->num);
448 add_uevent_var(env, "DVB_DEVICE_TYPE=%s", dnames[dvbdev->type]);
449 add_uevent_var(env, "DVB_DEVICE_NUM=%d", dvbdev->id);
450 return 0;
451}
452
453static char *dvb_devnode(struct device *dev, mode_t *mode)
454{
455 struct dvb_device *dvbdev = dev_get_drvdata(dev);
456
457 return kasprintf(GFP_KERNEL, "dvb/adapter%d/%s%d",
458 dvbdev->adapter->num, dnames[dvbdev->type], dvbdev->id);
459}
460
461
462static int __init init_dvbdev(void)
463{
464 int retval;
465 dev_t dev = MKDEV(DVB_MAJOR, 0);
466
467 if ((retval = register_chrdev_region(dev, MAX_DVB_MINORS, "DVB")) != 0) {
468 printk(KERN_ERR "dvb-core: unable to get major %d\n", DVB_MAJOR);
469 return retval;
470 }
471
472 cdev_init(&dvb_device_cdev, &dvb_device_fops);
473 if ((retval = cdev_add(&dvb_device_cdev, dev, MAX_DVB_MINORS)) != 0) {
474 printk(KERN_ERR "dvb-core: unable register character device\n");
475 goto error;
476 }
477
478 dvb_class = class_create(THIS_MODULE, "dvb");
479 if (IS_ERR(dvb_class)) {
480 retval = PTR_ERR(dvb_class);
481 goto error;
482 }
483 dvb_class->dev_uevent = dvb_uevent;
484 dvb_class->devnode = dvb_devnode;
485 return 0;
486
487error:
488 cdev_del(&dvb_device_cdev);
489 unregister_chrdev_region(dev, MAX_DVB_MINORS);
490 return retval;
491}
492
493
494static void __exit exit_dvbdev(void)
495{
496 class_destroy(dvb_class);
497 cdev_del(&dvb_device_cdev);
498 unregister_chrdev_region(MKDEV(DVB_MAJOR, 0), MAX_DVB_MINORS);
499}
500
501subsys_initcall(init_dvbdev);
502module_exit(exit_dvbdev);
503
504MODULE_DESCRIPTION("DVB Core Driver");
505MODULE_AUTHOR("Marcus Metzler, Ralph Metzler, Holger Waechtler");
506MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h
new file mode 100644
index 00000000000..fcc6ae98745
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvbdev.h
@@ -0,0 +1,172 @@
1/*
2 * dvbdev.h
3 *
4 * Copyright (C) 2000 Ralph Metzler & Marcus Metzler
5 * for convergence integrated media GmbH
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Lesser Public License
9 * as published by the Free Software Foundation; either version 2.1
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 *
21 */
22
23#ifndef _DVBDEV_H_
24#define _DVBDEV_H_
25
26#include <linux/types.h>
27#include <linux/poll.h>
28#include <linux/fs.h>
29#include <linux/list.h>
30
31#define DVB_MAJOR 212
32
33#if defined(CONFIG_DVB_MAX_ADAPTERS) && CONFIG_DVB_MAX_ADAPTERS > 0
34 #define DVB_MAX_ADAPTERS CONFIG_DVB_MAX_ADAPTERS
35#else
36 #define DVB_MAX_ADAPTERS 8
37#endif
38
39#define DVB_UNSET (-1)
40
41#define DVB_DEVICE_VIDEO 0
42#define DVB_DEVICE_AUDIO 1
43#define DVB_DEVICE_SEC 2
44#define DVB_DEVICE_FRONTEND 3
45#define DVB_DEVICE_DEMUX 4
46#define DVB_DEVICE_DVR 5
47#define DVB_DEVICE_CA 6
48#define DVB_DEVICE_NET 7
49#define DVB_DEVICE_OSD 8
50
51#define DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr) \
52 static short adapter_nr[] = \
53 {[0 ... (DVB_MAX_ADAPTERS - 1)] = DVB_UNSET }; \
54 module_param_array(adapter_nr, short, NULL, 0444); \
55 MODULE_PARM_DESC(adapter_nr, "DVB adapter numbers")
56
57struct dvb_frontend;
58
59struct dvb_adapter {
60 int num;
61 struct list_head list_head;
62 struct list_head device_list;
63 const char *name;
64 u8 proposed_mac [6];
65 void* priv;
66
67 struct device *device;
68
69 struct module *module;
70
71 int mfe_shared; /* indicates mutually exclusive frontends */
72 struct dvb_device *mfe_dvbdev; /* frontend device in use */
73 struct mutex mfe_lock; /* access lock for thread creation */
74
75 /* Allow the adapter/bridge driver to perform an action before and/or
76 * after the core handles an ioctl:
77 *
78 * DVB_FE_IOCTL_PRE indicates that the ioctl has not yet been handled.
79 * DVB_FE_IOCTL_POST indicates that the ioctl has been handled.
80 *
81 * When DVB_FE_IOCTL_PRE is passed to the callback as the stage arg:
82 *
83 * return 0 to allow dvb-core to handle the ioctl.
84 * return a positive int to prevent dvb-core from handling the ioctl,
85 * and exit without error.
86 * return a negative int to prevent dvb-core from handling the ioctl,
87 * and return that value as an error.
88 *
89 * When DVB_FE_IOCTL_POST is passed to the callback as the stage arg:
90 *
91 * return 0 to allow the dvb_frontend ioctl handler to exit normally.
92 * return a negative int to cause the dvb_frontend ioctl handler to
93 * return that value as an error.
94 */
95#define DVB_FE_IOCTL_PRE 0
96#define DVB_FE_IOCTL_POST 1
97 int (*fe_ioctl_override)(struct dvb_frontend *fe,
98 unsigned int cmd, void *parg,
99 unsigned int stage);
100};
101
102
103struct dvb_device {
104 struct list_head list_head;
105 const struct file_operations *fops;
106 struct dvb_adapter *adapter;
107 int type;
108 int minor;
109 u32 id;
110
111 /* in theory, 'users' can vanish now,
112 but I don't want to change too much now... */
113 int readers;
114 int writers;
115 int users;
116
117 wait_queue_head_t wait_queue;
118 /* don't really need those !? -- FIXME: use video_usercopy */
119 int (*kernel_ioctl)(struct file *file, unsigned int cmd, void *arg);
120
121 void *priv;
122};
123
124
125extern int dvb_register_adapter(struct dvb_adapter *adap, const char *name,
126 struct module *module, struct device *device,
127 short *adapter_nums);
128extern int dvb_unregister_adapter (struct dvb_adapter *adap);
129
130extern int dvb_register_device (struct dvb_adapter *adap,
131 struct dvb_device **pdvbdev,
132 const struct dvb_device *template,
133 void *priv,
134 int type);
135
136extern void dvb_unregister_device (struct dvb_device *dvbdev);
137
138extern int dvb_generic_open (struct inode *inode, struct file *file);
139extern int dvb_generic_release (struct inode *inode, struct file *file);
140extern long dvb_generic_ioctl (struct file *file,
141 unsigned int cmd, unsigned long arg);
142
143/* we don't mess with video_usercopy() any more,
144we simply define out own dvb_usercopy(), which will hopefully become
145generic_usercopy() someday... */
146
147extern int dvb_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
148 int (*func)(struct file *file, unsigned int cmd, void *arg));
149
150/** generic DVB attach function. */
151#ifdef CONFIG_MEDIA_ATTACH
152#define dvb_attach(FUNCTION, ARGS...) ({ \
153 void *__r = NULL; \
154 typeof(&FUNCTION) __a = symbol_request(FUNCTION); \
155 if (__a) { \
156 __r = (void *) __a(ARGS); \
157 if (__r == NULL) \
158 symbol_put(FUNCTION); \
159 } else { \
160 printk(KERN_ERR "DVB: Unable to find symbol "#FUNCTION"()\n"); \
161 } \
162 __r; \
163})
164
165#else
166#define dvb_attach(FUNCTION, ARGS...) ({ \
167 FUNCTION(ARGS); \
168})
169
170#endif
171
172#endif /* #ifndef _DVBDEV_H_ */