int media_entity_create_link(struct media_entity *source, u16 source_pad, struct media_entity *sink, u16 sink_pad, u32 flags) { struct media_link *link; struct media_link *backlink; BUG_ON(source == NULL || sink == NULL); BUG_ON(source_pad >= source->num_pads); BUG_ON(sink_pad >= sink->num_pads); link = media_entity_add_link(source); if (link == NULL) return -ENOMEM; link->source = &source->pads[source_pad]; link->sink = &sink->pads[sink_pad]; link->flags = flags; /* Create the backlink. Backlinks are used to help graph traversal and * are not reported to userspace. */ backlink = media_entity_add_link(sink); if (backlink == NULL) { source->num_links--; return -ENOMEM; } backlink->source = &source->pads[source_pad]; backlink->sink = &sink->pads[sink_pad]; backlink->flags = flags; link->reverse = backlink; backlink->reverse = link; sink->num_backlinks++; return 0; }
int media_entity_create_link(struct media_entity *source, u16 source_pad, struct media_entity *sink, u16 sink_pad, u32 flags) { struct media_link *link; struct media_link *backlink; BUG_ON(source == NULL || sink == NULL); BUG_ON(source_pad >= source->num_pads); BUG_ON(sink_pad >= sink->num_pads); link = media_entity_add_link(source); if (link == NULL) return -ENOMEM; link->source = &source->pads[source_pad]; link->sink = &sink->pads[sink_pad]; link->flags = flags; backlink = media_entity_add_link(sink); if (backlink == NULL) { source->num_links--; return -ENOMEM; } backlink->source = &source->pads[source_pad]; backlink->sink = &sink->pads[sink_pad]; backlink->flags = flags; link->reverse = backlink; backlink->reverse = link; sink->num_backlinks++; return 0; }
static int media_enum_links(struct media_device *media) { __u32 id; int ret = 0; for (id = 1; id <= media->entities_count; id++) { struct media_entity *entity = &media->entities[id - 1]; struct media_links_enum links; unsigned int i; links.entity = entity->info.id; links.pads = malloc(entity->info.pads * sizeof(struct media_pad_desc)); links.links = malloc(entity->info.links * sizeof(struct media_link_desc)); if (ioctl(media->fd, MEDIA_IOC_ENUM_LINKS, &links) < 0) { media_dbg(media, "%s: Unable to enumerate pads and links (%s).\n", __func__, strerror(errno)); free(links.pads); free(links.links); return -errno; } for (i = 0; i < entity->info.pads; ++i) { entity->pads[i].entity = entity; entity->pads[i].index = links.pads[i].index; entity->pads[i].flags = links.pads[i].flags; } for (i = 0; i < entity->info.links; ++i) { struct media_link_desc *link = &links.links[i]; struct media_link *fwdlink; struct media_link *backlink; struct media_entity *source; struct media_entity *sink; source = media_get_entity_by_id(media, link->source.entity); sink = media_get_entity_by_id(media, link->sink.entity); if (source == NULL || sink == NULL) { media_dbg(media, "WARNING entity %u link %u from %u/%u to %u/%u is invalid!\n", id, i, link->source.entity, link->source.index, link->sink.entity, link->sink.index); ret = -EINVAL; } else { fwdlink = media_entity_add_link(source); fwdlink->source = &source->pads[link->source.index]; fwdlink->sink = &sink->pads[link->sink.index]; fwdlink->flags = link->flags; backlink = media_entity_add_link(sink); backlink->source = &source->pads[link->source.index]; backlink->sink = &sink->pads[link->sink.index]; backlink->flags = link->flags; fwdlink->twin = backlink; backlink->twin = fwdlink; } } free(links.pads); free(links.links); } return ret; }