static u32 gb_manifest_parse_bundles()

in manifest.c [312:386]


static u32 gb_manifest_parse_bundles(struct gb_interface *intf)
{
	struct manifest_desc *desc;
	struct gb_bundle *bundle;
	struct gb_bundle *bundle_next;
	u32 count = 0;
	u8 bundle_id;
	u8 class;

	while ((desc = get_next_bundle_desc(intf))) {
		struct greybus_descriptor_bundle *desc_bundle;

		/* Found one.  Set up its bundle structure*/
		desc_bundle = desc->data;
		bundle_id = desc_bundle->id;
		class = desc_bundle->class;

		/* Done with this bundle descriptor */
		release_manifest_descriptor(desc);

		/* Ignore any legacy control bundles */
		if (bundle_id == GB_CONTROL_BUNDLE_ID) {
			dev_dbg(&intf->dev, "%s - ignoring control bundle\n",
				__func__);
			release_cport_descriptors(&intf->manifest_descs,
						  bundle_id);
			continue;
		}

		/* Nothing else should have its class set to control class */
		if (class == GREYBUS_CLASS_CONTROL) {
			dev_err(&intf->dev,
				"bundle %u cannot use control class\n",
				bundle_id);
			goto cleanup;
		}

		bundle = gb_bundle_create(intf, bundle_id, class);
		if (!bundle)
			goto cleanup;

		/*
		 * Now go set up this bundle's functions and cports.
		 *
		 * A 'bundle' represents a device in greybus. It may require
		 * multiple cports for its functioning. If we fail to setup any
		 * cport of a bundle, we better reject the complete bundle as
		 * the device may not be able to function properly then.
		 *
		 * But, failing to setup a cport of bundle X doesn't mean that
		 * the device corresponding to bundle Y will not work properly.
		 * Bundles should be treated as separate independent devices.
		 *
		 * While parsing manifest for an interface, treat bundles as
		 * separate entities and don't reject entire interface and its
		 * bundles on failing to initialize a cport. But make sure the
		 * bundle which needs the cport, gets destroyed properly.
		 */
		if (!gb_manifest_parse_cports(bundle)) {
			gb_bundle_destroy(bundle);
			continue;
		}

		count++;
	}

	return count;
cleanup:
	/* An error occurred; undo any changes we've made */
	list_for_each_entry_safe(bundle, bundle_next, &intf->bundles, links) {
		gb_bundle_destroy(bundle);
		count--;
	}
	return 0;	/* Error; count should also be 0 */
}