87b17383c9404fc02f0e2489b1cafb27cf3a9da5
[vuplus_openvuplus_3.0] / meta-bsp / common / recipes / linux / linux-vuplus-2.6.37 / dvb-core.patch
1 diff --git a/drivers/media/dvb/dvb-core/Makefile b/drivers/media/dvb/dvb-core/Makefile
2 index 0b51828..8f22bcd 100644
3 --- a/drivers/media/dvb/dvb-core/Makefile
4 +++ b/drivers/media/dvb/dvb-core/Makefile
5 @@ -2,8 +2,10 @@
6  # Makefile for the kernel DVB device drivers.
7  #
8  
9 +dvb-net-$(CONFIG_DVB_NET) := dvb_net.o
10 +
11  dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o    \
12                  dvb_ca_en50221.o dvb_frontend.o                \
13 -                dvb_net.o dvb_ringbuffer.o dvb_math.o
14 +                $(dvb-net-y) dvb_ringbuffer.o dvb_math.o
15  
16  obj-$(CONFIG_DVB_CORE) += dvb-core.o
17 diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
18 index ad1f61d..cb59681 100644
19 --- a/drivers/media/dvb/dvb-core/dmxdev.c
20 +++ b/drivers/media/dvb/dvb-core/dmxdev.c
21 @@ -83,7 +83,11 @@ static ssize_t dvb_dmxdev_buffer_read(struct dvb_ringbuffer *src,
22  
23                 ret = wait_event_interruptible(src->queue,
24                                                !dvb_ringbuffer_empty(src) ||
25 -                                              (src->error != 0));
26 +                                              (src->error != 0) ||
27 +                                              (src->do_wait != 1));
28 +               if (src->do_wait != 1)
29 +                       ret = -EINTR;
30 +
31                 if (ret < 0)
32                         break;
33  
34 @@ -572,13 +576,13 @@ static int dvb_dmxdev_start_feed(struct dmxdev *dmxdev,
35         dmx_output_t otype;
36         int ret;
37         int ts_type;
38 -       enum dmx_ts_pes ts_pes;
39 +       dmx_pes_type_t ts_pes;
40         struct dmx_ts_feed *tsfeed;
41  
42         feed->ts = NULL;
43         otype = para->output;
44  
45 -       ts_pes = (enum dmx_ts_pes)para->pes_type;
46 +       ts_pes = para->pes_type;
47  
48         if (ts_pes < DMX_PES_OTHER)
49                 ts_type = TS_DECODER;
50 @@ -963,6 +967,22 @@ dvb_demux_read(struct file *file, char __user *buf, size_t count,
51         return ret;
52  }
53  
54 +static int dvb_demux_lock_filter(struct dmxdev_filter *dmxdevfilter)
55 +{
56 +       int ret;
57 +
58 +       dmxdevfilter->buffer.do_wait = 0;
59 +
60 +       if (waitqueue_active(&dmxdevfilter->buffer.queue))
61 +               wake_up(&dmxdevfilter->buffer.queue);
62 +
63 +       ret = mutex_lock_interruptible(&dmxdevfilter->mutex);
64 +
65 +       dmxdevfilter->buffer.do_wait = 1;
66 +
67 +       return ret;
68 +}
69 +
70  static int dvb_demux_do_ioctl(struct file *file,
71                               unsigned int cmd, void *parg)
72  {
73 @@ -976,7 +996,7 @@ static int dvb_demux_do_ioctl(struct file *file,
74  
75         switch (cmd) {
76         case DMX_START:
77 -               if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
78 +               if (dvb_demux_lock_filter(dmxdevfilter)) {
79                         mutex_unlock(&dmxdev->mutex);
80                         return -ERESTARTSYS;
81                 }
82 @@ -988,7 +1008,7 @@ static int dvb_demux_do_ioctl(struct file *file,
83                 break;
84  
85         case DMX_STOP:
86 -               if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
87 +               if (dvb_demux_lock_filter(dmxdevfilter)) {
88                         mutex_unlock(&dmxdev->mutex);
89                         return -ERESTARTSYS;
90                 }
91 @@ -997,7 +1017,7 @@ static int dvb_demux_do_ioctl(struct file *file,
92                 break;
93  
94         case DMX_SET_FILTER:
95 -               if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
96 +               if (dvb_demux_lock_filter(dmxdevfilter)) {
97                         mutex_unlock(&dmxdev->mutex);
98                         return -ERESTARTSYS;
99                 }
100 @@ -1006,7 +1026,7 @@ static int dvb_demux_do_ioctl(struct file *file,
101                 break;
102  
103         case DMX_SET_PES_FILTER:
104 -               if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
105 +               if (dvb_demux_lock_filter(dmxdevfilter)) {
106                         mutex_unlock(&dmxdev->mutex);
107                         return -ERESTARTSYS;
108                 }
109 @@ -1015,7 +1035,7 @@ static int dvb_demux_do_ioctl(struct file *file,
110                 break;
111  
112         case DMX_SET_BUFFER_SIZE:
113 -               if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
114 +               if (dvb_demux_lock_filter(dmxdevfilter)) {
115                         mutex_unlock(&dmxdev->mutex);
116                         return -ERESTARTSYS;
117                 }
118 @@ -1059,7 +1079,7 @@ static int dvb_demux_do_ioctl(struct file *file,
119                 break;
120  
121         case DMX_ADD_PID:
122 -               if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
123 +               if (dvb_demux_lock_filter(dmxdevfilter)) {
124                         ret = -ERESTARTSYS;
125                         break;
126                 }
127 @@ -1068,7 +1088,7 @@ static int dvb_demux_do_ioctl(struct file *file,
128                 break;
129  
130         case DMX_REMOVE_PID:
131 -               if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
132 +               if (dvb_demux_lock_filter(dmxdevfilter)) {
133                         ret = -ERESTARTSYS;
134                         break;
135                 }
136 diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
137 index 4a88a3e..faa3671 100644
138 --- a/drivers/media/dvb/dvb-core/dvb_demux.c
139 +++ b/drivers/media/dvb/dvb-core/dvb_demux.c
140 @@ -478,97 +478,94 @@ void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf,
141  
142  EXPORT_SYMBOL(dvb_dmx_swfilter_packets);
143  
144 -void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
145 +static inline int find_next_packet(const u8 *buf, int pos, size_t count,
146 +                                  const int pktsize)
147  {
148 -       int p = 0, i, j;
149 +       int start = pos, lost;
150  
151 -       spin_lock(&demux->lock);
152 -
153 -       if (demux->tsbufp) {
154 -               i = demux->tsbufp;
155 -               j = 188 - i;
156 -               if (count < j) {
157 -                       memcpy(&demux->tsbuf[i], buf, count);
158 -                       demux->tsbufp += count;
159 -                       goto bailout;
160 -               }
161 -               memcpy(&demux->tsbuf[i], buf, j);
162 -               if (demux->tsbuf[0] == 0x47)
163 -                       dvb_dmx_swfilter_packet(demux, demux->tsbuf);
164 -               demux->tsbufp = 0;
165 -               p += j;
166 +       while (pos < count) {
167 +               if (buf[pos] == 0x47 ||
168 +                   (pktsize == 204 && buf[pos] == 0xB8))
169 +                       break;
170 +               pos++;
171         }
172  
173 -       while (p < count) {
174 -               if (buf[p] == 0x47) {
175 -                       if (count - p >= 188) {
176 -                               dvb_dmx_swfilter_packet(demux, &buf[p]);
177 -                               p += 188;
178 -                       } else {
179 -                               i = count - p;
180 -                               memcpy(demux->tsbuf, &buf[p], i);
181 -                               demux->tsbufp = i;
182 -                               goto bailout;
183 -                       }
184 -               } else
185 -                       p++;
186 +       lost = pos - start;
187 +       if (lost) {
188 +               /* This garbage is part of a valid packet? */
189 +               int backtrack = pos - pktsize;
190 +               if (backtrack >= 0 && (buf[backtrack] == 0x47 ||
191 +                   (pktsize == 204 && buf[backtrack] == 0xB8)))
192 +                       return backtrack;
193         }
194  
195 -bailout:
196 -       spin_unlock(&demux->lock);
197 +       return pos;
198  }
199  
200 -EXPORT_SYMBOL(dvb_dmx_swfilter);
201 -
202 -void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
203 +/* Filter all pktsize= 188 or 204 sized packets and skip garbage. */
204 +static inline void _dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf,
205 +               size_t count, const int pktsize)
206  {
207         int p = 0, i, j;
208 -       u8 tmppack[188];
209 +       const u8 *q;
210  
211         spin_lock(&demux->lock);
212  
213 -       if (demux->tsbufp) {
214 +       if (demux->tsbufp) { /* tsbuf[0] is now 0x47. */
215                 i = demux->tsbufp;
216 -               j = 204 - i;
217 +               j = pktsize - i;
218                 if (count < j) {
219                         memcpy(&demux->tsbuf[i], buf, count);
220                         demux->tsbufp += count;
221                         goto bailout;
222                 }
223                 memcpy(&demux->tsbuf[i], buf, j);
224 -               if ((demux->tsbuf[0] == 0x47) || (demux->tsbuf[0] == 0xB8)) {
225 -                       memcpy(tmppack, demux->tsbuf, 188);
226 -                       if (tmppack[0] == 0xB8)
227 -                               tmppack[0] = 0x47;
228 -                       dvb_dmx_swfilter_packet(demux, tmppack);
229 -               }
230 +               if (demux->tsbuf[0] == 0x47) /* double check */
231 +                       dvb_dmx_swfilter_packet(demux, demux->tsbuf);
232                 demux->tsbufp = 0;
233                 p += j;
234         }
235  
236 -       while (p < count) {
237 -               if ((buf[p] == 0x47) || (buf[p] == 0xB8)) {
238 -                       if (count - p >= 204) {
239 -                               memcpy(tmppack, &buf[p], 188);
240 -                               if (tmppack[0] == 0xB8)
241 -                                       tmppack[0] = 0x47;
242 -                               dvb_dmx_swfilter_packet(demux, tmppack);
243 -                               p += 204;
244 -                       } else {
245 -                               i = count - p;
246 -                               memcpy(demux->tsbuf, &buf[p], i);
247 -                               demux->tsbufp = i;
248 -                               goto bailout;
249 -                       }
250 -               } else {
251 -                       p++;
252 +       while (1) {
253 +               p = find_next_packet(buf, p, count, pktsize);
254 +               if (p >= count)
255 +                       break;
256 +               if (count - p < pktsize)
257 +                       break;
258 +
259 +               q = &buf[p];
260 +
261 +               if (pktsize == 204 && (*q == 0xB8)) {
262 +                       memcpy(demux->tsbuf, q, 188);
263 +                       demux->tsbuf[0] = 0x47;
264 +                       q = demux->tsbuf;
265                 }
266 +               dvb_dmx_swfilter_packet(demux, q);
267 +               p += pktsize;
268 +       }
269 +
270 +       i = count - p;
271 +       if (i) {
272 +               memcpy(demux->tsbuf, &buf[p], i);
273 +               demux->tsbufp = i;
274 +               if (pktsize == 204 && demux->tsbuf[0] == 0xB8)
275 +                       demux->tsbuf[0] = 0x47;
276         }
277  
278  bailout:
279         spin_unlock(&demux->lock);
280  }
281  
282 +void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
283 +{
284 +       _dvb_dmx_swfilter(demux, buf, count, 188);
285 +}
286 +EXPORT_SYMBOL(dvb_dmx_swfilter);
287 +
288 +void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
289 +{
290 +       _dvb_dmx_swfilter(demux, buf, count, 204);
291 +}
292  EXPORT_SYMBOL(dvb_dmx_swfilter_204);
293  
294  static struct dvb_demux_filter *dvb_dmx_filter_alloc(struct dvb_demux *demux)
295 diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
296 index cad6634..efe9c30 100644
297 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c
298 +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
299 @@ -105,7 +105,8 @@ struct dvb_frontend_private {
300  
301         /* thread/frontend values */
302         struct dvb_device *dvbdev;
303 -       struct dvb_frontend_parameters parameters;
304 +       struct dvb_frontend_parameters parameters_in;
305 +       struct dvb_frontend_parameters parameters_out;
306         struct dvb_fe_events events;
307         struct semaphore sem;
308         struct list_head list_head;
309 @@ -160,12 +161,11 @@ static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status)
310  
311         e = &events->events[events->eventw];
312  
313 -       memcpy (&e->parameters, &fepriv->parameters,
314 -               sizeof (struct dvb_frontend_parameters));
315 -
316         if (status & FE_HAS_LOCK)
317                 if (fe->ops.get_frontend)
318 -                       fe->ops.get_frontend(fe, &e->parameters);
319 +                       fe->ops.get_frontend(fe, &fepriv->parameters_out);
320 +
321 +       e->parameters = fepriv->parameters_out;
322  
323         events->eventw = wp;
324  
325 @@ -277,12 +277,12 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra
326         int ready = 0;
327         int fe_set_err = 0;
328         struct dvb_frontend_private *fepriv = fe->frontend_priv;
329 -       int original_inversion = fepriv->parameters.inversion;
330 -       u32 original_frequency = fepriv->parameters.frequency;
331 +       int original_inversion = fepriv->parameters_in.inversion;
332 +       u32 original_frequency = fepriv->parameters_in.frequency;
333  
334         /* are we using autoinversion? */
335         autoinversion = ((!(fe->ops.info.caps & FE_CAN_INVERSION_AUTO)) &&
336 -                        (fepriv->parameters.inversion == INVERSION_AUTO));
337 +                        (fepriv->parameters_in.inversion == INVERSION_AUTO));
338  
339         /* setup parameters correctly */
340         while(!ready) {
341 @@ -348,18 +348,19 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra
342                 fepriv->auto_step, fepriv->auto_sub_step, fepriv->started_auto_step);
343  
344         /* set the frontend itself */
345 -       fepriv->parameters.frequency += fepriv->lnb_drift;
346 +       fepriv->parameters_in.frequency += fepriv->lnb_drift;
347         if (autoinversion)
348 -               fepriv->parameters.inversion = fepriv->inversion;
349 +               fepriv->parameters_in.inversion = fepriv->inversion;
350         if (fe->ops.set_frontend)
351 -               fe_set_err = fe->ops.set_frontend(fe, &fepriv->parameters);
352 +               fe_set_err = fe->ops.set_frontend(fe, &fepriv->parameters_in);
353 +       fepriv->parameters_out = fepriv->parameters_in;
354         if (fe_set_err < 0) {
355                 fepriv->state = FESTATE_ERROR;
356                 return fe_set_err;
357         }
358  
359 -       fepriv->parameters.frequency = original_frequency;
360 -       fepriv->parameters.inversion = original_inversion;
361 +       fepriv->parameters_in.frequency = original_frequency;
362 +       fepriv->parameters_in.inversion = original_inversion;
363  
364         fepriv->auto_sub_step++;
365         return 0;
366 @@ -383,7 +384,8 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe)
367                 if (fepriv->state & FESTATE_RETUNE) {
368                         if (fe->ops.set_frontend)
369                                 retval = fe->ops.set_frontend(fe,
370 -                                                       &fepriv->parameters);
371 +                                                       &fepriv->parameters_in);
372 +                       fepriv->parameters_out = fepriv->parameters_in;
373                         if (retval < 0)
374                                 fepriv->state = FESTATE_ERROR;
375                         else
376 @@ -413,8 +415,8 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe)
377  
378                 /* if we're tuned, then we have determined the correct inversion */
379                 if ((!(fe->ops.info.caps & FE_CAN_INVERSION_AUTO)) &&
380 -                   (fepriv->parameters.inversion == INVERSION_AUTO)) {
381 -                       fepriv->parameters.inversion = fepriv->inversion;
382 +                   (fepriv->parameters_in.inversion == INVERSION_AUTO)) {
383 +                       fepriv->parameters_in.inversion = fepriv->inversion;
384                 }
385                 return;
386         }
387 @@ -594,12 +596,14 @@ restart:
388  
389                                 if (fepriv->state & FESTATE_RETUNE) {
390                                         dprintk("%s: Retune requested, FESTATE_RETUNE\n", __func__);
391 -                                       params = &fepriv->parameters;
392 +                                       params = &fepriv->parameters_in;
393                                         fepriv->state = FESTATE_TUNED;
394                                 }
395  
396                                 if (fe->ops.tune)
397                                         fe->ops.tune(fe, params, fepriv->tune_mode_flags, &fepriv->delay, &s);
398 +                               if (params)
399 +                                       fepriv->parameters_out = *params;
400  
401                                 if (s != fepriv->status && !(fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT)) {
402                                         dprintk("%s: state changed, adding current state\n", __func__);
403 @@ -612,11 +616,9 @@ restart:
404                                 dvb_frontend_swzigzag(fe);
405                                 break;
406                         case DVBFE_ALGO_CUSTOM:
407 -                               params = NULL; /* have we been asked to RETUNE ?        */
408                                 dprintk("%s: Frontend ALGO = DVBFE_ALGO_CUSTOM, state=%d\n", __func__, fepriv->state);
409                                 if (fepriv->state & FESTATE_RETUNE) {
410                                         dprintk("%s: Retune requested, FESTAT_RETUNE\n", __func__);
411 -                                       params = &fepriv->parameters;
412                                         fepriv->state = FESTATE_TUNED;
413                                 }
414                                 /* Case where we are going to search for a carrier
415 @@ -625,7 +627,7 @@ restart:
416                                  */
417                                 if (fepriv->algo_status & DVBFE_ALGO_SEARCH_AGAIN) {
418                                         if (fe->ops.search) {
419 -                                               fepriv->algo_status = fe->ops.search(fe, &fepriv->parameters);
420 +                                               fepriv->algo_status = fe->ops.search(fe, &fepriv->parameters_in);
421                                                 /* We did do a search as was requested, the flags are
422                                                  * now unset as well and has the flags wrt to search.
423                                                  */
424 @@ -636,11 +638,12 @@ restart:
425                                 /* Track the carrier if the search was successful */
426                                 if (fepriv->algo_status == DVBFE_ALGO_SEARCH_SUCCESS) {
427                                         if (fe->ops.track)
428 -                                               fe->ops.track(fe, &fepriv->parameters);
429 +                                               fe->ops.track(fe, &fepriv->parameters_in);
430                                 } else {
431                                         fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN;
432                                         fepriv->delay = HZ / 2;
433                                 }
434 +                               fepriv->parameters_out = fepriv->parameters_in;
435                                 fe->ops.read_status(fe, &s);
436                                 if (s != fepriv->status) {
437                                         dvb_frontend_add_event(fe, s); /* update event list */
438 @@ -860,34 +863,34 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe,
439  
440  static int dvb_frontend_clear_cache(struct dvb_frontend *fe)
441  {
442 +       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
443         int i;
444  
445 -       memset(&(fe->dtv_property_cache), 0,
446 -                       sizeof(struct dtv_frontend_properties));
447 -
448 -       fe->dtv_property_cache.state = DTV_CLEAR;
449 -       fe->dtv_property_cache.delivery_system = SYS_UNDEFINED;
450 -       fe->dtv_property_cache.inversion = INVERSION_AUTO;
451 -       fe->dtv_property_cache.fec_inner = FEC_AUTO;
452 -       fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_AUTO;
453 -       fe->dtv_property_cache.bandwidth_hz = BANDWIDTH_AUTO;
454 -       fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_AUTO;
455 -       fe->dtv_property_cache.hierarchy = HIERARCHY_AUTO;
456 -       fe->dtv_property_cache.symbol_rate = QAM_AUTO;
457 -       fe->dtv_property_cache.code_rate_HP = FEC_AUTO;
458 -       fe->dtv_property_cache.code_rate_LP = FEC_AUTO;
459 -
460 -       fe->dtv_property_cache.isdbt_partial_reception = -1;
461 -       fe->dtv_property_cache.isdbt_sb_mode = -1;
462 -       fe->dtv_property_cache.isdbt_sb_subchannel = -1;
463 -       fe->dtv_property_cache.isdbt_sb_segment_idx = -1;
464 -       fe->dtv_property_cache.isdbt_sb_segment_count = -1;
465 -       fe->dtv_property_cache.isdbt_layer_enabled = 0x7;
466 +       memset(c, 0, sizeof(struct dtv_frontend_properties));
467 +
468 +       c->state = DTV_CLEAR;
469 +       c->delivery_system = SYS_UNDEFINED;
470 +       c->inversion = INVERSION_AUTO;
471 +       c->fec_inner = FEC_AUTO;
472 +       c->transmission_mode = TRANSMISSION_MODE_AUTO;
473 +       c->bandwidth_hz = BANDWIDTH_AUTO;
474 +       c->guard_interval = GUARD_INTERVAL_AUTO;
475 +       c->hierarchy = HIERARCHY_AUTO;
476 +       c->symbol_rate = QAM_AUTO;
477 +       c->code_rate_HP = FEC_AUTO;
478 +       c->code_rate_LP = FEC_AUTO;
479 +
480 +       c->isdbt_partial_reception = -1;
481 +       c->isdbt_sb_mode = -1;
482 +       c->isdbt_sb_subchannel = -1;
483 +       c->isdbt_sb_segment_idx = -1;
484 +       c->isdbt_sb_segment_count = -1;
485 +       c->isdbt_layer_enabled = 0x7;
486         for (i = 0; i < 3; i++) {
487 -               fe->dtv_property_cache.layer[i].fec = FEC_AUTO;
488 -               fe->dtv_property_cache.layer[i].modulation = QAM_AUTO;
489 -               fe->dtv_property_cache.layer[i].interleaving = -1;
490 -               fe->dtv_property_cache.layer[i].segment_count = -1;
491 +               c->layer[i].fec = FEC_AUTO;
492 +               c->layer[i].modulation = QAM_AUTO;
493 +               c->layer[i].interleaving = -1;
494 +               c->layer[i].segment_count = -1;
495         }
496  
497         return 0;
498 @@ -901,7 +904,7 @@ static int dvb_frontend_clear_cache(struct dvb_frontend *fe)
499         .buffer = b \
500  }
501  
502 -static struct dtv_cmds_h dtv_cmds[] = {
503 +static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = {
504         _DTV_CMD(DTV_TUNE, 1, 0),
505         _DTV_CMD(DTV_CLEAR, 1, 0),
506  
507 @@ -963,6 +966,7 @@ static struct dtv_cmds_h dtv_cmds[] = {
508         _DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING, 0, 0),
509  
510         _DTV_CMD(DTV_ISDBS_TS_ID, 1, 0),
511 +       _DTV_CMD(DTV_DVBT2_PLP_ID, 1, 0),
512  
513         /* Get */
514         _DTV_CMD(DTV_DISEQC_SLAVE_REPLY, 0, 1),
515 @@ -1020,10 +1024,9 @@ static int is_legacy_delivery_system(fe_delivery_system_t s)
516   * it's being used for the legacy or new API, reducing code and complexity.
517   */
518  static void dtv_property_cache_sync(struct dvb_frontend *fe,
519 -                                   struct dvb_frontend_parameters *p)
520 +                                   struct dtv_frontend_properties *c,
521 +                                   const struct dvb_frontend_parameters *p)
522  {
523 -       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
524 -
525         c->frequency = p->frequency;
526         c->inversion = p->inversion;
527  
528 @@ -1074,9 +1077,9 @@ static void dtv_property_cache_sync(struct dvb_frontend *fe,
529   */
530  static void dtv_property_legacy_params_sync(struct dvb_frontend *fe)
531  {
532 -       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
533 +       const struct dtv_frontend_properties *c = &fe->dtv_property_cache;
534         struct dvb_frontend_private *fepriv = fe->frontend_priv;
535 -       struct dvb_frontend_parameters *p = &fepriv->parameters;
536 +       struct dvb_frontend_parameters *p = &fepriv->parameters_in;
537  
538         p->frequency = c->frequency;
539         p->inversion = c->inversion;
540 @@ -1086,14 +1089,12 @@ static void dtv_property_legacy_params_sync(struct dvb_frontend *fe)
541                 dprintk("%s() Preparing QPSK req\n", __func__);
542                 p->u.qpsk.symbol_rate = c->symbol_rate;
543                 p->u.qpsk.fec_inner = c->fec_inner;
544 -               c->delivery_system = SYS_DVBS;
545                 break;
546         case FE_QAM:
547                 dprintk("%s() Preparing QAM req\n", __func__);
548                 p->u.qam.symbol_rate = c->symbol_rate;
549                 p->u.qam.fec_inner = c->fec_inner;
550                 p->u.qam.modulation = c->modulation;
551 -               c->delivery_system = SYS_DVBC_ANNEX_AC;
552                 break;
553         case FE_OFDM:
554                 dprintk("%s() Preparing OFDM req\n", __func__);
555 @@ -1111,15 +1112,10 @@ static void dtv_property_legacy_params_sync(struct dvb_frontend *fe)
556                 p->u.ofdm.transmission_mode = c->transmission_mode;
557                 p->u.ofdm.guard_interval = c->guard_interval;
558                 p->u.ofdm.hierarchy_information = c->hierarchy;
559 -               c->delivery_system = SYS_DVBT;
560                 break;
561         case FE_ATSC:
562                 dprintk("%s() Preparing VSB req\n", __func__);
563                 p->u.vsb.modulation = c->modulation;
564 -               if ((c->modulation == VSB_8) || (c->modulation == VSB_16))
565 -                       c->delivery_system = SYS_ATSC;
566 -               else
567 -                       c->delivery_system = SYS_DVBC_ANNEX_B;
568                 break;
569         }
570  }
571 @@ -1129,9 +1125,9 @@ static void dtv_property_legacy_params_sync(struct dvb_frontend *fe)
572   */
573  static void dtv_property_adv_params_sync(struct dvb_frontend *fe)
574  {
575 -       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
576 +       const struct dtv_frontend_properties *c = &fe->dtv_property_cache;
577         struct dvb_frontend_private *fepriv = fe->frontend_priv;
578 -       struct dvb_frontend_parameters *p = &fepriv->parameters;
579 +       struct dvb_frontend_parameters *p = &fepriv->parameters_in;
580  
581         p->frequency = c->frequency;
582         p->inversion = c->inversion;
583 @@ -1148,10 +1144,9 @@ static void dtv_property_adv_params_sync(struct dvb_frontend *fe)
584                 break;
585         }
586  
587 -       if(c->delivery_system == SYS_ISDBT) {
588 -               /* Fake out a generic DVB-T request so we pass validation in the ioctl */
589 -               p->frequency = c->frequency;
590 -               p->inversion = c->inversion;
591 +       /* Fake out a generic DVB-T request so we pass validation in the ioctl */
592 +       if ((c->delivery_system == SYS_ISDBT) ||
593 +           (c->delivery_system == SYS_DVBT2)) {
594                 p->u.ofdm.constellation = QAM_AUTO;
595                 p->u.ofdm.code_rate_HP = FEC_AUTO;
596                 p->u.ofdm.code_rate_LP = FEC_AUTO;
597 @@ -1171,7 +1166,7 @@ static void dtv_property_adv_params_sync(struct dvb_frontend *fe)
598  
599  static void dtv_property_cache_submit(struct dvb_frontend *fe)
600  {
601 -       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
602 +       const struct dtv_frontend_properties *c = &fe->dtv_property_cache;
603  
604         /* For legacy delivery systems we don't need the delivery_system to
605          * be specified, but we populate the older structures from the cache
606 @@ -1204,133 +1199,149 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
607                                     struct dtv_property *tvp,
608                                     struct file *file)
609  {
610 -       int r = 0;
611 -
612 -       /* Allow the frontend to validate incoming properties */
613 -       if (fe->ops.get_property)
614 -               r = fe->ops.get_property(fe, tvp);
615 +       const struct dtv_frontend_properties *c = &fe->dtv_property_cache;
616 +       struct dvb_frontend_private *fepriv = fe->frontend_priv;
617 +       struct dtv_frontend_properties cdetected;
618 +       int r;
619  
620 -       if (r < 0)
621 -               return r;
622 +       /*
623 +        * If the driver implements a get_frontend function, then convert
624 +        * detected parameters to S2API properties.
625 +        */
626 +       if (fe->ops.get_frontend) {
627 +               cdetected = *c;
628 +               dtv_property_cache_sync(fe, &cdetected, &fepriv->parameters_out);
629 +               c = &cdetected;
630 +       }
631  
632         switch(tvp->cmd) {
633         case DTV_FREQUENCY:
634 -               tvp->u.data = fe->dtv_property_cache.frequency;
635 +               tvp->u.data = c->frequency;
636                 break;
637         case DTV_MODULATION:
638 -               tvp->u.data = fe->dtv_property_cache.modulation;
639 +               tvp->u.data = c->modulation;
640                 break;
641         case DTV_BANDWIDTH_HZ:
642 -               tvp->u.data = fe->dtv_property_cache.bandwidth_hz;
643 +               tvp->u.data = c->bandwidth_hz;
644                 break;
645         case DTV_INVERSION:
646 -               tvp->u.data = fe->dtv_property_cache.inversion;
647 +               tvp->u.data = c->inversion;
648                 break;
649         case DTV_SYMBOL_RATE:
650 -               tvp->u.data = fe->dtv_property_cache.symbol_rate;
651 +               tvp->u.data = c->symbol_rate;
652                 break;
653         case DTV_INNER_FEC:
654 -               tvp->u.data = fe->dtv_property_cache.fec_inner;
655 +               tvp->u.data = c->fec_inner;
656                 break;
657         case DTV_PILOT:
658 -               tvp->u.data = fe->dtv_property_cache.pilot;
659 +               tvp->u.data = c->pilot;
660                 break;
661         case DTV_ROLLOFF:
662 -               tvp->u.data = fe->dtv_property_cache.rolloff;
663 +               tvp->u.data = c->rolloff;
664                 break;
665         case DTV_DELIVERY_SYSTEM:
666 -               tvp->u.data = fe->dtv_property_cache.delivery_system;
667 +               tvp->u.data = c->delivery_system;
668                 break;
669         case DTV_VOLTAGE:
670 -               tvp->u.data = fe->dtv_property_cache.voltage;
671 +               tvp->u.data = c->voltage;
672                 break;
673         case DTV_TONE:
674 -               tvp->u.data = fe->dtv_property_cache.sectone;
675 +               tvp->u.data = c->sectone;
676                 break;
677         case DTV_API_VERSION:
678                 tvp->u.data = (DVB_API_VERSION << 8) | DVB_API_VERSION_MINOR;
679                 break;
680         case DTV_CODE_RATE_HP:
681 -               tvp->u.data = fe->dtv_property_cache.code_rate_HP;
682 +               tvp->u.data = c->code_rate_HP;
683                 break;
684         case DTV_CODE_RATE_LP:
685 -               tvp->u.data = fe->dtv_property_cache.code_rate_LP;
686 +               tvp->u.data = c->code_rate_LP;
687                 break;
688         case DTV_GUARD_INTERVAL:
689 -               tvp->u.data = fe->dtv_property_cache.guard_interval;
690 +               tvp->u.data = c->guard_interval;
691                 break;
692         case DTV_TRANSMISSION_MODE:
693 -               tvp->u.data = fe->dtv_property_cache.transmission_mode;
694 +               tvp->u.data = c->transmission_mode;
695                 break;
696         case DTV_HIERARCHY:
697 -               tvp->u.data = fe->dtv_property_cache.hierarchy;
698 +               tvp->u.data = c->hierarchy;
699                 break;
700  
701         /* ISDB-T Support here */
702         case DTV_ISDBT_PARTIAL_RECEPTION:
703 -               tvp->u.data = fe->dtv_property_cache.isdbt_partial_reception;
704 +               tvp->u.data = c->isdbt_partial_reception;
705                 break;
706         case DTV_ISDBT_SOUND_BROADCASTING:
707 -               tvp->u.data = fe->dtv_property_cache.isdbt_sb_mode;
708 +               tvp->u.data = c->isdbt_sb_mode;
709                 break;
710         case DTV_ISDBT_SB_SUBCHANNEL_ID:
711 -               tvp->u.data = fe->dtv_property_cache.isdbt_sb_subchannel;
712 +               tvp->u.data = c->isdbt_sb_subchannel;
713                 break;
714         case DTV_ISDBT_SB_SEGMENT_IDX:
715 -               tvp->u.data = fe->dtv_property_cache.isdbt_sb_segment_idx;
716 +               tvp->u.data = c->isdbt_sb_segment_idx;
717                 break;
718         case DTV_ISDBT_SB_SEGMENT_COUNT:
719 -               tvp->u.data = fe->dtv_property_cache.isdbt_sb_segment_count;
720 +               tvp->u.data = c->isdbt_sb_segment_count;
721                 break;
722         case DTV_ISDBT_LAYER_ENABLED:
723 -               tvp->u.data = fe->dtv_property_cache.isdbt_layer_enabled;
724 +               tvp->u.data = c->isdbt_layer_enabled;
725                 break;
726         case DTV_ISDBT_LAYERA_FEC:
727 -               tvp->u.data = fe->dtv_property_cache.layer[0].fec;
728 +               tvp->u.data = c->layer[0].fec;
729                 break;
730         case DTV_ISDBT_LAYERA_MODULATION:
731 -               tvp->u.data = fe->dtv_property_cache.layer[0].modulation;
732 +               tvp->u.data = c->layer[0].modulation;
733                 break;
734         case DTV_ISDBT_LAYERA_SEGMENT_COUNT:
735 -               tvp->u.data = fe->dtv_property_cache.layer[0].segment_count;
736 +               tvp->u.data = c->layer[0].segment_count;
737                 break;
738         case DTV_ISDBT_LAYERA_TIME_INTERLEAVING:
739 -               tvp->u.data = fe->dtv_property_cache.layer[0].interleaving;
740 +               tvp->u.data = c->layer[0].interleaving;
741                 break;
742         case DTV_ISDBT_LAYERB_FEC:
743 -               tvp->u.data = fe->dtv_property_cache.layer[1].fec;
744 +               tvp->u.data = c->layer[1].fec;
745                 break;
746         case DTV_ISDBT_LAYERB_MODULATION:
747 -               tvp->u.data = fe->dtv_property_cache.layer[1].modulation;
748 +               tvp->u.data = c->layer[1].modulation;
749                 break;
750         case DTV_ISDBT_LAYERB_SEGMENT_COUNT:
751 -               tvp->u.data = fe->dtv_property_cache.layer[1].segment_count;
752 +               tvp->u.data = c->layer[1].segment_count;
753                 break;
754         case DTV_ISDBT_LAYERB_TIME_INTERLEAVING:
755 -               tvp->u.data = fe->dtv_property_cache.layer[1].interleaving;
756 +               tvp->u.data = c->layer[1].interleaving;
757                 break;
758         case DTV_ISDBT_LAYERC_FEC:
759 -               tvp->u.data = fe->dtv_property_cache.layer[2].fec;
760 +               tvp->u.data = c->layer[2].fec;
761                 break;
762         case DTV_ISDBT_LAYERC_MODULATION:
763 -               tvp->u.data = fe->dtv_property_cache.layer[2].modulation;
764 +               tvp->u.data = c->layer[2].modulation;
765                 break;
766         case DTV_ISDBT_LAYERC_SEGMENT_COUNT:
767 -               tvp->u.data = fe->dtv_property_cache.layer[2].segment_count;
768 +               tvp->u.data = c->layer[2].segment_count;
769                 break;
770         case DTV_ISDBT_LAYERC_TIME_INTERLEAVING:
771 -               tvp->u.data = fe->dtv_property_cache.layer[2].interleaving;
772 +               tvp->u.data = c->layer[2].interleaving;
773                 break;
774         case DTV_ISDBS_TS_ID:
775 -               tvp->u.data = fe->dtv_property_cache.isdbs_ts_id;
776 +               tvp->u.data = c->isdbs_ts_id;
777 +               break;
778 +       case DTV_DVBT2_PLP_ID:
779 +               tvp->u.data = c->dvbt2_plp_id;
780                 break;
781         default:
782 -               r = -1;
783 +               return -EINVAL;
784 +       }
785 +
786 +       /* Allow the frontend to override outgoing properties */
787 +       if (fe->ops.get_property) {
788 +               r = fe->ops.get_property(fe, tvp);
789 +               if (r < 0)
790 +                       return r;
791         }
792  
793         dtv_property_dump(tvp);
794  
795 -       return r;
796 +       return 0;
797  }
798  
799  static int dtv_property_process_set(struct dvb_frontend *fe,
800 @@ -1338,15 +1349,16 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
801                                     struct file *file)
802  {
803         int r = 0;
804 +       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
805         struct dvb_frontend_private *fepriv = fe->frontend_priv;
806         dtv_property_dump(tvp);
807  
808         /* Allow the frontend to validate incoming properties */
809 -       if (fe->ops.set_property)
810 +       if (fe->ops.set_property) {
811                 r = fe->ops.set_property(fe, tvp);
812 -
813 -       if (r < 0)
814 -               return r;
815 +               if (r < 0)
816 +                       return r;
817 +       }
818  
819         switch(tvp->cmd) {
820         case DTV_CLEAR:
821 @@ -1361,126 +1373,129 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
822                  * tunerequest so we can pass validation in the FE_SET_FRONTEND
823                  * ioctl.
824                  */
825 -               fe->dtv_property_cache.state = tvp->cmd;
826 +               c->state = tvp->cmd;
827                 dprintk("%s() Finalised property cache\n", __func__);
828                 dtv_property_cache_submit(fe);
829  
830 -               r |= dvb_frontend_ioctl_legacy(file, FE_SET_FRONTEND,
831 -                       &fepriv->parameters);
832 +               r = dvb_frontend_ioctl_legacy(file, FE_SET_FRONTEND,
833 +                       &fepriv->parameters_in);
834                 break;
835         case DTV_FREQUENCY:
836 -               fe->dtv_property_cache.frequency = tvp->u.data;
837 +               c->frequency = tvp->u.data;
838                 break;
839         case DTV_MODULATION:
840 -               fe->dtv_property_cache.modulation = tvp->u.data;
841 +               c->modulation = tvp->u.data;
842                 break;
843         case DTV_BANDWIDTH_HZ:
844 -               fe->dtv_property_cache.bandwidth_hz = tvp->u.data;
845 +               c->bandwidth_hz = tvp->u.data;
846                 break;
847         case DTV_INVERSION:
848 -               fe->dtv_property_cache.inversion = tvp->u.data;
849 +               c->inversion = tvp->u.data;
850                 break;
851         case DTV_SYMBOL_RATE:
852 -               fe->dtv_property_cache.symbol_rate = tvp->u.data;
853 +               c->symbol_rate = tvp->u.data;
854                 break;
855         case DTV_INNER_FEC:
856 -               fe->dtv_property_cache.fec_inner = tvp->u.data;
857 +               c->fec_inner = tvp->u.data;
858                 break;
859         case DTV_PILOT:
860 -               fe->dtv_property_cache.pilot = tvp->u.data;
861 +               c->pilot = tvp->u.data;
862                 break;
863         case DTV_ROLLOFF:
864 -               fe->dtv_property_cache.rolloff = tvp->u.data;
865 +               c->rolloff = tvp->u.data;
866                 break;
867         case DTV_DELIVERY_SYSTEM:
868 -               fe->dtv_property_cache.delivery_system = tvp->u.data;
869 +               c->delivery_system = tvp->u.data;
870                 break;
871         case DTV_VOLTAGE:
872 -               fe->dtv_property_cache.voltage = tvp->u.data;
873 +               c->voltage = tvp->u.data;
874                 r = dvb_frontend_ioctl_legacy(file, FE_SET_VOLTAGE,
875 -                       (void *)fe->dtv_property_cache.voltage);
876 +                       (void *)c->voltage);
877                 break;
878         case DTV_TONE:
879 -               fe->dtv_property_cache.sectone = tvp->u.data;
880 +               c->sectone = tvp->u.data;
881                 r = dvb_frontend_ioctl_legacy(file, FE_SET_TONE,
882 -                       (void *)fe->dtv_property_cache.sectone);
883 +                       (void *)c->sectone);
884                 break;
885         case DTV_CODE_RATE_HP:
886 -               fe->dtv_property_cache.code_rate_HP = tvp->u.data;
887 +               c->code_rate_HP = tvp->u.data;
888                 break;
889         case DTV_CODE_RATE_LP:
890 -               fe->dtv_property_cache.code_rate_LP = tvp->u.data;
891 +               c->code_rate_LP = tvp->u.data;
892                 break;
893         case DTV_GUARD_INTERVAL:
894 -               fe->dtv_property_cache.guard_interval = tvp->u.data;
895 +               c->guard_interval = tvp->u.data;
896                 break;
897         case DTV_TRANSMISSION_MODE:
898 -               fe->dtv_property_cache.transmission_mode = tvp->u.data;
899 +               c->transmission_mode = tvp->u.data;
900                 break;
901         case DTV_HIERARCHY:
902 -               fe->dtv_property_cache.hierarchy = tvp->u.data;
903 +               c->hierarchy = tvp->u.data;
904                 break;
905  
906         /* ISDB-T Support here */
907         case DTV_ISDBT_PARTIAL_RECEPTION:
908 -               fe->dtv_property_cache.isdbt_partial_reception = tvp->u.data;
909 +               c->isdbt_partial_reception = tvp->u.data;
910                 break;
911         case DTV_ISDBT_SOUND_BROADCASTING:
912 -               fe->dtv_property_cache.isdbt_sb_mode = tvp->u.data;
913 +               c->isdbt_sb_mode = tvp->u.data;
914                 break;
915         case DTV_ISDBT_SB_SUBCHANNEL_ID:
916 -               fe->dtv_property_cache.isdbt_sb_subchannel = tvp->u.data;
917 +               c->isdbt_sb_subchannel = tvp->u.data;
918                 break;
919         case DTV_ISDBT_SB_SEGMENT_IDX:
920 -               fe->dtv_property_cache.isdbt_sb_segment_idx = tvp->u.data;
921 +               c->isdbt_sb_segment_idx = tvp->u.data;
922                 break;
923         case DTV_ISDBT_SB_SEGMENT_COUNT:
924 -               fe->dtv_property_cache.isdbt_sb_segment_count = tvp->u.data;
925 +               c->isdbt_sb_segment_count = tvp->u.data;
926                 break;
927         case DTV_ISDBT_LAYER_ENABLED:
928 -               fe->dtv_property_cache.isdbt_layer_enabled = tvp->u.data;
929 +               c->isdbt_layer_enabled = tvp->u.data;
930                 break;
931         case DTV_ISDBT_LAYERA_FEC:
932 -               fe->dtv_property_cache.layer[0].fec = tvp->u.data;
933 +               c->layer[0].fec = tvp->u.data;
934                 break;
935         case DTV_ISDBT_LAYERA_MODULATION:
936 -               fe->dtv_property_cache.layer[0].modulation = tvp->u.data;
937 +               c->layer[0].modulation = tvp->u.data;
938                 break;
939         case DTV_ISDBT_LAYERA_SEGMENT_COUNT:
940 -               fe->dtv_property_cache.layer[0].segment_count = tvp->u.data;
941 +               c->layer[0].segment_count = tvp->u.data;
942                 break;
943         case DTV_ISDBT_LAYERA_TIME_INTERLEAVING:
944 -               fe->dtv_property_cache.layer[0].interleaving = tvp->u.data;
945 +               c->layer[0].interleaving = tvp->u.data;
946                 break;
947         case DTV_ISDBT_LAYERB_FEC:
948 -               fe->dtv_property_cache.layer[1].fec = tvp->u.data;
949 +               c->layer[1].fec = tvp->u.data;
950                 break;
951         case DTV_ISDBT_LAYERB_MODULATION:
952 -               fe->dtv_property_cache.layer[1].modulation = tvp->u.data;
953 +               c->layer[1].modulation = tvp->u.data;
954                 break;
955         case DTV_ISDBT_LAYERB_SEGMENT_COUNT:
956 -               fe->dtv_property_cache.layer[1].segment_count = tvp->u.data;
957 +               c->layer[1].segment_count = tvp->u.data;
958                 break;
959         case DTV_ISDBT_LAYERB_TIME_INTERLEAVING:
960 -               fe->dtv_property_cache.layer[1].interleaving = tvp->u.data;
961 +               c->layer[1].interleaving = tvp->u.data;
962                 break;
963         case DTV_ISDBT_LAYERC_FEC:
964 -               fe->dtv_property_cache.layer[2].fec = tvp->u.data;
965 +               c->layer[2].fec = tvp->u.data;
966                 break;
967         case DTV_ISDBT_LAYERC_MODULATION:
968 -               fe->dtv_property_cache.layer[2].modulation = tvp->u.data;
969 +               c->layer[2].modulation = tvp->u.data;
970                 break;
971         case DTV_ISDBT_LAYERC_SEGMENT_COUNT:
972 -               fe->dtv_property_cache.layer[2].segment_count = tvp->u.data;
973 +               c->layer[2].segment_count = tvp->u.data;
974                 break;
975         case DTV_ISDBT_LAYERC_TIME_INTERLEAVING:
976 -               fe->dtv_property_cache.layer[2].interleaving = tvp->u.data;
977 +               c->layer[2].interleaving = tvp->u.data;
978                 break;
979         case DTV_ISDBS_TS_ID:
980 -               fe->dtv_property_cache.isdbs_ts_id = tvp->u.data;
981 +               c->isdbs_ts_id = tvp->u.data;
982 +               break;
983 +       case DTV_DVBT2_PLP_ID:
984 +               c->dvbt2_plp_id = tvp->u.data;
985                 break;
986         default:
987 -               r = -1;
988 +               return -EINVAL;
989         }
990  
991         return r;
992 @@ -1491,6 +1506,7 @@ static int dvb_frontend_ioctl(struct file *file,
993  {
994         struct dvb_device *dvbdev = file->private_data;
995         struct dvb_frontend *fe = dvbdev->priv;
996 +       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
997         struct dvb_frontend_private *fepriv = fe->frontend_priv;
998         int err = -EOPNOTSUPP;
999  
1000 @@ -1510,7 +1526,7 @@ static int dvb_frontend_ioctl(struct file *file,
1001         if ((cmd == FE_SET_PROPERTY) || (cmd == FE_GET_PROPERTY))
1002                 err = dvb_frontend_ioctl_properties(file, cmd, parg);
1003         else {
1004 -               fe->dtv_property_cache.state = DTV_UNDEFINED;
1005 +               c->state = DTV_UNDEFINED;
1006                 err = dvb_frontend_ioctl_legacy(file, cmd, parg);
1007         }
1008  
1009 @@ -1523,6 +1539,7 @@ static int dvb_frontend_ioctl_properties(struct file *file,
1010  {
1011         struct dvb_device *dvbdev = file->private_data;
1012         struct dvb_frontend *fe = dvbdev->priv;
1013 +       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1014         int err = 0;
1015  
1016         struct dtv_properties *tvps = NULL;
1017 @@ -1554,11 +1571,13 @@ static int dvb_frontend_ioctl_properties(struct file *file,
1018                 }
1019  
1020                 for (i = 0; i < tvps->num; i++) {
1021 -                       (tvp + i)->result = dtv_property_process_set(fe, tvp + i, file);
1022 -                       err |= (tvp + i)->result;
1023 +                       err = dtv_property_process_set(fe, tvp + i, file);
1024 +                       if (err < 0)
1025 +                               goto out;
1026 +                       (tvp + i)->result = err;
1027                 }
1028  
1029 -               if(fe->dtv_property_cache.state == DTV_TUNE)
1030 +               if (c->state == DTV_TUNE)
1031                         dprintk("%s() Property cache is full, tuning\n", __func__);
1032  
1033         } else
1034 @@ -1586,8 +1605,10 @@ static int dvb_frontend_ioctl_properties(struct file *file,
1035                 }
1036  
1037                 for (i = 0; i < tvps->num; i++) {
1038 -                       (tvp + i)->result = dtv_property_process_get(fe, tvp + i, file);
1039 -                       err |= (tvp + i)->result;
1040 +                       err = dtv_property_process_get(fe, tvp + i, file);
1041 +                       if (err < 0)
1042 +                               goto out;
1043 +                       (tvp + i)->result = err;
1044                 }
1045  
1046                 if (copy_to_user(tvps->props, tvp, tvps->num * sizeof(struct dtv_property))) {
1047 @@ -1638,7 +1659,7 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
1048         case FE_READ_STATUS: {
1049                 fe_status_t* status = parg;
1050  
1051 -               /* if retune was requested but hasn't occured yet, prevent
1052 +               /* if retune was requested but hasn't occurred yet, prevent
1053                  * that user get signal state from previous tuning */
1054                 if (fepriv->state == FESTATE_RETUNE ||
1055                     fepriv->state == FESTATE_ERROR) {
1056 @@ -1729,7 +1750,7 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
1057                          * Dish network legacy switches (as used by Dish500)
1058                          * are controlled by sending 9-bit command words
1059                          * spaced 8msec apart.
1060 -                        * the actual command word is switch/port dependant
1061 +                        * the actual command word is switch/port dependent
1062                          * so it is up to the userspace application to send
1063                          * the right command.
1064                          * The command must always start with a '0' after
1065 @@ -1787,10 +1808,11 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
1066                 break;
1067  
1068         case FE_SET_FRONTEND: {
1069 +               struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1070                 struct dvb_frontend_tune_settings fetunesettings;
1071  
1072 -               if(fe->dtv_property_cache.state == DTV_TUNE) {
1073 -                       if (dvb_frontend_check_parameters(fe, &fepriv->parameters) < 0) {
1074 +               if (c->state == DTV_TUNE) {
1075 +                       if (dvb_frontend_check_parameters(fe, &fepriv->parameters_in) < 0) {
1076                                 err = -EINVAL;
1077                                 break;
1078                         }
1079 @@ -1800,9 +1822,9 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
1080                                 break;
1081                         }
1082  
1083 -                       memcpy (&fepriv->parameters, parg,
1084 +                       memcpy (&fepriv->parameters_in, parg,
1085                                 sizeof (struct dvb_frontend_parameters));
1086 -                       dtv_property_cache_sync(fe, &fepriv->parameters);
1087 +                       dtv_property_cache_sync(fe, c, &fepriv->parameters_in);
1088                 }
1089  
1090                 memset(&fetunesettings, 0, sizeof(struct dvb_frontend_tune_settings));
1091 @@ -1811,15 +1833,15 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
1092  
1093                 /* force auto frequency inversion if requested */
1094                 if (dvb_force_auto_inversion) {
1095 -                       fepriv->parameters.inversion = INVERSION_AUTO;
1096 +                       fepriv->parameters_in.inversion = INVERSION_AUTO;
1097                         fetunesettings.parameters.inversion = INVERSION_AUTO;
1098                 }
1099                 if (fe->ops.info.type == FE_OFDM) {
1100                         /* without hierarchical coding code_rate_LP is irrelevant,
1101                          * so we tolerate the otherwise invalid FEC_NONE setting */
1102 -                       if (fepriv->parameters.u.ofdm.hierarchy_information == HIERARCHY_NONE &&
1103 -                           fepriv->parameters.u.ofdm.code_rate_LP == FEC_NONE)
1104 -                               fepriv->parameters.u.ofdm.code_rate_LP = FEC_AUTO;
1105 +                       if (fepriv->parameters_in.u.ofdm.hierarchy_information == HIERARCHY_NONE &&
1106 +                           fepriv->parameters_in.u.ofdm.code_rate_LP == FEC_NONE)
1107 +                               fepriv->parameters_in.u.ofdm.code_rate_LP = FEC_AUTO;
1108                 }
1109  
1110                 /* get frontend-specific tuning settings */
1111 @@ -1832,8 +1854,8 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
1112                         switch(fe->ops.info.type) {
1113                         case FE_QPSK:
1114                                 fepriv->min_delay = HZ/20;
1115 -                               fepriv->step_size = fepriv->parameters.u.qpsk.symbol_rate / 16000;
1116 -                               fepriv->max_drift = fepriv->parameters.u.qpsk.symbol_rate / 2000;
1117 +                               fepriv->step_size = fepriv->parameters_in.u.qpsk.symbol_rate / 16000;
1118 +                               fepriv->max_drift = fepriv->parameters_in.u.qpsk.symbol_rate / 2000;
1119                                 break;
1120  
1121                         case FE_QAM:
1122 @@ -1875,8 +1897,8 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
1123  
1124         case FE_GET_FRONTEND:
1125                 if (fe->ops.get_frontend) {
1126 -                       memcpy (parg, &fepriv->parameters, sizeof (struct dvb_frontend_parameters));
1127 -                       err = fe->ops.get_frontend(fe, (struct dvb_frontend_parameters*) parg);
1128 +                       err = fe->ops.get_frontend(fe, &fepriv->parameters_out);
1129 +                       memcpy(parg, &fepriv->parameters_out, sizeof(struct dvb_frontend_parameters));
1130                 }
1131                 break;
1132  
1133 @@ -1967,6 +1989,14 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
1134         if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl) {
1135                 if ((ret = fe->ops.ts_bus_ctrl(fe, 1)) < 0)
1136                         goto err0;
1137 +
1138 +               /* If we took control of the bus, we need to force
1139 +                  reinitialization.  This is because many ts_bus_ctrl()
1140 +                  functions strobe the RESET pin on the demod, and if the
1141 +                  frontend thread already exists then the dvb_init() routine
1142 +                  won't get called (which is what usually does initial
1143 +                  register configuration). */
1144 +               fepriv->reinitialise = 1;
1145         }
1146  
1147         if ((ret = dvb_generic_open (inode, file)) < 0)
1148 diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
1149 index f9f19be..5590eb6 100644
1150 --- a/drivers/media/dvb/dvb-core/dvb_frontend.h
1151 +++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
1152 @@ -239,7 +239,6 @@ struct analog_demod_ops {
1153         void (*set_params)(struct dvb_frontend *fe,
1154                            struct analog_parameters *params);
1155         int  (*has_signal)(struct dvb_frontend *fe);
1156 -       int  (*is_stereo)(struct dvb_frontend *fe);
1157         int  (*get_afc)(struct dvb_frontend *fe);
1158         void (*tuner_status)(struct dvb_frontend *fe);
1159         void (*standby)(struct dvb_frontend *fe);
1160 @@ -359,6 +358,9 @@ struct dtv_frontend_properties {
1161  
1162         /* ISDB-T specifics */
1163         u32                     isdbs_ts_id;
1164 +
1165 +       /* DVB-T2 specifics */
1166 +       u32                     dvbt2_plp_id;
1167  };
1168  
1169  struct dvb_frontend {
1170 diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c
1171 index 4df42aa..51752a9 100644
1172 --- a/drivers/media/dvb/dvb-core/dvb_net.c
1173 +++ b/drivers/media/dvb/dvb-core/dvb_net.c
1174 @@ -1329,7 +1329,8 @@ static int dvb_net_remove_if(struct dvb_net *dvbnet, unsigned long num)
1175                 return -EBUSY;
1176  
1177         dvb_net_stop(net);
1178 -       flush_scheduled_work();
1179 +       flush_work_sync(&priv->set_multicast_list_wq);
1180 +       flush_work_sync(&priv->restart_net_feed_wq);
1181         printk("dvb_net: removed network interface %s\n", net->name);
1182         unregister_netdev(net);
1183         dvbnet->state[num]=0;
1184 diff --git a/drivers/media/dvb/dvb-core/dvb_net.h b/drivers/media/dvb/dvb-core/dvb_net.h
1185 index 3a3126c..1e53acd 100644
1186 --- a/drivers/media/dvb/dvb-core/dvb_net.h
1187 +++ b/drivers/media/dvb/dvb-core/dvb_net.h
1188 @@ -32,6 +32,8 @@
1189  
1190  #define DVB_NET_DEVICES_MAX 10
1191  
1192 +#ifdef CONFIG_DVB_NET
1193 +
1194  struct dvb_net {
1195         struct dvb_device *dvbdev;
1196         struct net_device *device[DVB_NET_DEVICES_MAX];
1197 @@ -40,8 +42,25 @@ struct dvb_net {
1198         struct dmx_demux *demux;
1199  };
1200  
1201 -
1202  void dvb_net_release(struct dvb_net *);
1203  int  dvb_net_init(struct dvb_adapter *, struct dvb_net *, struct dmx_demux *);
1204  
1205 +#else
1206 +
1207 +struct dvb_net {
1208 +       struct dvb_device *dvbdev;
1209 +};
1210 +
1211 +static inline void dvb_net_release(struct dvb_net *dvbnet)
1212 +{
1213 +}
1214 +
1215 +static inline int dvb_net_init(struct dvb_adapter *adap,
1216 +                              struct dvb_net *dvbnet, struct dmx_demux *dmx)
1217 +{
1218 +       return 0;
1219 +}
1220 +
1221 +#endif /* ifdef CONFIG_DVB_NET */
1222 +
1223  #endif
1224 diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
1225 index a5712cd..d5333f3 100644
1226 --- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
1227 +++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
1228 @@ -45,6 +45,7 @@ void dvb_ringbuffer_init(struct dvb_ringbuffer *rbuf, void *data, size_t len)
1229         rbuf->data=data;
1230         rbuf->size=len;
1231         rbuf->error=0;
1232 +       rbuf->do_wait=1;
1233  
1234         init_waitqueue_head(&rbuf->queue);
1235  
1236 diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h
1237 index 41f04da..6951dd3 100644
1238 --- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h
1239 +++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h
1240 @@ -39,6 +39,7 @@ struct dvb_ringbuffer {
1241  
1242         wait_queue_head_t queue;
1243         spinlock_t        lock;
1244 +       int               do_wait;
1245  };
1246  
1247  #define DVB_RINGBUFFER_PKTHDRSIZE 3
1248 diff --git a/include/linux/dvb/audio.h b/include/linux/dvb/audio.h
1249 index fec66bd..d47bccd 100644
1250 --- a/include/linux/dvb/audio.h
1251 +++ b/include/linux/dvb/audio.h
1252 @@ -67,7 +67,7 @@ typedef struct audio_status {
1253  
1254  
1255  typedef
1256 -struct audio_karaoke{  /* if Vocal1 or Vocal2 are non-zero, they get mixed  */
1257 +struct audio_karaoke {  /* if Vocal1 or Vocal2 are non-zero, they get mixed  */
1258         int vocal1;    /* into left and right t at 70% each */
1259         int vocal2;    /* if both, Vocal1 and Vocal2 are non-zero, Vocal1 gets*/
1260         int melody;    /* mixed into the left channel and */
1261 diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h
1262 index 493a2bf..36a3ed6 100644
1263 --- a/include/linux/dvb/frontend.h
1264 +++ b/include/linux/dvb/frontend.h
1265 @@ -175,14 +175,20 @@ typedef enum fe_transmit_mode {
1266         TRANSMISSION_MODE_2K,
1267         TRANSMISSION_MODE_8K,
1268         TRANSMISSION_MODE_AUTO,
1269 -       TRANSMISSION_MODE_4K
1270 +       TRANSMISSION_MODE_4K,
1271 +       TRANSMISSION_MODE_1K,
1272 +       TRANSMISSION_MODE_16K,
1273 +       TRANSMISSION_MODE_32K,
1274  } fe_transmit_mode_t;
1275  
1276  typedef enum fe_bandwidth {
1277         BANDWIDTH_8_MHZ,
1278         BANDWIDTH_7_MHZ,
1279         BANDWIDTH_6_MHZ,
1280 -       BANDWIDTH_AUTO
1281 +       BANDWIDTH_AUTO,
1282 +       BANDWIDTH_5_MHZ,
1283 +       BANDWIDTH_10_MHZ,
1284 +       BANDWIDTH_1_712_MHZ,
1285  } fe_bandwidth_t;
1286  
1287  
1288 @@ -191,7 +197,10 @@ typedef enum fe_guard_interval {
1289         GUARD_INTERVAL_1_16,
1290         GUARD_INTERVAL_1_8,
1291         GUARD_INTERVAL_1_4,
1292 -       GUARD_INTERVAL_AUTO
1293 +       GUARD_INTERVAL_AUTO,
1294 +       GUARD_INTERVAL_1_128,
1295 +       GUARD_INTERVAL_19_128,
1296 +       GUARD_INTERVAL_19_256,
1297  } fe_guard_interval_t;
1298  
1299  
1300 @@ -305,7 +314,9 @@ struct dvb_frontend_event {
1301  
1302  #define DTV_ISDBS_TS_ID                42
1303  
1304 -#define DTV_MAX_COMMAND                                DTV_ISDBS_TS_ID
1305 +#define DTV_DVBT2_PLP_ID       43
1306 +
1307 +#define DTV_MAX_COMMAND                                DTV_DVBT2_PLP_ID
1308  
1309  typedef enum fe_pilot {
1310         PILOT_ON,
1311 @@ -337,6 +348,7 @@ typedef enum fe_delivery_system {
1312         SYS_DMBTH,
1313         SYS_CMMB,
1314         SYS_DAB,
1315 +       SYS_DVBT2,
1316  } fe_delivery_system_t;
1317  
1318  struct dtv_cmds_h {
1319 diff --git a/include/linux/dvb/version.h b/include/linux/dvb/version.h
1320 index 5a7546c..1421cc8 100644
1321 --- a/include/linux/dvb/version.h
1322 +++ b/include/linux/dvb/version.h
1323 @@ -24,6 +24,6 @@
1324  #define _DVBVERSION_H_
1325  
1326  #define DVB_API_VERSION 5
1327 -#define DVB_API_VERSION_MINOR 2
1328 +#define DVB_API_VERSION_MINOR 3
1329  
1330  #endif /*_DVBVERSION_H_*/