diff options
author | Sakari Ailus <sakari.ailus@iki.fi> | 2013-10-13 07:00:26 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-12-04 12:03:45 -0500 |
commit | de49c285a3604955dcbf746edd871f2a4f128122 (patch) | |
tree | fbfa015d30fe98726b8fde0ce1354e1b6425771d | |
parent | d0700c5175b0684c9935ca57deae733c2758667c (diff) |
[media] media: Check for active links on pads with MEDIA_PAD_FL_MUST_CONNECT flag
Do not allow streaming if a pad with MEDIA_PAD_FL_MUST_CONNECT flag is not
connected by an active link.
This patch makes it possible to avoid drivers having to check for the most
common case of link state validation: a sink pad that must be connected.
Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi>
Tested-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/media-entity.c | 41 |
1 files changed, 34 insertions, 7 deletions
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 2c286c307145..37c334edc7e8 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c | |||
@@ -235,6 +235,8 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity, | |||
235 | media_entity_graph_walk_start(&graph, entity); | 235 | media_entity_graph_walk_start(&graph, entity); |
236 | 236 | ||
237 | while ((entity = media_entity_graph_walk_next(&graph))) { | 237 | while ((entity = media_entity_graph_walk_next(&graph))) { |
238 | DECLARE_BITMAP(active, entity->num_pads); | ||
239 | DECLARE_BITMAP(has_no_links, entity->num_pads); | ||
238 | unsigned int i; | 240 | unsigned int i; |
239 | 241 | ||
240 | entity->stream_count++; | 242 | entity->stream_count++; |
@@ -248,21 +250,46 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity, | |||
248 | if (!entity->ops || !entity->ops->link_validate) | 250 | if (!entity->ops || !entity->ops->link_validate) |
249 | continue; | 251 | continue; |
250 | 252 | ||
253 | bitmap_zero(active, entity->num_pads); | ||
254 | bitmap_fill(has_no_links, entity->num_pads); | ||
255 | |||
251 | for (i = 0; i < entity->num_links; i++) { | 256 | for (i = 0; i < entity->num_links; i++) { |
252 | struct media_link *link = &entity->links[i]; | 257 | struct media_link *link = &entity->links[i]; |
253 | 258 | struct media_pad *pad = link->sink->entity == entity | |
254 | /* Is this pad part of an enabled link? */ | 259 | ? link->sink : link->source; |
255 | if (!(link->flags & MEDIA_LNK_FL_ENABLED)) | 260 | |
256 | continue; | 261 | /* Mark that a pad is connected by a link. */ |
257 | 262 | bitmap_clear(has_no_links, pad->index, 1); | |
258 | /* Are we the sink or not? */ | 263 | |
259 | if (link->sink->entity != entity) | 264 | /* |
265 | * Pads that either do not need to connect or | ||
266 | * are connected through an enabled link are | ||
267 | * fine. | ||
268 | */ | ||
269 | if (!(pad->flags & MEDIA_PAD_FL_MUST_CONNECT) || | ||
270 | link->flags & MEDIA_LNK_FL_ENABLED) | ||
271 | bitmap_set(active, pad->index, 1); | ||
272 | |||
273 | /* | ||
274 | * Link validation will only take place for | ||
275 | * sink ends of the link that are enabled. | ||
276 | */ | ||
277 | if (link->sink != pad || | ||
278 | !(link->flags & MEDIA_LNK_FL_ENABLED)) | ||
260 | continue; | 279 | continue; |
261 | 280 | ||
262 | ret = entity->ops->link_validate(link); | 281 | ret = entity->ops->link_validate(link); |
263 | if (ret < 0 && ret != -ENOIOCTLCMD) | 282 | if (ret < 0 && ret != -ENOIOCTLCMD) |
264 | goto error; | 283 | goto error; |
265 | } | 284 | } |
285 | |||
286 | /* Either no links or validated links are fine. */ | ||
287 | bitmap_or(active, active, has_no_links, entity->num_pads); | ||
288 | |||
289 | if (!bitmap_full(active, entity->num_pads)) { | ||
290 | ret = -EPIPE; | ||
291 | goto error; | ||
292 | } | ||
266 | } | 293 | } |
267 | 294 | ||
268 | mutex_unlock(&mdev->graph_mutex); | 295 | mutex_unlock(&mdev->graph_mutex); |