aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/pvrusb2/pvrusb2-context.c
diff options
context:
space:
mode:
authorMike Isely <isely@pobox.com>2008-04-21 02:47:43 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-04-24 13:09:49 -0400
commit1cb03b76d09d20accfa5c1664c16ba6566f539a0 (patch)
tree8c58f23151ab54f71472b80f6d0d29df25ddbb9f /drivers/media/video/pvrusb2/pvrusb2-context.c
parentd3f8d8fb304a8b9a81eae16ff7b50f5379f2437e (diff)
V4L/DVB (7719): pvrusb2: Implement input selection enforcement
In the pvrusb2 driver, different interfaces (e.g. V4L, DVB) have Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/pvrusb2/pvrusb2-context.c')
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-context.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-context.c b/drivers/media/video/pvrusb2/pvrusb2-context.c
index a2ce022c515a..b5db6a5bab31 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-context.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-context.c
@@ -245,6 +245,22 @@ struct pvr2_context *pvr2_context_create(
245} 245}
246 246
247 247
248static void pvr2_context_reset_input_limits(struct pvr2_context *mp)
249{
250 unsigned int tmsk,mmsk;
251 struct pvr2_channel *cp;
252 struct pvr2_hdw *hdw = mp->hdw;
253 mmsk = pvr2_hdw_get_input_available(hdw);
254 tmsk = mmsk;
255 for (cp = mp->mc_first; cp; cp = cp->mc_next) {
256 if (!cp->input_mask) continue;
257 tmsk &= cp->input_mask;
258 }
259 pvr2_hdw_set_input_allowed(hdw,mmsk,tmsk);
260 pvr2_hdw_commit_ctl(hdw);
261}
262
263
248static void pvr2_context_enter(struct pvr2_context *mp) 264static void pvr2_context_enter(struct pvr2_context *mp)
249{ 265{
250 mutex_lock(&mp->mutex); 266 mutex_lock(&mp->mutex);
@@ -300,7 +316,9 @@ void pvr2_channel_done(struct pvr2_channel *cp)
300{ 316{
301 struct pvr2_context *mp = cp->mc_head; 317 struct pvr2_context *mp = cp->mc_head;
302 pvr2_context_enter(mp); 318 pvr2_context_enter(mp);
319 cp->input_mask = 0;
303 pvr2_channel_disclaim_stream(cp); 320 pvr2_channel_disclaim_stream(cp);
321 pvr2_context_reset_input_limits(mp);
304 if (cp->mc_next) { 322 if (cp->mc_next) {
305 cp->mc_next->mc_prev = cp->mc_prev; 323 cp->mc_next->mc_prev = cp->mc_prev;
306 } else { 324 } else {
@@ -316,6 +334,57 @@ void pvr2_channel_done(struct pvr2_channel *cp)
316} 334}
317 335
318 336
337int pvr2_channel_limit_inputs(struct pvr2_channel *cp,unsigned int cmsk)
338{
339 unsigned int tmsk,mmsk;
340 int ret = 0;
341 struct pvr2_channel *p2;
342 struct pvr2_hdw *hdw = cp->hdw;
343
344 mmsk = pvr2_hdw_get_input_available(hdw);
345 cmsk &= mmsk;
346 if (cmsk == cp->input_mask) {
347 /* No change; nothing to do */
348 return 0;
349 }
350
351 pvr2_context_enter(cp->mc_head);
352 do {
353 if (!cmsk) {
354 cp->input_mask = 0;
355 pvr2_context_reset_input_limits(cp->mc_head);
356 break;
357 }
358 tmsk = mmsk;
359 for (p2 = cp->mc_head->mc_first; p2; p2 = p2->mc_next) {
360 if (p2 == cp) continue;
361 if (!p2->input_mask) continue;
362 tmsk &= p2->input_mask;
363 }
364 if (!(tmsk & cmsk)) {
365 ret = -EPERM;
366 break;
367 }
368 tmsk &= cmsk;
369 if ((ret = pvr2_hdw_set_input_allowed(hdw,mmsk,tmsk)) != 0) {
370 /* Internal failure changing allowed list; probably
371 should not happen, but react if it does. */
372 break;
373 }
374 cp->input_mask = cmsk;
375 pvr2_hdw_commit_ctl(hdw);
376 } while (0);
377 pvr2_context_exit(cp->mc_head);
378 return ret;
379}
380
381
382unsigned int pvr2_channel_get_limited_inputs(struct pvr2_channel *cp)
383{
384 return cp->input_mask;
385}
386
387
319int pvr2_channel_claim_stream(struct pvr2_channel *cp, 388int pvr2_channel_claim_stream(struct pvr2_channel *cp,
320 struct pvr2_context_stream *sp) 389 struct pvr2_context_stream *sp)
321{ 390{